Canary Deploys with Kubernetes
Table of Contents
Canary Deploys with Kubernetes
This guide shows how to use canary deploys in kubernetes using a service object to split direct traffic to two different deployments
gcloud config set compute/zone us-central1-a
# Set dynamically on Cloudshell or set explicitly if local
export PROJECT_ID=$(gcloud info --format='value(config.project)')
Enable APIs
gcloud services enable container.googleapis.com --async
gcloud services enable containerregistry.googleapis.com --async
gcloud services enable cloudbuild.googleapis.com --async
gcloud services enable sourcerepo.googleapis.com --async
Create the cluster
gcloud container clusters create test-cluster
gcloud container clusters get-credentials test-cluster
Code the Application
Using Cloud Shell, write a simple Node.js server that you’ll deploy to Kubernetes Engine:
server.js
var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end("Hello World! - V1");
}
var www = http.createServer(handleRequest);
www.listen(8080);
node server.js
Use the built-in Web preview feature of Cloud Shell to open a new browser tab and proxy a request to the instance you just started on port 8080. If you don’t see this feature in the Cloud Shell toolbar, click Navigation menu to close the left pane.)
A new browser tab will open to display your results:
Create your Docker Image
Dockerfile
FROM node:6.9.2
EXPOSE 8080
COPY server.js .
CMD node server.js
docker build -t gcr.io/$PROJECT_ID/hello-node:v1 .
docker run -it --rm -p 8080:8080 gcr.io/$PROJECT_ID/hello-node:v1
To see your results you can use the web preview feature of Cloud Shell:
gcloud docker -- push gcr.io/$PROJECT_ID/hello-node:v1
Create your Deployment resource
Create a deployment.yaml file that describes the details of your deployment
deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello
spec:
replicas: 3
template:
metadata:
labels:
app: hello
track: prod
spec:
containers:
- name: hello
image: gcr.io/[PROJECT_ID]/hello-node:v1
ports:
- name: http-server
containerPort: 8080
Expose it with a service
service.yaml
apiVersion: v1
kind: Service
metadata:
name: hello-service
labels:
app: hello
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: http-server
selector:
app: hello
Deploy to Kubernetes
kubectl apply -f .
kubectl get deployments
kubectl get services
View your deployment
Now that you see the IP address, open your browser to that address in my case that http://35.226.58.213/ and you should see
Hello World! - V1
Create a new V2 Docker image
server.js
var http = require('http');
var handleRequest = function(request, response) {
response.writeHead(200);
response.end("Hello World! - V2");
}
var www = http.createServer(handleRequest);
www.listen(8080);
docker build -t gcr.io/$PROJECT_ID/hello-node:v2 .
gcloud docker -- push gcr.io/$PROJECT_ID/hello-node:v2
Create and deploy a new Canary deployment
deployment-canary.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-canary
spec:
replicas: 1
template:
metadata:
labels:
app: hello
track: canary
spec:
containers:
- name: hello
image: gcr.io/[PROJECT_ID]/hello-node:v2
ports:
- name: http-server
containerPort: 8080
Create your deployment and service on Kubernetes with the apply command
kubectl apply -f ./deployment-canary.yaml
Retrieve the LoadBalancer IP again
kubectl get services
while true; sleep 1; do curl http://35.226.58.213; echo \n; done
Which should return something like
Hello World! - V1n
Hello World! - V1n
Hello World! - V2n
Hello World! - V1n