Replication and Deployment

$ kubectl scale --replicas=3 -f helloworld-replica.yml
replicationcontroller "helloworld-controller" scaled

$ kubectl get pod
NAME                          READY     STATUS    RESTARTS   AGE
helloworld-controller-2v2x1   1/1       Running   0          13m
helloworld-controller-hgn9s   1/1       Running   0          3m
helloworld-controller-r2vkh   1/1       Running   0          5s

  • Each node contain Docker engine (can be also another container engine)
  • Each pod contain one or more Docker containers
  • iptables is like a firewall
  • The pod is built based on the YAML spec kind Pod
  • Containers are built based on the the containers section

Replication Controller

Scaling

  • If your application is stateless, you can horizontally scale it
    • Stateless = your application doesn't have a state, it doesn't write any local files / keeps local sessions
    • All traditional databases (MySQL, Postgres) are stateful, they have database files that can't split over multiple instances
  • Most web applications can be made stateless:
    • Session management needs to be done outside the container
    • Any files that need to be saved can't be save locally on the container
  • For more information about best practices, have a look at 12factor.net
  • We can use volumes to still run stateful apps
    • Those stateful apps can't horizontally scale, but you can run them in a single container and vertically scale (allocate more CPU / memory / disk)
  • Scaling in Kubernetes can be done using the Replication Controller
  • The replication controller will ensure a specified number of pod replicas will run at all time
  • A pod created with the replica controller will automatically be replaced if they fail, get deleted, or are terminated
  • Using the replication controller is also recommended if you just want to make sure 1 pod is always running, even after reboots 
    • You can then run a replication controller with just 1 replica
    • This makes sure that the pod is always running

Our First App

To replicate our example app 2 times:

  • Set kind: ReplicationController
  • Add template
apiVersion: v1
kind: ReplicationController
metadata:
  name: helloworld-controller
spec:
  replicas: 2
  selector:
    app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: k8s-demo
        image: wardviaene/k8s-demo
        ports:
        - name: nodejs-port
          containerPort: 3000

Create pods

$ kubectl create -f helloworld-replica.yml
replicationcontroller "helloworld-controller" created

$ kubectl get pod
NAME                          READY     STATUS    RESTARTS   AGE
helloworld-controller-2v2x1   1/1       Running   0          9s
helloworld-controller-8bdf3   1/1       Running   0          9s

If one pod is failed, replication controller will automatically restore.

$ kubectl delete pod helloworld-controller-8bdf3
pod "helloworld-controller-8bdf3" deleted

$ kubectl get pod
NAME                          READY     STATUS              RESTARTS   AGE
helloworld-controller-2v2x1   1/1       Running             0          10m
helloworld-controller-8bdf3   1/1       Terminating         0          10m
helloworld-controller-hgn9s   0/1       ContainerCreating   0          3s

You can also specify number of replicas.

$ kubectl scale --replicas=3 -f helloworld-replica.yml
replicationcontroller "helloworld-controller" scaled

$ kubectl get pod
NAME                          READY     STATUS    RESTARTS   AGE
helloworld-controller-2v2x1   1/1       Running   0          13m
helloworld-controller-hgn9s   1/1       Running   0          3m
helloworld-controller-r2vkh   1/1       Running   0          5s

You can see status of the Replication Controller using kubectl get rc

$ kubectl get rc
NAME                    DESIRED   CURRENT   READY     AGE
helloworld-controller   3         3         3         14m

Finally, delete the app.

$ kubectl delete rc/helloworld-controller
replicationcontroller "helloworld-controller" delete

Deployments

Replication Set

  • Replica Set is the next-generation Replication Controller
  • It supports a new selector that can do selection based on filtering according a set of values
    • e.g. "environment" either "dev" or "qa"
    • not only based on equality, like the Replication Controller
      • e.g. "environment" == "dev"
  • This Replica Set, rather than the Replication Controller, is used by the Deployment object

Deployment Object

  • A deployment declaration in Kubernetes allows you to do app deployments and updates
  • When using the deployment object, you define the state of your application
    • Kubernetes will then make sure the clusters matches your desired state
  • Just using the replication controller or replication set might be cumbersome to deploy apps
    • The Deployment Object is easier to use and gives you more possibilities
  • With a deployment object, you can:
    • Create a deployment (e.g. deploying an app)
    • Update a deployment (e.g. deploying a new version)
    • Do rolling updates (zero downtime deployments)
    • Roll back to a previous version
    • Pause / resume a deployment (e.g. to roll-out to only a certain percentage) 

Example Deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: helloworld-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: k8s-demo
        image: wardviaene/k8s-demo
        ports:
        - name: nodejs-port
          containerPort: 3000

Useful Commands

Command Description
kubectl get deployments Get information on current deployments
kubectl get rs Get information about the replica sets
kubectl get pods --show-labels Get pods, and also show labels attached to those pods
kubectl rollout status deployment/helloworld-deployment Get deployment status
kubectl set image deployment/helloworld-deployment k8s-demo=k8s-demo:2 Run k8s-demo with the image label version 2
kubectl rollout status deployment/helloworld-deployment Get the status of the rollout
kubectl rollout history deployment/helloworld-deployment Get the rollout history
kubectl rollout undo deployment/helloworld-deployment Rollback to previous version
kubectl rollout undo deployment/helloworld-deployment --to-revision=n Rollback to any version

Demo

Deploy Version 1

$ kubectl create -f helloworld-deploy.yml
deployment "helloworld-deployment" created

$ kubectl get deployment
NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
helloworld-deployment   3         3         3            3           2m

$ kubectl get rs
NAME                               DESIRED   CURRENT   READY     AGE
helloworld-deployment-4153696333   3         3         3         2m

$ kubectl get pod --show-labels
NAME                                     READY     STATUS    RESTARTS   AGE       LABELS
helloworld-deployment-4153696333-17vqp   1/1       Running   0          3m        app=helloworld,pod-template-hash=4153696333
helloworld-deployment-4153696333-ltxvt   1/1       Running   0          3m        app=helloworld,pod-template-hash=4153696333
helloworld-deployment-4153696333-zbtn7   1/1       Running   0          3m        app=helloworld,pod-template-hash=4153696333

$ kubectl rollout status deployment/helloworld-deployment
deployment "helloworld-deployment" successfully rolled out

Expose and Test Version 1

$ kubectl expose deployment helloworld-deployment --type=NodePort
service "helloworld-deployment" exposed

$ kubectl get service
NAME                    CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
helloworld-deployment   10.0.214.139   <nodes>       3000:31616/TCP   37s
kubernetes              10.0.0.1       <none>        443/TCP          9d

$ kubectl describe service helloworld-deployment
Name:				helloworld-deployment
Namespace:			default
Labels:				app=helloworld
Annotations:		<none>
Selector:			app=helloworld
Type:				NodePort
IP:					10.0.214.139
Port:				<unset>	3000/TCP
NodePort:			<unset>	31616/TCP
Endpoints:			10.244.1.11:3000,10.244.1.12:3000,10.244.1.13:3000
Session Affinity:	None
Events:				<none>

$ curl http://10.0.214.139:3000
Hello World!

Upgrade to Version 2

$ kubectl set image deployment/helloworld-deployment k8s-demo=wardviaene/k8s-demo:2
deployment "helloworld-deployment" image updated

$ kubectl rollout status deployment/helloworld-deployment
deployment "helloworld-deployment" successfully rolled out

$ curl http://10.0.214.139:3000
Hello World v2!

$ kubectl get pod
NAME                                     READY     STATUS        RESTARTS   AGE
helloworld-deployment-4153696333-zbtn7   0/1       Terminating   0          15m
helloworld-deployment-521624165-3jftr    1/1       Running       0          36s
helloworld-deployment-521624165-469mg    1/1       Running       0          46s
helloworld-deployment-521624165-pt5f7    1/1       Running       0          46s

$ kubectl rollout history deployment/helloworld-deployment
deployments "helloworld-deployment"
REVISION	CHANGE-CAUSE
1		<none>
2		<none>

Rollback to Version 1

$ kubectl rollout undo deployment/helloworld-deployment
deployment "helloworld-deployment" rolled back

$ kubectl rollout status deployment/helloworld-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "helloworld-deployment" successfully rolled out

$ kubectl get pod
NAME                                     READY     STATUS        RESTARTS   AGE
helloworld-deployment-4153696333-d0jv7   1/1       Running       0          10s
helloworld-deployment-4153696333-w5dhs   1/1       Running       0          15s
helloworld-deployment-4153696333-x62bk   1/1       Running       0          15s
helloworld-deployment-521624165-3jftr    1/1       Terminating   0          1m
helloworld-deployment-521624165-469mg    1/1       Terminating   0          1m
helloworld-deployment-521624165-pt5f7    1/1       Terminating   0          1m

$ kubectl rollout history deployment/helloworld-deployment
deployments "helloworld-deployment"
REVISION	CHANGE-CAUSE
2		<none>
3		<none>

No Comments

Back to top