Pipelines for continuous integration and deployment, or CI/CD, are essential for expediting the development and delivery of software. One popular open-source CI/CD tool for developing, testing, and delivering apps is Jenkins. Reliability, scalability, and container orchestration are benefits of using Jenkins on Amazon Elastic Kubernetes Service (EKS). In order to create a reliable, containerised CI/CD solution, this article will show you how to set up Jenkins on AWS EKS.

Why use Jenkins on AWS EKS?

Running Jenkins on EKS allows for scalable CI/CD pipelines that leverage the full power of Kubernetes. EKS manages the Kubernetes control plane, while you focus on deploying and managing Jenkins. Jenkins on EKS also improves fault tolerance, streamlines resource management, and easily connects with AWS services.

Prerequisites

Before starting, ensure you have the following in place:

  • AWS Account with permissions to create and manage EKS resources.
  • kubectl and eksctl installed for interacting with your EKS cluster.
  • Basic knowledge of Kubernetes concepts, Jenkins, and CI/CD pipelines.

Setting Up Jenkins on AWS EKS

1. Setting Up the EKS Cluster

First- create an EKS cluster to host your Jenkins instance.

  • Create an EKS Cluster Using eksctl: To create a new EKS cluster, run the following command:
eksctl create cluster --name jenkins-eks-cluster --region us-west-2 --nodegroup-name jenkins-nodes --nodes 3 --nodes-min 1 --nodes-max 4 --managed
  • Update Kubeconfig: After the creation of the cluster, configure your kubectl to connect to the new cluster:
aws eks --region us-west-2 update-kubeconfig --name jenkins-eks-cluster

2. Setting Up Persistent Storage for Jenkins

Jenkins requires persistent storage to retain job data, configurations, and plugins.

  • Create an EBS Volume: Use AWS EBS as a persistent volume in EKS. When deploying Jenkins, configure persistent volume claims to leverage EBS for durability across pod restarts.
  • Install the Amazon EBS CSI Driver: This allows Kubernetes to make use of EBS volumes as persistent storage.
kubectl apply -k 
"github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/ecr/?ref=release-1.0"
  • Create Persistent Volume Claims (PVC) for Jenkins:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
spec:
  accessModes
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

This PVC will allocate 20 GB of EBS storage for Jenkins.

3. Deploying Jenkins on EKS

Now, let us deploy Jenkins as a service on the EKS cluster using a Jenkins Kubernetes manifest.

  • Create a Namespace for Jenkins:
kubectl create namespace jenkins
  • Deploy Jenkins Using Helm: Helm simplifies deploying applications on Kubernetes. You can use the Jenkins Helm chart to set up Jenkin quickly:
helm repo add jenkinsci https://charts.jenkins.io
helm repo update
helm install jenkins jenkinsci/jenkins --namespace jenkins --set persistence.existingClaim=jenkins-pvc
  • Access Jenkins: Retrieve the Jenkins admin password:
kubectl get secret --namespace jenkins jenkins -o 
jsonpath="{.data.jenkins-admin-password}" | base64 --decode

Forward the Jenkins port to access it locally:

kubectl port-forward svc/jenkins -n jenkins 8080:8080

Jenkins can be now accessed at http://localhost:8080 and log in with the retrieved admin password.

Configuring Jenkins for Kubernetes-Based CI/CD

Install the Jenkins Kubernetes Plugin to enable Jenkins to manage Kubernetes resources. Set up pod templates to dynamically run builds in containers. A sample pipeline might look like this:

pipeline {
    agent {
        kubernetes {
            yaml """
            apiVersion: v1
            kind: Pod
            spec:
              containers:
              - name: build
                image: maven:3.6.3-jdk-8
                command:
                - cat
                tty: true
            """
        }
    }
    stages {
        stage('Build') {
            steps {
                container('build') {
                    sh 'mvn --version'
                }
            }
        }
    }
}

Scaling Jenkins on EKS

Scaling Jenkins efficiently ensures optimal resource utilization:

  1. Enable Cluster Autoscaler: Automatically adjust the node pool size to accommodate Jenkins workloads. Install Cluster Autoscaler with:
helm install cluster-autoscaler stable/cluster-autoscaler
  1. Dynamic Agents: Use Kubernetes pod templates to create ephemeral build agents that are provisioned only during active builds, reducing idle resource costs.
  2. Horizontal Pod Autoscaler: Deploy the Horizontal Pod Autoscaler (HPA) to scale the Jenkins controller pods based on CPU or memory usage.
  3. Optimize Node Groups: Configure different node groups for varying workloads, ensuring the Jenkins master and agents run on appropriately sized instances.

Monitoring Jenkins on EKS

Monitoring is critical for maintaining performance and troubleshooting:

1. AWS CloudWatch Logs Insights:

Query Jenkins logs for build failures:

fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc

2. Prometheus and Grafana:

  • Install Prometheus to monitor metrics such as pod CPU and memory usage.
  • An example query to track resource usage:
rate(container_cpu_usage_seconds_total{namespace="jenkins"}[5m])
  • Use Grafana dashboards to visualize Jenkins build queue times, errors, and resource utilization.

3. Alerting:

  • Set up CloudWatch Alarms or Prometheus Alertmanager to notify you of high resource usage or job failures.

Securing Jenkins on EKS

  1. Restrict Permissions: Use AWS IAM Roles for Service Accounts (IRSA) to grant Jenkins the least privilege required.
  2. Secure Access:
    1. Enable HTTPS for the Jenkins UI.
    2. Restrict access to trusted IPs or use a VPN.
  3. Secrets Management: Use AWS Secrets Manager to securely store and retrieve Jenkins credentials.

Integrating AWS Services with Jenkins

One advantage of running Jenkins on AWS is the ability to integrate with AWS services seamlessly:

  • Amazon S3 for storing build artifacts.
  • AWS CodeCommit for source code repositories.
  • AWS Secrets Manager for securely managing credentials and secrets.

To allow Jenkins to access these services, configure IAM roles and policies with IRSA so that Jenkins can interact with these resources securely.

Conclusion

By incorporating containerization, you can create a highly scalable, containerized CI/CD pipeline that leverages Kubernetes’ flexibility and robustness by running Jenkins on AWS EKS. With this configuration, you can effortlessly manage CI/CD workflows by combining the automation features of Jenkins with the potent orchestration of EKS. With best practices in scaling, security, monitoring, and AWS EKS architecture, you will be well-equipped to deploy Jenkins effectively within an AWS ecosystem.

For clear insights on cloud technology, AWS EKS architecture, setting up CI/CD pipeline, Jenkins, and more, visit the CloudZenia website.