Pods allows us to keep containers grouped in terms of networking and hardware infrastructure. Pods can run one or more containers in them. The idea behind pods is that they are a logical group of containers that can be replicated and scheduled by Kubernetes.
A pod can be either created through the web interface or via a yaml file. We will have a look at the yaml file here:
apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-pod image: nginx/alpine ports: - containerPort: 80
We will then have the create the pod via the CLI:
WAUTERW-M-T3ZT:pods wim$ kubectl create -f nginx-pod.yaml pod "nginx-pod" created
This will create a pod called nginx-pod. You will notice that the pod will be in a ‘ContainerCreating’ state while Kubernetes is pulling the nginx image.
If all goes well, your pod will be successfully created
How do we know now that the pod was effectively running correctly? Well, for now, let’s do it as follows:
We will run a container that is using the tutum/curl image. It’s pretty handy as it allows us to issue a simple curl command from this container to the pod that we just created:
WAUTERW-M-T3ZT:pods wim$ kubectl run -i -t --rm cli --image=tutum/curl --restart=Never If you don't see a command prompt, try pressing enter. root@cli:/# curl 172.17.0.4
You will see the nginx default webpage being returned. See the screenshot below:
Another way to test if our pod was effectively running nginx is to have a look at the log files. Let’s first check quickly the pod again:
WAUTERW-M-T3ZT:pods wim$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 7m
And let’s now have a look at the logs of that pod:
WAUTERW-M-T3ZT:pods wim$ kubectl logs -f nginx-pod 172.17.0.5 - - [27/Jul/2017:06:49:13 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-"
Nothing fancy in terms of output, but it will show us that the curl command was launched and that it returned successfully (200 OK response).
Note: another way to do all of this, without having to launch a new container etc… is simply to do the following:
WAUTERW-M-T3ZT:pods wim$ kubectl exec nginx-pod -- curl 172.17.0.4
Labels are key/value pairs that are attached to objects, such as pods. They are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users. Let’s go ahead and add a label to our pod. I’ve chosen the key/value pair ‘type=web’
WAUTERW-M-T3ZT:services wim$ kubectl label pods nginx-pod type:web pod "nginx-pod" labeled
Services are an abstraction to provide a network connection to one or more pods. In the previous example, our pod was running a container but how can the outside world reach this container? The answer is to use services.
Here is an example yaml file for a service:
apiVersion: v1 kind: Service metadata: name: my-nginx labels: name: my-nginx spec: type: NodePort ports: - port: 80 targetPort: 80 nodePort: 31000 protocol: TCP selector: type: web
This specification will create a new Service object named “my-nginx” which targets TCP port 80 on any Pod with the “type=web” label. Important to understand the difference between the port and the targetports. In Kubernetes services are mapped with the ports. Here our service is mapped with port 80. So port is considered as the incoming port for the service, the port your service listens on inside the cluster. Any request reaching there is forwarded to a running pod on targetPort 80. In case you would have an application running on port 3000, you should set the targetPort to 3000.
Deploying and using the services targetPort gives more flexibility. It allows you to change your internal architecture (ports) of your application while not affecting the client that is using our service.
You will see that each time you create a service, Kubernetes will decide it’s own port. In case you would want your client to always use a fixed port you could specify this with the nodePort parameter. For instance if you specify nodePort: 31000, your client will be able to reach it on that port
Let’s go ahead and create the service now:
WAUTERW-M-T3ZT:services wim$ kubectl create -f service-nginx.yaml service "my-nginx" created
To retrieve the URL on which you can see your running nginx, you could do the following:
WAUTERW-M-T3ZT:services wim$ minikube service my-nginx --url http://192.168.99.100:31000
A ReplicationController ensures that a specified number of pod “replicas” are running at any one time. In other words, a ReplicationController makes sure that a pod or homogeneous set of pods are always up and available. If there are too many pods, it will kill some. If there are too few, the ReplicationController will start more. Unlike manually created pods, the pods maintained by a ReplicationController are automatically replaced if they fail, get deleted, or are terminated. For this reason, it is often recommended that you use a ReplicationController even if your application requires only a single pod.
Let’s put things in practice with creating a :
apiVersion: v1 kind: ReplicationController metadata: name: nginx-pod-rc spec: replicas: 5 selector: type: web template: metadata: name: nginx-pod labels: type: web spec: containers: - name: nginx-pod image: nginx:alpine ports: - containerPort: 80
In this example, we have created a replication controller that will assure we always have 5 replicas running. In the template, we describe how the pods should ‘look’ like (e.g. name, what image…). Important as well is that we use a selector, a replication controller manages all the pods with labels which match the selector. So if we launch an additional pod without the label ‘type: web’, that pod will not be part of the replica controller.
WAUTERW-M-T3ZT:replication wim$ kubectl create -f nginx-replicationcontroller.yaml replicationcontroller "nginx-pod-rc" created
On your Kubernetes dashboard, you will now see that 5 pods have been created.
I leave it as an exercise to you to see what happens if a pod gets deleted (answer: the replica controller will create a new one automatically so the total number of pods are always maintained).
WAUTERW-M-T3ZT:replication wim$ kubectl get replicationcontroller NAME DESIRED CURRENT READY AGE nginx-pod-rc 5 5 5 7m WAUTERW-M-T3ZT:replication wim$ kubectl describe replicationcontroller/nginx-pod-rc Name: nginx-pod-rc Namespace: default Selector: type=web Labels: type=web Annotations:
Replicas: 5 current / 5 desired Pods Status: 5 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: type=web Containers: nginx-pod: Image: nginx:alpine Port: 80/TCP Environment: Mounts: Volumes: Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 8m 8m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-vjz91 8m 8m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-s981t 8m 8m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-gr51t 8m 8m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-3bnmw 8m 8m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-8g3jg 7m 7m 1 replication-controller Normal SuccessfulCreate Created pod: nginx-pod-rc-zrzpf
WAUTERW-M-T3ZT:replication wim$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-pod-rc-8g3jg 1/1 Running 0 17m 172.17.0.7 minikube nginx-pod-rc-gr51t 1/1 Running 0 17m 172.17.0.8 minikube nginx-pod-rc-s981t 1/1 Running 0 17m 172.17.0.6 minikube nginx-pod-rc-vjz91 1/1 Running 0 17m 172.17.0.5 minikube nginx-pod-rc-zrzpf 1/1 Running 0 17m 172.17.0.4 minikube
Let’s clean up things a bit. Notice that when the replication controller is deleted, also the associated pods will be deleted.
WAUTERW-M-T3ZT:replication wim$ kubectl delete rc nginx-pod-rc replicationcontroller "nginx-pod-rc" deleted WAUTERW-M-T3ZT:replication wim$ kubectl get pods No resources found.