Skip to content

Instantly share code, notes, and snippets.

@cmwylie19
Last active December 5, 2022 13:11
Show Gist options
  • Select an option

  • Save cmwylie19/92ac9a7f2840d7ac5571b51ad1c4bd74 to your computer and use it in GitHub Desktop.

Select an option

Save cmwylie19/92ac9a7f2840d7ac5571b51ad1c4bd74 to your computer and use it in GitHub Desktop.

Canary Deployment in Kubernetes

We are going to deploy an nginx app with 2 versions, blue and green. We will mount the index.html to the deployments to show which version we are looking at. Then we will create a service with labels pointing to both versions, and control the flow of traffic between the blue version to the green version through pod replicas in the deployment.

Create the resources

Create the demo namespace

k create ns demo
k config set-context $(k config current-context) --namespace=demo

Create a pod that we will use to curl the service.

k run curler --image=nginx --port=80 --restart=Never --command -- sleep 9999

Create a blue deployment and mount index.html from a configmap

kubectl apply -f -<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
    version: blue
  name: nginx-blue
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
        version: blue
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - mountPath: /usr/share/nginx/html
            name: index
      volumes:
        - name: index
          configMap:
            name: blue-config
---
apiVersion: v1
data:
  index.html: |
    <html>
    <body>
    Blue Version
    </body>
    </html>
kind: ConfigMap
metadata:
  name: blue-config
  namespace: demo
EOF

Create a green deployment and mount index.html from a configmap

kubectl apply -f -<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
    version: green
  name: nginx-green
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
        version: green
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - mountPath: /usr/share/nginx/html
            name: index
      volumes:
        - name: index
          configMap:
            name: green-config
---
apiVersion: v1
data:
  index.html: |
    <html>
    <body>
    Green Version
    </body>
    </html>
kind: ConfigMap
metadata:
  name: green-config
  namespace: demo
EOF

Create a service with the label selector pointing to both versions and control the canary rollout based on replicas

kubectl apply -f -<<EOF
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: demo
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: ClusterIP
EOF

Demo

We should have 75% of the traffic going to the blue version right now and 25% going to green.

Now lets curl the nginx service. (Make sure you copy the command as it, no \)

for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done

expected output

<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>

Lets split the traffic 50/50.

k patch deploy/nginx-green -p '{"spec":{"replicas":4}}' 

The blue and green deployment both have 4 replicas, so the traffic should be distrubted evenly mongst the pods.

Now lets curl the nginx service again. (Make sure you copy the command as it, no \)

for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done

expected output

<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>

You have successfully done a blue/green deployment

Lets split the traffic 25/75.

k patch deploy/nginx-green -p '{"spec":{"replicas":16}}' 

The blue deployment has 4 replicas, the green has 16. 75% of Traffic should go to green.

for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done

output:

<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>

Clean up

k delete pods,svc,deploy,cm --all --wait

k delete ns demo --wait
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment