Skip to content

Files

Latest commit

 

History

History
363 lines (277 loc) · 12.3 KB

01-pods-deployments.md

File metadata and controls

363 lines (277 loc) · 12.3 KB

This exercise/kata covers:

  • Pod creation / deletion
  • Deployments
  • Logging into the pods/containers
  • Viewing logs of the pods/containers

Pods and Deployments:

A Pod (not container) is the basic building-block/worker-unit in Kubernetes. Normally a pod is a part of a Deployment.

Creating pods using 'run' command:

We start by creating our first deployment. Normally people will run an nginx container/pod as first example o deployment. You can surely do that. But, we will run a different container image as our first exercise. The reason is that it will work as a multitool for testing and debugging throughout this course. Besides it too runs nginx!

Here is the command to do it:

kubectl run multitool  --image=praqma/network-multitool

You should be able to see the following output:

$ kubectl run multitool --image=praqma/network-multitool 
deployment "multitool" created

What this command does behind the scenes is, it creates a deployment named multitool, starts a pod using this docker image (praqma/network-multitool), and makes that pod a memeber of that deployment. You don't need to confuse yourself with all these details at this stage. This is just extra (but vital) information. Just so you know what we are talking about, check the list of pods and deployments:

List of pods:

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
multitool-3148954972-k8q06   1/1       Running   0          3m

List of deployments:

$ kubectl get deployments
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
multitool   1         1         1            1           3m

There is actually also a replicaset, which is created as a result of the run command above, but we did not mention earlier; because that is not super important to know at this point. It is something which deals with the number of copies of this pod. It will be covered in later exercise. It is shown below just for the sake of completeness.

$ kubectl get replicasets
NAME                   DESIRED   CURRENT   READY     AGE
multitool-3148954972   1         1         1         3m

Ok. The bottom line is that we wanted to have a pod running ,and we have that.

Lets setup another pod, a traditional nginx deployment, with a specific version - 1.7.9.

Setup an nginx deployment with nginx:1.7.9

kubectl run nginx  --image=nginx:1.7.9

You get another deployment and a replicaset as a result of above command, shown below, so you know what to expect:

$ kubectl get pods,deployments,replicasets
NAME                            READY     STATUS    RESTARTS   AGE
po/multitool-3148954972-k8q06   1/1       Running   0          25m
po/nginx-1480123054-xn5p8       1/1       Running   0          14s

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/multitool   1         1         1            1           25m
deploy/nginx       1         1         1            1           14s

NAME                      DESIRED   CURRENT   READY     AGE
rs/multitool-3148954972   1         1         1         25m
rs/nginx-1480123054       1         1         1         14s

Alternate / preffered way to deploy pods:

You can also use the nginx-simple-deployment.yaml file to create the same nginx deployment. The file is in suport-files directory of this repo. However before you execute the command shown below, note that it will try to create a deployment with the name nginx. If you already have a deployment named nginx running, as done in the previous step, then you will need to delete that first.

Delete the existing deployment using the following command:

$ kubectl get deployments
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
multitool   1         1         1            1           32m
nginx       1         1         1            1           7m

$ kubectl delete deployment nginx
deployment "nginx" deleted

Now you are ready to proceed with the example below:

$ kubectl create -f nginx-simple-deployment.yaml 
deployment "nginx" created

The contents of nginx-simple-deployment.yaml are as follows:

$ cat nginx-simple-deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Verify that the deployment is created:

$ kubectl get deployments
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
multitool   1         1         1            1           59m
nginx       1         1         1            1           36s

Check if the pods are running:

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
multitool-3148954972-k8q06   1/1       Running   0          1h
nginx-431080787-9r0lx        1/1       Running   0          40s

Deleting a pod, the kubernetes promise of resilience:

Before we move forward, lets see if we can delete a pod, and if it comes to life automatically:

$ kubectl delete pod nginx-431080787-9r0lx 
pod "nginx-431080787-9r0lx" deleted

As soon as we delete a pod, a new one is created, satisfying the desired state by the deployment, which is - it needs at least one pod running nginx. So we see that a new nginx pod is created (with a new ID):

$ kubectl get pods
NAME                         READY     STATUS              RESTARTS   AGE
multitool-3148954972-k8q06   1/1       Running             0          1h
nginx-431080787-tx5m7        0/1       ContainerCreating   0          5s

(after few more seconds)

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
multitool-3148954972-k8q06   1/1       Running   0          1h
nginx-431080787-tx5m7        1/1       Running   0          12s

Creating a standalone pod:

Often times you will need to create a pod, without making it a member of a deployment or daemon-set, or anything else. For those instances, here is how you would create a standalone pod.

apiVersion: v1
kind: Pod
metadata:
  name: standalone-nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:alpine

Save the above few lines of code as a yaml file, and use kubectl create -f <filename> to create this pod.

$ kubectl create -f support-files/standalone-nginx-pod.yaml 
pod "standalone-nginx-pod" created

$ kubectl get pods
NAME                   READY     STATUS    RESTARTS   AGE
standalone-nginx-pod   1/1       Running   0          4s
$

The example above will work with container images, which have some sort of daemon/service process running as their entrypoint. If you want to run something which does not have a service process in the container image, you can pass it a custom command, such as shown below:

apiVersion: v1
kind: Pod
metadata:
  name: standalone-busybox-pod
spec:
  containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

The above code will create a pod, which will go into a sleep for 3600 seconds ( one hour), and will exit (die) dilently. Good to run certain diagnostics.

$ kubectl create -f support-files/standalone-busybox-pod.yaml 
pod "standalone-busybox-pod" created
$

$ kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
standalone-busybox-pod   1/1       Running   0          30s
$

PS. Praqma has an excellent multitool for network (and container) troubleshooting. It is called praqma/network-multitool, and it runs nginx web server, eliminating a need to pass any custom commands. You can run it like this:

$ kubectl run multitool --image praqma/network-multitool

Exec into the pod/container:

Just like docker exec, you can exec into a kubernetes pod/container by using kubectl exec. This is a good way to troubleshoot any problems. All you need is the name of the pod (and container name - in case it is a multi-container pod).

You can exec into the pod like so:

[kamran@kworkhorse kubernetes-katas]$ kubectl exec -it standalone-busybox-pod /bin/sh

/ # 

You can do a lot of troubleshooting after you exec (log) into the pod:

[kamran@kworkhorse kubernetes-katas]$ kubectl exec -it standalone-busybox-pod /bin/sh

/ # ls -l
total 16
drwxr-xr-x    2 root     root         12288 Feb 14 18:58 bin
drwxr-xr-x    5 root     root           360 Mar  8 12:51 dev
drwxr-xr-x    1 root     root            66 Mar  8 12:51 etc
drwxr-xr-x    2 nobody   nogroup          6 Feb 14 18:58 home
dr-xr-xr-x  127 root     root             0 Mar  8 12:51 proc
drwx------    1 root     root            26 Mar  8 12:55 root
dr-xr-xr-x   13 root     root             0 Mar  7 10:49 sys
drwxrwxrwt    2 root     root             6 Feb 14 18:58 tmp
drwxr-xr-x    3 root     root            18 Feb 14 18:58 usr
drwxr-xr-x    1 root     root            17 Mar  8 12:51 var

/ # nslookup yahoo.com
Server:		10.32.0.10
Address:	10.32.0.10:53

Non-authoritative answer:
Name:	yahoo.com
Address: 2001:4998:c:1023::4
Name:	yahoo.com
Address: 2001:4998:44:41d::4
/ # exit
$

An example of network-multitool:

$ kubectl run multitool --image=praqma/network-multitool 
deployment.apps "multitool" created

$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
multitool-5558fd48d4-lggqg   1/1       Running   0          12s
standalone-busybox-pod       1/1       Running   0          13m
standalone-nginx-pod         1/1       Running   0          22m
$
$ kubectl exec -it multitool-5558fd48d4-lggqg /bin/bash
bash-4.4# dig +short yahoo.com
98.137.246.8
98.137.246.7
72.30.35.10
98.138.219.231
72.30.35.9
98.138.219.232
bash-4.4# 


bash-4.4# dig +short kubernetes.default.svc.cluster.local
10.32.0.1

bash-4.4# 

Logs:

Logs can be very helpful in troubleshooting why a certain pod/container is not behaving the way you expect it to. You can check logs of the pods by using kubectl logs [-f] <pod-name>. E.g. to watch the logs of the nginx pod, you can do the following:

$ kubectl logs standalone-nginx-pod
10.200.2.4 - - [08/Mar/2019:13:15:18 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1" "-"
$

The above example shows, that the nginx web service in this pod was accessed by a client with an IP 10.200.2.4 .

Accessing the pods:

Now the question comes, How can we access nginx webserver at port 80 in this pod? For now we can do it from within the cluster. First, we need to know the IP address of the nginx pod. We use the -o wide parameters with the get pods command:

$ kubectl get pods -o wide
NAME                         READY     STATUS    RESTARTS   AGE       IP             NODE
multitool-3148954972-k8q06   1/1       Running   0          1h        100.96.2.31    ip-172-20-60-255.eu-central-1.compute.internal
nginx-431080787-tx5m7        1/1       Running   0          12m       100.96.1.148   ip-172-20-49-54.eu-central-1.compute.internal

Bonus info: The IPs you see for the pods (e.g. 100.96.2.31) are private IPs and belong to something called Pod Network, which is a completely private network inside a Kubernetes cluster, and is not accessible from outside the Kubernetes cluster.

Now, we exec into our multitool, as shown below and use the curl command from the pod to access nginx service in the nginx pod:

$ kubectl exec -it multitool-3148954972-k8q06 bash
[root@multitool-3148954972-k8q06 /]#
[root@multitool-3148954972-k8q06 /]# curl -s 100.96.1.148 | grep h1
<h1>Welcome to nginx!</h1>
[root@multitool-3148954972-k8q06 /]# 

We accessed the nginx webserver in the nginx pod using another (multitool) pod in the cluster, because at this point in time the nginx web-service (running as pod) is not accessible through a service. Services are explained separately.

This concludes the exercise, happy coding!


Useful commands

kubectl config get-contexts
kubectl config use-context minikube
kubectl version
kubectl cluster-info
kubectl get nodes
kubectl get pods
kubectl get all
kubectl describe pod
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl api-resources # kubectl 1.11+
kubectl api-versions

Cheatsheat: https://kubernetes.io/docs/reference/kubectl/cheatsheet/