CANARY DEPLOYMENTS WITH KUBERNETES AND
JENKINS
Today we'll look at canary deployments
with Kubernetes. Your team is building an application, but there were some
recent deployments that introduced bugs. They tested and tested and tried to
ensure that no bugs, but unfortunately anytime they deploy the application they
still have some bugs.
Now we want to mitigate these kinds of
issues, therefore the team has requested you to develop a Canary deployment.
That means that when we want to deploy new code, we will actually release that
code into production to a portion of our user base, so it will not be used by
everyone, but a certain percentage of people will be using the new code even if
they are unaware of it, and once we verify that everything is up and running
and everything looks good with that code, we will proceed to roll it out to the
entire population. Our application is presently running on a Kubernetes
cluster, and the team is using a Jenkins pipeline to execute continuous
integration and deployments, thus we will need to add lo`gic to this existing
pipeline to accomplish the Canary deployment.
SETUP YOUR CODE
REPO AND JENKINS
Ø
First,
we need to go to this code and fork the repo: https://github.com/ACloudGuru-Resources/cicd-pipeline-train-schedule-canary.
Ø
After
creating your personal fork, edit the Jenkinsfile and put in your DockerHub
username.
Ø
Log
Into our Jenkins Server
SET UP OUR
JENKINS CREDENTIALS
Select Manage
Jenkins > Credentials from the menu.
From the single
credential present, click on global, then Add Credentials.
Enter your
personal GitHub user name in the Username section.
Copy your Github
token, and back in Jenkins, paste the token into the Password field.
Set the ID to
github_key and the Description to GitHub Key.
Click Create.
ADD DOCKER HUB
CREDENTIALS
Click + Add
Credentials.
Provide your
Docker Hub username and password in the corresponding fields.
Set the ID to
docker_hub_login and the Description to Docker Hub.
Click Create.
ADD KUBERNETES
CREDENTIALS
Click + Add
Credentials.
Set the Kind to
Kubernetes configuration (kubeconfig)
Set the ID to
kubeconfig and the description to Kubeconfig.
SSH into the Cloud
Server Kubernetes Master host.
Run the following:
ssh cloud_user@
cat ~/.kube/config
Copy the contents
of the file that appears.
Back in our
Jenkins browser, paste what was copied into the Enter directly > Content
section.
Click Create.
SET UP THE PROJECT
Go back to the main
page by selecting the Jenkins icon at the top left of the website.
Click New Item.
Give the item the
name
Select Multibranch
Pipeline and click OK.
Under Branch
Sources, change the Add source to GitHub.
Set up the page as
follows:
Credentials:
Option that ends in (GitHub Key)
Repository HTTPS
URL: your github repository
Select Save.
BUILD THE JOB IN JENKINS
Click on our
Kubernetes server, and enter the following to review our deployment:
kubectl get pods
launch the
application with Kubernetes master ip address and port 8080
ADD A CANARY STAGE TO THE PIPELINE
To complete this,
you will need to do the following:
Go back to GitHub
and go to the fork that we made.
Copy the
train-schedule-kube-canary.yml code.
Click Add file
> Create new file.
Name the file train-schedule-kube-canary.yml.
Paste in the
train-schedule-kube-canary.yml code.
Click Commit new
file.
Select the
Jenkinsfile, which can be found here.
Add a new stage after the Push Docker Image stage and before DeployToProduction
kind: Service
apiVersion: v1
metadata:
name: train-schedule-service-canary
spec:
type: NodePort
selector:
app: train-schedule
track: canary
ports:
- protocol: TCP
port: 8080
nodePort: 8081
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: train-schedule-deployment-canary
labels:
app: train-schedule
spec:
replicas: $CANARY_REPLICAS
selector:
matchLabels:
app: train-schedule
track: canary
template:
metadata:
labels:
app: train-schedule
track: canary
spec:
containers:
- name: train-schedule
image: $DOCKER_IMAGE_NAME:$BUILD_NUMBER
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 15
timeoutSeconds: 1
periodSeconds: 10
resources:
requests:
cpu: 200m
Jenkinsfile
pipeline {
agent any
environment {
//be sure to replace "willbla" with your own Docker Hub username
DOCKER_IMAGE_NAME = "willbla/train-schedule"
}
stages {
stage('Build') {
steps {
echo 'Running build automation'
sh './gradlew build --no-daemon'
archiveArtifacts artifacts: 'dist/trainSchedule.zip'
}
}
stage('Build Docker Image') {
when {
branch 'master'
}
steps {
script {
app = docker.build(DOCKER_IMAGE_NAME)
app.inside {
sh 'echo Hello, World!'
}
}
}
}
stage('Push Docker Image') {
when {
branch 'master'
}
steps {
script {
docker.withRegistry('https://registry.hub.docker.com', 'docker_hub_login') {
app.push("${env.BUILD_NUMBER}")
app.push("latest")
}
}
}
}
stage('CanaryDeploy') {
when {
branch 'master'
}
environment {
CANARY_REPLICAS = 1
}
steps {
kubernetesDeploy(
kubeconfigId: 'kubeconfig',
configs: 'train-schedule-kube-canary.yml',
enableConfigSubstitution: true
)
}
}
stage('DeployToProduction') {
when {
branch 'master'
}
environment {
CANARY_REPLICAS = 0
}
steps {
input 'Deploy to Production?'
milestone(1)
kubernetesDeploy(
kubeconfigId: 'kubeconfig',
configs: 'train-schedule-kube-canary.yml',
enableConfigSubstitution: true
)
kubernetesDeploy(
kubeconfigId: 'kubeconfig',
configs: 'train-schedule-kube.yml',
enableConfigSubstitution: true
)
}
}
}
}
RUN A SUCCESSFUL DEPLOYMENT
Check on our website that everything is working by putting in the Public IP address for our Kubernetes with port :8081 at the end.
Once we know the site is working, go back to Jenkins, hover over DeployToProduction, and click Proceed.
On our Kubernetes server,we see the new node running
No comments:
Post a Comment