305-998-7702 | 415-800-2922 info@rx-m.com

Deployment Patterns

Learn how to put the latest open source technology into practice with hands-on training, delivered by industry experts, aligned to your desired business outcomes

As you have seen, deployments when combined with services, can expose new application features and updates to users with little downtime. That combination allows a basic Kubernetes clusters to perform things like canary or blue/green deployments.

A canary deployment is a pattern where new features or updates are exposed to users gradually. A canary deployment can be achieved by taking a service backed by a deployment and adding additional pods with the updated code to that service (whether they are standalone pods or another deployment).

Given an existing webserver deployment with two pods and a service, each time clients send a request to the service IP address, one of the original webserver pods returns the response:

$ kubectl get pods,svc -l app=webserver

NAME READY STATUS RESTARTS AGE
pod/webserver-754db6dc6-jrtf4 1/1 Running 0 29s
pod/webserver-754db6dc6-jsxtt 1/1 Running 0 29s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/webserver ClusterIP 10.103.48.81 <none> 80/TCP 24s

$ curl 10.103.48.81

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

...

Creating another deployment whose pods have the app=webserver label adds those pods as endpoints to the webserver service:

$ cat webserver-canary.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webserver-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      labels:
        app: webserver
    spec:
      containers:
      - image: httpd
        name: httpd

$ kubectl apply -f webserver-canary.yaml

deployment.apps/webserver-canary created

$ kubectl get svc,pods -l app=webserver
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/webserver   ClusterIP   10.103.48.81           80/TCP    6m7s

NAME                                    READY   STATUS    RESTARTS   AGE
pod/webserver-754db6dc6-jrtf4           1/1     Running   0          6m12s
pod/webserver-754db6dc6-jsxtt           1/1     Running   0          6m12s
pod/webserver-canary-7f9f87794f-r8tnv   1/1     Running   0          11s

In the typical canary deployment, a majority of requests made to the service should go to the original pods. The canary deployment should have fewer active pods to enable a portion of that traffic (33% in the case of a service with 3 pods) to be routed to the canary:

$ curl 10.103.48.81

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

...

$ curl 10.103.48.81

<html><body><h1>It works!</h1></body></html>

$

If a gradual switch to a new version is not needed, then the blue/green strategy can be implemented instead. In a blue/green strategy, the network endpoint (the service) is instructed to send all traffic to new versions of the application that serve as the back end.

Given the following scenario, with a service backed by NGINX and a “new” webserver backed by Apache webserver:

$ kubectl get svc,pods

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1              443/TCP   21h
service/webserver    ClusterIP   10.103.48.81           80/TCP    30m

NAME                                 READY   STATUS    RESTARTS   AGE
pod/new-webserver-869b87b4c7-4vsvw   1/1     Running   0          19s
pod/new-webserver-869b87b4c7-6x8sh   1/1     Running   0          18s
pod/new-webserver-869b87b4c7-8nqrh   1/1     Running   0          18s
pod/webserver-754db6dc6-jrtf4        1/1     Running   0          30m
pod/webserver-754db6dc6-jsxtt        1/1     Running   0          30m

$

For a blue-green deployment, switching the service’s selector (which determines which pods a service send traffic to) ensures that the service goes from the blue backend (NGINX) to the green backend (httpd).

$ kubectl set selector svc webserver app=new-webserver

service/webserver selector updated

$

Now, 100% of all requests go to the new, Apache webserver while the old NGINX websever can be safely retired:

$ curl 10.103.48.81

<html><body><h1>It works!</h1></body></html>

$ curl 10.103.48.81

<html><body><h1>It works!</h1></body></html>

$ curl 10.103.48.81

<html><body><h1>It works!</h1></body></html>

$

Learn more about blue/green deployments and canary deployments.