Pages

Monday, August 13, 2018

Kubernetes Deployment Strategy - Recreate

Release management is very important while playing with containers. It is very necessary to plan the release management for containers based on the application and infrastructure. Kubernetes provides multiple ways of release management or we can call deployment strategies. Kubernetes has a Strategy element that we can define in our deployment manifest file to define how the deployment works.

In the next 4 blog posts we will see how to release a containerized application in kubernetes. In this first post we will understand how to implement a Recreate strategy

Release Strategy – Recreate
The recreate is quite simple. When we define a deployment manifest file with Recreate strategy, all running application pods will be terminated and new application version pods will be created.

Pros: application state is entirely new
Cons: There will be an outage for the application

Let’s see an example of how to implement the recreate strategy,
[root@manja17-I13330 kubenetes-config]# cat recreate-deployment-v1.yml
apiVersion: v1
kind: Service
metadata:
  name: testing-service
  labels:
    app: testings-service
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: http
  selector:
    app: testing-service
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: testing-service
  labels:
    app: testing-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: testing-service
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: testing-service
  template:
    metadata:
      labels:
        app: testing-service
        version: "1.0"
    spec:
      containers:
      - name: test-service
        image: docker.io/jagadesh1982/testing-service
        ports:
        - name: http
          containerPort: 9876
        env:
        - name: VERSION
          value: "1.0"

In the above deployment manifest file, I defined an service and also a deployment. The example is quite east to understand. The important element in the above configuration is,
strategy:
    type: Recreate

Run the deployment using,
[root@manja17-I13330 kubenetes-config]# kubectl create -f recreate-deployment-v1.yml

service "testing-service" created

deployment.apps "testing-service" created


Once done check the objects that are created from the above command using,
[root@manja17-I13330 kubenetes-config]# kubectl get all -l app=testing-service

NAME                                               READY     STATUS    RESTARTS   AGE

pod/testing-service-d48f8c647-2gw9b   1/1       Running      0             18s
pod/testing-service-d48f8c647-59mx2   1/1       Running     0             18s
pod/testing-service-d48f8c647-z682m   1/1       Running     0             18s


NAME                                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/testing-service   3            3                3                  3                18s

NAME                                                    DESIRED   CURRENT   READY     AGE
replicaset.apps/testing-service-d48f8c647   3            3               3            18s


We can see that the deployment is created as well as a service also. We can access the
Application using,
[root@manja17-I13330 kubenetes-config]# curl 10.109.124.147:80/info
{"host": "10.109.124.147", "version": "1.0", "from": "10.32.0.1"}

We can see the version from the output is 1. Now lets deploy a version 2 using the recreate deployment strategy,

[root@manja17-I13330 kubenetes-config]# cat recreate-deployment-v2.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testing-service
  labels:
    app: testing-service
spec:
  replicas: 3
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: testing-service
  template:
    metadata:
      labels:
        app: testing-service
        version: "2.0"
    spec:
      containers:
      - name: test-service
        image: docker.io/jagadesh1982/testing-service
        ports:
        - name: http
          containerPort: 9876
        env:
        - name: VERSION
          value: "2.0"

In the above configuration file, we are just updating the deployment file. We changed the version of the application to 2.

Now if we run this deployment file using,
[root@manja17-I13330 kubenetes-config]# kubectl apply -f recreate-deployment-v2.yml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps "testing-service" configured

[root@manja17-I13330 kubenetes-config]# kubectl get pods --watch
NAME                                        READY     STATUS              RESTARTS   AGE
testing-service-d48f8c647-2gw9b   1/1       Terminating            0          8m
testing-service-d48f8c647-59mx2   1/1       Terminating            0          8m
testing-service-d48f8c647-z682m   1/1       Terminating            0          8m
testing-service-5c87dc5b6c-llkjm   0/1        Pending                 0         0s
testing-service-5c87dc5b6c-2srx6   0/1       Pending                 0         0s
testing-service-5c87dc5b6c-hdpz5   0/1       Pending                 0         0s
testing-service-5c87dc5b6c-llkjm   0/1        ContainerCreating   0         0s
testing-service-5c87dc5b6c-hdpz5   0/1       ContainerCreating  0         0s
testing-service-5c87dc5b6c-2srx6   0/1       ContainerCreating   0         0s
testing-service-5c87dc5b6c-2srx6   1/1       Running                 0         5s
testing-service-5c87dc5b6c-llkjm   1/1        Running                 0         5s
testing-service-5c87dc5b6c-hdpz5   1/1       Running                0         8s

If we watch the pods, we can see that the older version pods will be terminated, and the newer version pods are created. If we access the application, we can see
[root@manja17-I13330 kubenetes-config]# curl 10.109.124.147:80/info
{"host": "10.109.124.147", "version": "2.0", "from": "10.32.0.1"}

We can see the version is 2 over here. So how does this happen?
The selector field is the main one which does the magic. The selector field tell the deployment which pod to update with the newer version. This will define how the deployment finds which pod to manage.

Delete all the objects that we created using,
[root@manja17-I13330 kubenetes-config]#  kubectl delete all -l app=testing-service
pod "testing-service-5c87dc5b6c-2srx6" deleted
pod "testing-service-5c87dc5b6c-hdpz5" deleted
pod "testing-service-5c87dc5b6c-llkjm" deleted
deployment.apps "testing-service" deleted

In the next article we will see another deployment strategy.

No comments :

Post a Comment