Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sumitm01/ci-cd-for-docker-kubernetes-using-jenkins
This project contains documented details of implementation of a CI CD pipeline using Jenkins for Docker and Kubernetes
https://github.com/sumitm01/ci-cd-for-docker-kubernetes-using-jenkins
continous-deployment continous-integration docker docker-compose dockerfile dockerhub dockerhub-image helm-charts jenkins jenkins-pipeline jenkins-plugins jenkinsfile kops kubernetes pipeline-as-a-code
Last synced: about 1 month ago
JSON representation
This project contains documented details of implementation of a CI CD pipeline using Jenkins for Docker and Kubernetes
- Host: GitHub
- URL: https://github.com/sumitm01/ci-cd-for-docker-kubernetes-using-jenkins
- Owner: SumitM01
- License: gpl-3.0
- Created: 2023-07-16T05:55:37.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-07-19T11:16:26.000Z (over 1 year ago)
- Last Synced: 2024-11-22T23:09:41.656Z (about 1 month ago)
- Topics: continous-deployment, continous-integration, docker, docker-compose, dockerfile, dockerhub, dockerhub-image, helm-charts, jenkins, jenkins-pipeline, jenkins-plugins, jenkinsfile, kops, kubernetes, pipeline-as-a-code
- Language: Java
- Homepage:
- Size: 4.53 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CI-CD-for-Docker-Kubernetes-using-Jenkins
This project contains documented details of implementation of a CI CD pipeline using Jenkins for Docker and Kubernetes
## Overview
The project focuses on implementing continuous delivery for Docker containers ๐ณ. The aim is to continuously build Docker images and deploy them to a Kubernetes cluster ๐. This approach is commonly used in microservice architecture, but it can be applied anywhere containers are used.With continuous code changes, there needs to be a continuous build and test process ๐จ, as well as regular deployment of the containers ๐. The deployment process is typically handled by the operations team ๐ทโโ๏ธ, who manage the container orchestration tool like Kubernetes ๐. However, manual deployment can create dependencies ๐ and be time-consuming โฐ.
To address this, the project aims to automate the build and release process of container images, allowing for fast and continuous deployment as soon as code changes are made by developers ๐ป. This will be achieved through the implementation of a continuous delivery or deployment pipeline for Docker containers ๐ฆ.
## Services used
## Project Architecture
The following events happen serially:- A developer makes a code change and pushes it to GitHub ๐ป.
- Jenkins fetches the code, including the Dockerfile, Jenkinsfile, and Helm charts ๐ฅ.
- The code is tested and analyzed using Checkstyle and SonarQube scanner ๐, with results uploaded to SonarQube Server ๐.
- If the code passes all quality gates, an artifact is built with Maven ๐จ.
- A Docker build process starts to build the Docker image ๐ณ.
- If everything passes, the Docker image is pushed to Docker Hub ๐.
- Jenkins uses Helm to deploy the Helm charts to the Kubernetes Cluster ๐.
- The Helm chart deployment creates all necessary resources, such as pods, services, secrets, and volumes ๐ฆ.
- If any changes are made, such as a new image tag for an application pod, they are implemented ๐ง.## Implementation Details
### Continous Integration Setup ๐ ๏ธ
Follow the README.md file in https://github.com/SumitM01/CI-using-JenkinsโNexus-and-Sonaqube repository to create and setup the Continous Integration pipeline. Create instances for Jenkins and Sonarqube scanner only. Do not create an instance for Nexus artifact storage as it is not required.### Setup Jenkins server
- Install these additional plugins on Jenkins.
- Docker pipeline ๐ณ
- Log in to jenkins instance using SSH and install openjdk-11-jdk and openjdk-8-jdk using the following commands ๐ง
```bash
sudo apt update
sudo apt install openjdk-8-jdk -y
sudo apt install openjdk-11-jdk -y
```
![configure-jenkins-maven](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/884b5ddd-6ed8-48fa-a9b3-fc41e48b7d2a)
![configure-jenkins-credentials](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/e2d2e75f-a17f-4fb6-b619-dad633323ef3)- Configure JDK installation on Jenkins by providing Java_Home path.
![configure-jenkins-jdk-8](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/7c0cc15a-5a01-4476-8fca-0cea82c00356)
![configure-jenkins-jdk-11](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/54c88bc9-9d57-4143-b480-9365e66dc497)- Configure Sonarqube scanner and sonarqube server with sonarqube token ๐
![configure-jenkins-sonarqube-scanner](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/3d6dc20b-274d-4864-9f7c-c31d535d671e)
![configure-jenkins-system-sonarqube-server](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/74f8b9b9-d0dc-42ca-864c-e9a55e6dd44f)- SSH to the instance and install docker engine in it using the following commands ๐ณ
```bash
#!/bin/bash
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg -y
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
```
- Add Jenkins user to Docker group ๐ง
```bash
usermod -aG docker jenkins
```### Complete kOps pre-requisites
- Create a domain in GoDaddy and a subdomain in Route 53.๐
- Create a Domain on GoDaddy like this.๐ฑ๏ธ
![domain-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/d0104093-b08f-464c-b23f-07f6e20db5f9)- Create a sub-domain/hosted zone on AWS Route 53 like this.๐ฑ๏ธ
![sub-domain-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/8fa21120-8e2b-4021-83c6-33bfbd2488d6)- Copy the NameServer records to Godaddy DNS manager ๐ from the subdomain.
- After creation of hosted zone, copy the displayed records ๐.
![sub-domain-ns-recs](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/510fc11d-496b-4ce7-a860-c8ef7ab1840a)- **On Godaddy DNS Manager**
- Under *Nameservers* section, click on *Change Numservers* and paste the copied records individually.
![domain-ns-recs-replaced](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/f0612bcd-aa8a-421f-a591-e02c20d708fe)- Launch the kOps server instance with the following specifications ๐:
- *AMI*: Ubuntu 20/18
- *Instance type/*: t2.micro
- *Security Group Inbound Rules*: 22 allowed from your IP
![kops-server-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/d1c7e521-8cac-4a81-9b8f-80dd2619fd29)- Create an S3 bucket ๐ชฃ on the same region as the server.
- During creation of the bucket ensure the bucket is in the same zone as the kops server.
![s3-bucket-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/cbaa6172-9ada-431b-9921-6cdf17c1e9a7)- Create an IAM ๐ role for using awscli and store its credentials.
![iam-user-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/0c1f1212-cb9f-4b78-a6ee-a37f5b30a327)- Install awscli on kOps server and configure it with the IAM credentials ๐.
![configure-awscli](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/e87ae1db-2764-44fb-a43f-eb18e54e12e2)- Run the following command to download โฌ awscli :
```bash
apt get update
apt install awscli -y
```
- Install kubectl and kops from the kubernetes site ๐:
- Install kubectl using the following command ๐ง:
```bash
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
```
- Install kOps from Kubernetes site using the following command ๐ง:
```bash
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64
```
### Configure SSH key login to github remote:
- Generate the ssh keys on the kops server using ssh-keygen ๐
- Go to account settings -> SSH and GPG keys -> add key -> paste the contents of the public ssh key -> save ๐พ
![git-ssh-keys-created](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/65b17e78-dde6-4bba-9360-b2d28b0181a2)### Create a separate repository for the project ๐:
- Clone the created repo into your kops machine using SSH link ๐.
```bash
git clone [email protected]:git_username/git_repository_name.git
```
- ***IMPORTANT***: Cloning the repository on the machine validates the authentication using the created SSH keys๐.
- Copy the contents ๐ of the vprofile-project/cicd-kube branch.
- Clone ๐ the vprofile-project repo onto the kops machine.
```bash
git clone https://github.com/devopshydclub/vprofile-project.git
```
- Checkout to cicd-kube branch๐.
```bash
git checkout cicd-kube
```
- Copy all the files in the root to the created repository folder ๐.
```bash
cp -r * ../your_created_repo/
```
- Delete files inside your created repo that are not required: docker-db, docker-web, ansible,compose ๐๏ธ.
```bash
rm -rf docker-db docker-web ansible compose
```
- Copy dockerfile from inside docker-app folder to root and delete dockerapp folder ๐.
```bash
cp Dockerapp/Dockerfile .
rm -rf Dockerapp
```
- Delete ๐๏ธ contents ๐ inside helm/vprofilecharts/templates folder ๐ and replace them with contents of Deploying-an-application-on-Kubernetes- cluster/Setupfiles folder๐.
```bash
cd helm/vprofilecharts/templates
rm -rf
cd
git clone https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster.git
cp -r Deploying-an-application-on-Kubernetes-cluster/Setupfiles/* your_created_repo/helm/vprofilecharts/templates/
```
### Create an EC2 volume and configure it ๐ฝ:
- Create an EC2 volume using the following command๐ง:
```bash
aws ec2 create-volume --availability-zone=your_prefered_zone --size=3 --volume-type=gp2
```
![ec2-volume-created](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/eddbd266-e9ac-471e-91c9-4462cd424c68)- Note down the volume ID as displayed after volume creation๐.
- Specify the volume ID in the vprodbdep.yml file with the copied ID ๐ง.
- **On AWS console**
- Go to EC2 management console๐ฑ๏ธ.
- On Navigation Pane, go to volumes ๐ฑ๏ธ.
- Search for the created volume with the volume ID and select it๐.
- Click on Manage tags and add the following tag to it๐ง:
- Key : KubernetesCluster
- Value : your_subdomain_name
- ***IMPORTANT:*** This is necessary because without the cluster tags the volume won't get attached to the required instance for database purposesโก.
### Create Kubernetes Cluster using kops๐:
- Run the following command to create a Kubernetes cluster using kOps:๐
```bash
kops create cluster --name=your_subdomain_name --state=s3://your_bucket_name --zones=your_preferred_zone --node-count=2 --node-size=t2.small --master-size=t3.medium --dns-zone=your_subdomain_name
```
### Launch Kubernetes cluster using kops:๐ข
- Run the following command to launch the created cluster using kOps:๐
```bash
kops update cluster --name vprofile.sumitmishra.info --state=s3://vprofile-kube-project --yes --admin
```
- Wait for 10-15 minutes for the cluster to launch fully.โณ### Install Helm on the instanceโธ๏ธ
- While you wait for the cluster to be launched, you can install Helm on the kops server using the following commands
```bash
cd
wget https://get.helm.sh/helm-v3.12.2-linux-amd64.tar.gz
tar -zxvf helm-v3.12.2-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
helm --help
```
![Installing-helm](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/5979710e-aba6-4847-902f-5a86e561bb8c)### Check health of the cluster using kops:
- Run the following command to validate the created cluster using kOps:โ
```bash
kops validate cluster --name=vprofile.sumitmishra.info --state=s3://vprofile-kube-project
```
![cluster-validation](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/c589e62c-87dc-4404-93c1-09dc4433d064)### Configure nodes of kubernetes cluster:โ๏ธ
- Run the following command to taint all nodes to be Scheduled on launch.
```bash
kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule-
```
- ***IMPORTANT:*** This is very important because, the latest kubernetes versions do not allow scheduling to be done on control nodes which causes various errors during deployment, to avoid that we should allow scheduling on the control node.
- Run the following command to check whether all nodes have the same zone.โก
```bash
kubectl get nodes -L zone
```
- If there are no records under Zone then assign zones to individual nodes by running the following command for each node.
```bash
kubectl label nodes zone=your_prefered_zone
```
- ***IMPORTANT:*** This is necessary because the node should be in the same zone as the created volume in order to get attached to it and in the same zone as specified in the deployment files in order to not raise an error during deployment.โก### Configure Node on Jenkins and kops server: ๐ฅ๏ธ
- **On kops server**
- Connect to kops-server using SSH client.
- Using ubuntu user, install open-jdk-11 in the server.๐ฆ
```bash
sudo apt update
sudo apt install openjdk-11-jdk -y
```
- Create a folder as /opt/jenkins-slave and provide ownership of jenkins-slave to ubuntu user.๐
```bash
sudo mkdir /opt/jenkins-slave
sudo chown ubuntu.ubuntu /opt/jenkins-slave
```
- **On Jenkins server**
- Configure a node with the following settings:โ๏ธ
- Remote root directory : /opt/jenkins-slave
- Labels:KOPS
- Usage: only build jobs with label expressions matching this node
- Launch method:launch agents via ssh
- Host: private kops IP
- Credentials: kops instance private login key
- Host key verification strategy: non verifying verification strategy
- Availability: keep this agent online as much as possible### Write the Jenkinsfile โ๏ธ
- **On local_machine**
- Write a Jenkinsfile inside your-created-repository by referring to the Jenkinsfile present in vprofile-project/cicd-kube directory.
- Push the contents to github remote repo.### Configure and Run the pipeline:๐
- **On jenkins**
- Create a pipeline
- Choose Poll SCM and provide * * * * *
- Choose Pipeline script from SCM and provide your github repository, branch and Jenkinsfile path then save.๐พ
- Now commit to the repository then see that the pipeline gets automatically triggered after the commit.๐จ
- Wait for the pipeline to be completed successfully.โ
![Pipeline-success](https://github.com/SumitM01/CI-CD-for-Docker-Kubernetes-using-Jenkins/assets/65524561/89887083-1ba6-4395-8515-267371ead5c6)- After the successful completion of the pipeline do the following
### Create a Route53 record ๐
- **On kops server**
- SSH to kops-server.
- Run the following command to list all the running services in the project.๐
```bash
kubectl get svc
```
- Copy the Load balancer ARN from the displayed services.
- Create a new record in the hosted zone of route 53 with the value as the dns of load balancer.๐## Results๐
After everything is done, wait for 5-10 minsโณ then validate the services by accessing the website using the URL.๐
- We can see that the website is up and the frontend services are running fine.
**Login Page**
![login-page](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/bf3251d9-50da-4203-be7a-767d3a47d98c)**Welcome Page**
![welcome-page](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/25627cee-dcd4-4c03-9915-2b1695592b06)- Here we can see that the backend services have been created and configured and are also running fine.
**User details Page (Database Validation)**
![db-validation](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/2970b6b7-2336-429f-a20d-21c322864d01)**User details Page (Cache Validation)**
![cache-validation](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/1b129f62-1ce8-4613-a41c-d5a580ee3194)**Rabbitmq status Page**
![rabbitmq-page](https://github.com/SumitM01/Deploying-an-application-on-Kubernetes-cluster/assets/65524561/6f7ec5e4-843b-412d-851a-a17d4841f20f)
## Cleanup๐งน
- Cleanup the services one by one.
- Delete the cluster in the kops vm using the following command
```bash
kops delete cluster --name your_subdomain_name --state=s3://your_bucket_name --yes
```
- Take a snapshot of the entire stack and store it in an s3 bucket for future use.๐ฎ
- Poweroff/terminate the instances
- Delete security groups.๐๏ธ
- Delete S3 buckets if you don't require them.๐๏ธ
- Delete the hosted zone on AWS Route53 if not required.๐๏ธ## Conclusion
This project implmented the complete Continous Integration and Continous Deployment pipeline using Jenkins for production deployment on Docker and Kubernetes cluster. This ensures efficient and streamlined development process and maintenance of the application.As documented in this README file, I have invested MANY MANY HOURS of my time in **researching ๐, learning ๐, debugging ๐จโ๐ป** to implement this project. If you appreciate this document please give it a โญ, share with friends and do give it a try. Thank you for reading this! ๐
## References
- https://github.com/devopshydclub/vprofile-project/tree/cicd-kube
- https://www.udemy.com/course/decodingdevops
- https://Kubernetes.io
- https://hub.docker.com
- https://dcc.godaddy.com
- https://google.com