Cloud Native 13 min read

Integrating Kubernetes into CI/CD Pipelines with Jenkins, Ansible, and HAProxy

This tutorial explains how to incorporate Kubernetes into an existing CI/CD workflow using Jenkins, shared libraries, Docker, Ansible playbooks, and HAProxy to achieve high‑availability microservice deployments, covering tool setup, pipeline configuration, Dockerfile creation, Kubernetes manifests, and scaling new services.

Top Architect
Top Architect
Top Architect
Integrating Kubernetes into CI/CD Pipelines with Jenkins, Ansible, and HAProxy

Modern software teams deploy thousands of containers daily, and managing the complexity of scaling requires a robust CI/CD pipeline. This article demonstrates how to integrate Kubernetes into a traditional CI/CD workflow to achieve high availability and seamless production updates.

Tools used: Kubernetes, Jenkins (with shared libraries), Git, HAProxy, Ansible, Docker.

CI/CD installation: Set up a Jenkins server with Docker, Ansible, and kubectl; provision a three‑node Kubernetes cluster (one master, two workers) and an HAProxy load balancer.

Jenkins pipelines: Each microservice (shoppingapp‑home, shoppingapp‑kids, shoppingapp‑mens) has its own GitHub repository and a corresponding Jenkins pipeline job. The pipeline uses a shared library to define stages: Build (dockerbuild), Test, Publish (imagepush), Pull Playbook Repo, and Deploy.

@Library('jenkins-shared-library') _
pipeline {
    agent any
    environment {
        app = 'shoppingapp'
        service = 'shoppingapp-home'
        registryCredential = 'dockerhub'
        dockerImage = ''
        imageid = "deepanmurugan/shoppingapp-home:$BUILD_NUMBER"
    }
    stages {
        stage('Build') {
            steps { script { dockerImage = dockerbuild(imageid) } }
        }
        stage('Test') { steps { testcase() } }
        stage('Publish') { steps { script { imagepush(imageid) } } }
        stage('Pull Playbook Repo') { steps { dir('/tmp/ansible-playbooks/') { gitcheckout(branch: "master", repoUrl: "https://github.com/deepanmurugan/Ansible_Playbook.git") } } }
        stage('Deploy') { steps { dir('/tmp/ansible-playbooks/') { script { deploytok8s(imageid,app,service) } } } }
    }
}

The shared library provides helper functions such as dockerbuild (wraps docker build ), imagepush (logs into Docker Hub and pushes the image), and deploytok8s (runs an Ansible playbook to apply Kubernetes manifests).

Dockerfile example:

FROM python:3.7.3-alpine3.9
RUN mkdir -p /app
WORKDIR /app
COPY ./src/requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY ./src/ /app
ENV FLASK_APP=server.py
CMD flask run -h 0.0.0.0 -p 5000

The Docker image runs a simple Flask application on port 5000.

Ansible playbook (deploy_k8s.yml): Deploys the service, creates the Deployment, Service, and Ingress resources using templates that receive app_name , service_name , and image_id variables.

- hosts: localhost
  user: ubuntu
  tasks:
    - name: Deploy the service
      k8s:
        state: present
        definition: "{{ lookup('template', 'k8s/{{app_name}}/{{service_name}}/deployment.yml') | from_yaml }}"
        validate_certs: no
        namespace: default
    - name: Deploy the application
      k8s:
        state: present
        definition: "{{ lookup('template', 'k8s/{{app_name}}/{{service_name}}/service.yml') | from_yaml }}"
        validate_certs: no
        namespace: default
    - name: Deploy the Ingress
      k8s:
        state: present
        definition: "{{ lookup('template', 'k8s/{{app_name}}/common/ingress.yml') | from_yaml }}"
        validate_certs: no
        namespace: default

The Kubernetes cluster consists of one master node and two worker nodes (v1.19.4) and runs a Traefik Ingress controller exposed via NodePort 32365. HAProxy is configured to balance traffic between the two worker nodes.

frontend http_front
  bind *:80
  mode http
  default_backend http_back
backend http_back
  balance roundrobin
  server kube 172.31.35.122:32365 check
  server kube 172.31.40.13:32365 check

Real workflow: Developers push code to a microservice repo, a GitHub webhook triggers the corresponding Jenkins job, which builds the Docker image, runs tests, pushes the image, and invokes the Ansible playbook to deploy the updated image to the Kubernetes cluster.

Adding a new microservice: Create a new repository (e.g., shoppingapp‑ladies), copy the existing Jenkinsfile with the new service_name , add a new path in common/ingress.yml , and create the corresponding Deployment and Service manifests. The pipeline then automatically builds, pushes, and deploys the new service.

Original article: CI/CD with Kubernetes

DockerCI/CDmicroservicesKubernetesJenkinsAnsibleHAProxy
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.