Monthly Archives: July 2017

Kubernetes: basic concepts – part 3

Replica Set

ReplicaSets are the next-generation Replication Controllers. The only difference between a ReplicaSet and a Replication Controller right now is the selector support. Similar to Replication Controllers, a ReplicaSet ensures that a specified number of pod “replicas” are running at any given time.

Let’s give it a try:

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: nginx-pod-rs
spec:
  replicas: 5
  selector:
    matchLabels:
     type: web
  template:
    metadata:
     labels:
      type: web
      environment: dev
    spec:
     containers:
     - name: nginx-pod-rs
       image: nginx:alpine
       ports:
       - containerPort: 80
WAUTERW-M-T3ZT:replication wim$ kubectl create -f nginx-replicationset.yaml
replicaset "nginx-pod-rs" created
WAUTERW-M-T3ZT:replication wim$ kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
nginx-pod-rs-0k896   1/1       Running   0          22m
nginx-pod-rs-7rgjl   1/1       Running   0          22m
nginx-pod-rs-hflrp   1/1       Running   0          22m
nginx-pod-rs-lmf3v   1/1       Running   0          22m
nginx-pod-rs-m489m   1/1       Running   0          22m
WAUTERW-M-T3ZT:replication wim$ kubectl get rs
NAME           DESIRED   CURRENT   READY     AGE
nginx-pod-rs   5         5         5         23m
WAUTERW-M-T3ZT:replication wim$ kubectl describe rs nginx-pod-rs
Name:		nginx-pod-rs
Namespace:	default
Selector:	type=web
Labels:		environment=dev
		type=web
Annotations:	
Replicas:	5 current / 5 desired
Pods Status:	5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:	environment=dev
		type=web
  Containers:
   nginx-pod-rs:
    Image:		nginx:alpine
    Port:		80/TCP
    Environment:	
    Mounts:		
  Volumes:		
Events:
  FirstSeen	LastSeen	Count	From			SubObjectPath	Type		Reason			Message
  ---------	--------	-----	----			-------------	--------	------			-------
  23m		23m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-pod-rs-hflrp
  23m		23m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-pod-rs-m489m
  23m		23m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-pod-rs-lmf3v
  23m		23m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-pod-rs-7rgjl
  23m		23m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-pod-rs-0k896

Deployments

Deployments are intended to replace Replication Controllers. They provide the same replication functions (through Replica Sets) and also the ability to rollout changes and roll them back if necessary. In fact, a Deployment owns and manages one or more Replica Sets. And a Replica Set manages the basic units in Kubernetes which are Pods.

Let’s create a simple Deployment using the same image we’ve been using.

WAUTERW-M-T3ZT:deployments wim$ kubectl create -f nginx-deployment_v1.yaml
deployment "nginx-deployment" created
WAUTERW-M-T3ZT:deployments wim$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   5         5         5            3           8s
WAUTERW-M-T3ZT:deployments wim$ kubectl get rs
NAME                        DESIRED   CURRENT   READY     AGE
nginx-deployment-47451619   5         5         4         12s
WAUTERW-M-T3ZT:deployments wim$ kubectl describe deployment nginx-deployment
Name:			nginx-deployment
Namespace:		default
CreationTimestamp:	Thu, 27 Jul 2017 13:45:45 +0200
Labels:			type=web
			version=v0.1
Annotations:		deployment.kubernetes.io/revision=1
Selector:		type=web
Replicas:		5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType:		RollingUpdate
MinReadySeconds:	0
RollingUpdateStrategy:	1 max unavailable, 1 max surge
Pod Template:
  Labels:	type=web
		version=v0.1
  Containers:
   nginx-pod:
    Image:		nginx
    Port:		80/TCP
    Environment:	
    Mounts:		
  Volumes:		
Conditions:
  Type		Status	Reason
  ----		------	------
  Available 	True	MinimumReplicasAvailable
OldReplicaSets:	
NewReplicaSet:	nginx-deployment-47451619 (5/5 replicas created)
Events:
  FirstSeen	LastSeen	Count	From			SubObjectPath	Type		Reason			Message
  ---------	--------	-----	----			-------------	--------	------			-------
  31s		31s		1	deployment-controller			Normal		ScalingReplicaSet	Scaled up replica set nginx-deployment-47451619 to 5
WAUTERW-M-T3ZT:deployments wim$ kubectl describe rs nginx-deployment-47451619
Name:		nginx-deployment-47451619
Namespace:	default
Selector:	pod-template-hash=47451619,type=web
Labels:		pod-template-hash=47451619
		type=web
		version=v0.1
Annotations:	deployment.kubernetes.io/desired-replicas=5
		deployment.kubernetes.io/max-replicas=6
		deployment.kubernetes.io/revision=1
Replicas:	5 current / 5 desired
Pods Status:	5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:	pod-template-hash=47451619
		type=web
		version=v0.1
  Containers:
   nginx-pod:
    Image:		nginx
    Port:		80/TCP
    Environment:	
    Mounts:		
  Volumes:		
Events:
  FirstSeen	LastSeen	Count	From			SubObjectPath	Type		Reason			Message
  ---------	--------	-----	----			-------------	--------	------			-------
  1m		1m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-deployment-47451619-n0m3v
  1m		1m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-deployment-47451619-w02cr
  1m		1m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-deployment-47451619-19fvm
  1m		1m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-deployment-47451619-sr73l
  1m		1m		1	replicaset-controller			Normal		SuccessfulCreate	Created pod: nginx-deployment-47451619-24v6j
WAUTERW-M-T3ZT:deployments wim$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
nginx-deployment-47451619-19fvm   1/1       Running   0          1m
nginx-deployment-47451619-24v6j   1/1       Running   0          1m
nginx-deployment-47451619-n0m3v   1/1       Running   0          1m
nginx-deployment-47451619-sr73l   1/1       Running   0          1m
nginx-deployment-47451619-w02cr   1/1       Running   0          1m

You see here that in the deployment description the replication set is referenced and not the pods. The pods are described in the replication set description as can be seen from the snippet below.

Rolling updates with deployments

Make a small difference to the deployment yaml file:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      type: web
  template:
    metadata:
      labels:
        type: web
        version: v0.2
    spec:
      containers:
      - name: nginx-pod
        image: nginx:alpine
        imagePullPolicy: Always
        ports:
        - containerPort: 80

Apply the update

WAUTERW-M-T3ZT:deployments wim$ kubectl get deployments
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   5         6         3            4           3m
WAUTERW-M-T3ZT:deployments wim$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-2267353239   4         4         2         7s
nginx-deployment-47451619     2         2         2         3m
WAUTERW-M-T3ZT:deployments wim$ kubectl get pods
NAME                                READY     STATUS              RESTARTS   AGE
nginx-deployment-2267353239-2xt1d   1/1       Running             0          12s
nginx-deployment-2267353239-5d9tg   0/1       ContainerCreating   0          3s
nginx-deployment-2267353239-8xmbx   1/1       Running             0          8s
nginx-deployment-2267353239-kfs50   1/1       Running             0          6s
nginx-deployment-2267353239-r2d52   1/1       Running             0          12s
nginx-deployment-47451619-19fvm     0/1       Terminating         0          3m
nginx-deployment-47451619-sr73l     1/1       Terminating         0          3m
WAUTERW-M-T3ZT:deployments wim$
WAUTERW-M-T3ZT:deployments wim$
WAUTERW-M-T3ZT:deployments wim$
WAUTERW-M-T3ZT:deployments wim$
WAUTERW-M-T3ZT:deployments wim$
WAUTERW-M-T3ZT:deployments wim$ kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-2267353239-2xt1d   1/1       Running   0          22s
nginx-deployment-2267353239-5d9tg   1/1       Running   0          13s
nginx-deployment-2267353239-8xmbx   1/1       Running   0          18s
nginx-deployment-2267353239-kfs50   1/1       Running   0          16s
nginx-deployment-2267353239-r2d52   1/1       Running   0          22s

WAUTERW-M-T3ZT:deployments wim$ kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION	CHANGE-CAUSE
1		
2		kubectl apply --filename=nginx-deployment_v2.yaml --record=true

Rollback the deployment

WAUTERW-M-T3ZT:deployments wim$ kubectl rollout undo deployment nginx-deployment
deployment "nginx-deployment" rolled back
WAUTERW-M-T3ZT:deployments wim$ kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-2267353239   3         3         3         5m
nginx-deployment-47451619     3         3         1         9m
WAUTERW-M-T3ZT:deployments wim$ kubectl get pods
NAME                                READY     STATUS              RESTARTS   AGE
nginx-deployment-2267353239-2xt1d   1/1       Running             0          5m
nginx-deployment-47451619-1nqrl     1/1       Running             0          13s
nginx-deployment-47451619-3r235     1/1       Running             0          13s
nginx-deployment-47451619-5281h     1/1       Running             0          8s
nginx-deployment-47451619-7vjqw     0/1       ContainerCreating   0          6s
nginx-deployment-47451619-f1l90     0/1       ContainerCreating   0          4s
WAUTERW-M-T3ZT:deployments wim$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
nginx-deployment-47451619-1nqrl   1/1       Running   0          17s
nginx-deployment-47451619-3r235   1/1       Running   0          17s
nginx-deployment-47451619-5281h   1/1       Running   0          12s
nginx-deployment-47451619-7vjqw   1/1       Running   0          10s
nginx-deployment-47451619-f1l90   1/1       Running   0          8s

Kubernetes: basic concepts – part 2

Pods

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

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

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

Replication Controllers

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.