Zero-downtime Deployment in Kubernetes with Jenkins
Ever since we added the
Kubernetes supports the RollingUpdate strategy to replace old pods with new ones gradually, while continuing to serve clients without incurring downtime. To perform a RollingUpdate deployment: We'll use deployment of the official Tomcat image to demonstrate this: If the Tomcat running in the current deployments is version 7, we can replace Behind the scenes, Kubernetes manages the update like so: The Rolling Update strategy ensures we always have some Ready backend pods serving client requests, so there's no service downtime. However, some extra care is required: Blue/green deployment quoted from TechTarget A blue/green deployment is a change management strategy for releasing software code. Blue/green deployments, which may also be referred to as A/B deployments require two identical hardware environments that are configured exactly the same way. While one environment is active and serving end users, the other environment remains idle. Container technology offers a stand-alone environment to run the desired service, which makes it super easy to create identical environments as required in the blue/green deployment. The loosely coupled Services - ReplicaSets, and the label/selector-based service routing in Kubernetes make it easy to switch between different backend environments. With these techniques, the blue/green deployments in Kubernetes can be done as follows: As compared to Rolling Update, the blue/green up* The public service is either routed to the old applications, or new applications, but never both at the same time. Jenkins provides easy-to-setup workflow to automate your deployments. With
For the Rolling Update strategy, simply deploy the deployment configuration to the Kubernetes cluster, which is a simple, single step.Rolling Update
.spec.strategy.type
to RollingUpdate
(the default value)..spec.strategy.rollingUpdate.maxUnavailable
and .spec.strategy.rollingUpdate.maxSurge
to some reasonable value.
maxUnavailable
: the maximum number of pods that can be unavailable during the update process. This can be an absolute number or percentage of the replicas count; the default is 25%.maxSurge
: the maximum number of pods that can be created over the desired number of pods. Again this can be an absolute number or a percentage of the replicas count; the default is 25%.readinessProbe
for your service container to help Kubernetes determine the state of the pods. Kubernetes will only route the client traffic to the pods with a healthy liveness probe.apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deployment-rolling-update
spec:
replicas: 2
template:
metadata:
labels:
app: tomcat
role: rolling-update
spec:
containers:
- name: tomcat-container
image: tomcat:${TOMCAT_VERSION}
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
strategy:
type: RollingUpdate
rollingUp maxSurge: 50%
${TOMCAT_VERSION}
with 8 and apply this to the Kubernetes cluster. With the
maxUnavailable
pods in the desired Pods can be unavailable, that is, at least (replicas
- maxUnavailable
) pods should be serving the client traffic, which is 2-1=1 in our case.
Blue/green Deployment
TOMCAT_VERSION=7
and TARGET_ROLE
set to blue or green respectively.apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deployment-${TARGET_ROLE}
spec:
replicas: 2
template:
metadata:
labels:
app: tomcat
role: ${TARGET_ROLE}
spec:
containers:
- name: tomcat-container
image: tomcat:${TOMCAT_VERSION}
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
TARGET_ROLE=blue
.kind: Service
apiVersion: v1
metadata:
name: tomcat-service
labels:
app: tomcat
role: ${TARGET_ROLE}
env: prod
spec:
type: LoadBalancer
selector:
app: tomcat
role: ${TARGET_ROLE}
ports:
- port: 80
targetPort: 8080
kind: Service
apiVersion: v1
metadata:
name: tomcat-test-${TARGET_ROLE}
labels:
app: tomcat
role: test-${TARGET_ROLE}
spec:
type: LoadBalancer
selector:
app: tomcat
role: ${TARGET_ROLE}
ports:
- port: 80
targetPort: 8080
TARGET_ROLE=green
and TOMCAT_VERSION=8
in the deployment config to update the green environment.tomcat-test-green
test endpoint to ensure the green environment is ready to serve client traffic.TARGET_ROLE=green
.
Jenkins Automation
acsDeploy azureCredentialsId: 'stored-azure-credentials-id',
configFilePaths: "glob/path/to/*/resource-config-*.yml",
containerService: "aks-name | AKS",
resourceGroupName: "resource-group-name",
enableConfigSubstitution: true
Put It All Together