Deployment
Learn how to create a Kubernetes deployment and deploying the Hello World container image.
This section continues from the previous section - make sure you do the tutorial in sequence.

Pod

A Kubernetes Pod is a group of tightly coupled containers, tied together that must start, stop, and scale together. In many case a Pod is associated to only one container. Multiple containers in a single pod can be useful when you have, for example, a container that runs the application, and another container that periodically polls logs/metrics from the application container.
Every Pod has a unique, ephemeral, and routable IP address. I.e., a container inside of a Pod can directly reach another the IP address of another Pod (and the containers in that Pod).
All containers within a single pod are scheduled to a single physical resource (the same Node), and all containers within a Pod will share the same networking interface, IP address, volumes, etc.
You can start a single Pod in Kubernetes by creating a Pod resource. However, a Pod created this way would be known as an Unmanaged Pod. If an Unmanaged Pod dies/exits, it will not be restarted by Kubernetes. A better way to start a Pod, is by using a higher-level construct such as a Deployment.

Deployment

Deployment provides declarative way to manage a set of Pods. You only need to describe the desired state in a Deployment resource, and behind the scenes, a Kubernetes Deployment controller will change the actual state to the desired state for you. It does this using a resource called a ReplicaSet under the covers.

Deployment YAML

You can create a Deployment and deploy into Kubernetes using kubectl command line like in the Hello World tutorial. That's great to get a feel of Kubernetes. However, it's best that you create a YAML file first, and then deploy the YAML file.
1
# Under the helloworld-springboot-tomcat directory , create a k8s directory
2
mkdir k8s/
3
4
PROJECT_ID=$(gcloud config get-value project)
5
kubectl create deployment helloworld \
6
--image=gcr.io/${PROJECT_ID}/helloworld \
7
--dry-run \
8
-o yaml > k8s/deployment.yaml
Copied!
You can open the k8s/deployment.yaml file to see the content. Following is a version of the YAML file where it's slimmed down to the bare minimum.
k8s/deployment.yaml
1
# API Version and Kind are important to indicate the type of resource
2
apiVersion: apps/v1
3
kind: Deployment
4
metadata:
5
# Every Kubernetes resource has a name that's unique within a namespace
6
name: helloworld
7
# Every Kubernetes can have labels, label key/value pairs can be queried later.
8
labels:
9
app: helloworld
10
spec:
11
# The number of the pods that start
12
replicas: 1
13
14
# The labels that matches the pods within this deployment
15
selector:
16
matchLabels:
17
app: helloworld
18
# Every instance of the pod will be created using the template below
19
template:
20
metadata:
21
# Every new pod created by the deployment will have these labels
22
# The name of a newly created pod will be generated
23
labels:
24
app: helloworld
25
spec:
26
containers:
27
# Every container can have a name, and the container image to run
28
- name: helloworld
29
image: gcr.io/.../helloworld
Copied!
You can read more about Deployment in the Kubernetes Deployment Guide.

Deploy

Use kubectl command line to deploy the YAML file:
1
kubectl apply -f k8s/deployment.yaml
Copied!
To verify the application is deployed, see all the pods that are running:
1
kubectl get pods
Copied!
You should see that there is one pod running!
1
NAME READY STATUS RESTARTS AGE
2
helloworld-... 1/1 Running 0 ...
Copied!

Basic Interactions

Describe Details

For every Kubernetes resource, you can describe the details of a resource, and see its current state, and any events, errors that may have occurred.
Describe a Deployment:
1
kubectl describe deployment helloworld
Copied!
Describe a Pod:
1
POD_NAME=$(kubectl get pods -lapp=helloworld -o jsonpath='{.items[0].metadata.name}')
2
kubectl delete pod ${POD_NAME}
Copied!

Find Pods with Labels

kubectl get pods shows you every pod running in the current namespace. You can limit the output to just the application you are interested in by select only pods matching certain label key/value pairs.
1
kubectl get pods -lapp=helloworld
Copied!

Scaling

Scale the number of instances from 1 to 2.
1
kubectl scale deployment helloworld --replicas=2
Copied!
Verify that there are now 2 pods running:
1
kubectl get pods
Copied!

Delete a Pod

Out of the 2 pods, pick one to delete, and then observe that Kubernetes automatically starts another pod instance so that there are always 2 pods running.
1
POD_NAME=$(kubectl get pods -lapp=helloworld -o jsonpath='{.items[0].metadata.name}')
2
kubectl delete pod ${POD_NAME}
Copied!
Verify that there still 2 pods running, but one of them has a lower age indicating it's recently started.
1
kubectl get pods
Copied!

Delete All Pods

You can use labels to delete all pods matching certain label key/value pairs.
1
kubectl delete pod -lapp=helloworld
Copied!

Stream Logs

You can see the logs from the pod, and follow the log as new logs are produced:
1
POD_NAME=$(kubectl get pods -lapp=helloworld -o jsonpath='{.items[0].metadata.name}')
2
kubectl logs -f ${POD_NAME}
Copied!

Executing Commands

You can execute commands directly in the container instance. However, the container image will need to contains the command that you'd like to run. The Hello World application built with Jib uses a Distroless base image by default - and the Distroless base image does not come with any shell commands for security purposes.
Let's deploy an Nginx container that contains the executables and see how you can shell into the container instance.
1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/controllers/nginx-deployment.yaml
Copied!
See that Nginx container is running:
1
kubectl get pods -lapp=nginx
Copied!
Use a specific Nginx pod, and shell into the container instance:
1
POD_NAME=$(kubectl get pods -lapp=nginx -o jsonpath='{.items[0].metadata.name}')
2
kubectl exec -ti ${POD_NAME} /bin/bash
Copied!
The -ti flag means to receive output from TTY, and also that the session is interactive (i.e., you'll be typing commands).
Once you are in the container instance's shell, you can explore the container instance:
1
# Within the container instance shell:
2
ls
3
ls /sbin
4
ls /bin
5
exit
Copied!
In this Nginx container image, you can see that there are actually many command line utilities that's not needed for production deployment of an Nginx server. Exposing more commands like this may increase attack surface area if the container instance is compromised. For this reason, Distroless base images do not include any commands. On the other hand, lack of commands may increase the difficulty to debug the application instance.
Delete the Nginx deployment before you continue!
kubectl delete deployment nginx-deployment
Last modified 1yr ago