Introduction
Continuous Integration and Continuous Deployment (CI/CD) pipelines that are efficient and automated are critical in the fast-paced world of software development for delivering high-quality applications with speed and precision. This detailed article explains how to create seamless deployments by combining Jenkins, Helm, and Kubernetes.
Continuous Integration and Continuous Deployment streamline the software development lifecycle by automating the process of testing, building, and deploying code changes. This not only accelerates the release cycle but also ensures the reliability and consistency of applications
Prerequisites
- A Kubernetes Cluster
- Helm – Initialized and set capable of deploying applications
- A Cluster Role with required RBAC permissions
- A Cluster Role binding assigned to the previous Cluster Role and Service Account
- The reference link below provides how to set the above roles and external DNS –
- https://platform9.com/learn/tutorials/external-dns
- Jenkins – Configure aws cli, should be able to communicate to Kubernetes cluster configure kubectl (/.kubectl/config) in Jenkins home folder.
- A spare domain name to test the ExternalDNS.
In this post we see how we achieve Continuous Delivery (CD) piece to build a CI/CD pipeline so we can deploy an applications to Kubernetes Clus. As part of the deployment process Helm is used as package manager. Helm is a Kubernetes deployment tool for automating creation, packaging, configuration, and deployment of applications and services to Kubernetes, helps to build consistent deployments on Kubernetes clusters. For details see To learn more about Helm.
Helm has four main components required to be executed are as follows:
1. A Chart.yaml
2. A Values.yaml
3. Charts Directory for other Charts
4. Templates (Directory), this is where Helm finds the YAML definitions for your Services, Deployments and other Kubernetes objects. Deploying an nginx deployment that needs a service, configmap and secrets. we need to have deployment.yaml, service.yaml, config.yaml and secrets.yaml all in the template dir. They will all get their values from values.yaml from above.
We will be deploying an nginx application using Helm chart. Helm has the below folder structure-
Configure the Pipeline:
Jenkinsfile needs to be configured which is a text file that contains the definition of a Jenkins Pipeline and is checked into source control. The below file is for Pipeline which implements a basic three-stage continuous delivery pipeline. For our deployment, the Jenkins file in this repository is being used for deploying the Nginx app
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage(‘Build') {
steps {
echo 'Building..*'
}
stage(‘Test') {
steps {
echo ‘Testing. .'
}
stage('Deploy') {
steps {
echo ‘Deploying.
While we have Helm chart and Jenkins File setup, further configure the webhook in bitbucket to trigger build in Jenkins whenever the code is committed
Before the initial deployment of the Nginx app, go through the helm folder which contains the manifests in YAML format.
For example:
– values.yaml is used to declare variables to be passed into the templates.
– deployment.yaml defines our deployment
– service.yaml defines how the application is exposed outside a Kubernetes cluster.
apiVersion: v1
kind: Service
metadata:
name: nginxpp-service
annotations:
service. beta. kubernetes
io/aws-load-balancer-ssl-cert: [redacted]
service. beta. kubernetes.io/aws-load-balancer-healthcheck-protocol: “TCP”
service. beta. kubernetes.io/aws-load-balancer-protocol: “TCP
0/aws-load-balancer-ssl-ports: "443"
external-dns.alpha.kubernetes.io/hostname: extdns.k8sdemo.cloudzenix.in
lee:
service. beta. kubernetes
spec:
type: LoadBalancer
port:
- port: 443
targetPort: http
selector:
app-kubernetes.io/name: {{ template “nginx.name” . }}
app-kubernetes.io/instance: {{ .Release.Name }}
Deploy External DNS Service on Kubernetes Cluster
Kubernetes contains an internal DNS module that automatically discovers and assigns DNS names to individual containers when instructed. In practice, this works very well. However, we frequently need to expose some or all parts of the Kubernetes cluster to the public. For instance, if a cluster exists inside a public cloud provider such as AWS or Google Cloud Platform, we would like to have a container service that interacts with this cloud provider and changes any A Records to point to the nodes that expose those services.
- This is what the ExternalDNS project does. ExternalDNS is a Kubernetes project with the main purpose of automatically creating DNS records for Service or Ingress resources.
- Before the application is deployed, setup external-dns using helm
$ helm upgrade –install external-dns bitnami/external-dns –namespace external-dns –create-namespace –set provider=aws
- This enables to creation of Route53 A records for the application, which is exposed over a Load Balancer.
- Post setup of external DNS, add annotations in service.yaml file as shown above.
- Having a set of all the above, now be able to deploy the application by triggering a build by committing code in bitbucket.
Conclusion:
Implementing an automated CI/CD pipeline with Jenkins, Helm, and Kubernetes empowers development teams to deliver software faster, more reliably, and with greater consistency. By embracing these tools, organizations can stay competitive in the ever-evolving landscape of modern software development.