Skip to content

Commit 16b40c0

Browse files
committed
adding Project-17
1 parent d26beb2 commit 16b40c0

23 files changed

+322
-0
lines changed
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
# Project-17: Continuous Delivery for Docker Containers
2+
3+
[*Project Source*](https://www.udemy.com/course/devopsprojects/?src=sac&kw=devops+projects)
4+
5+
![](images/Project-17.png)
6+
7+
## Pre-requisites
8+
9+
* Kubernetes setup with kops from Project-15
10+
* Jenkins, Nexus and Sonar server setup from Project-5
11+
* DockerHub user account
12+
* GitHub account
13+
* Slack account
14+
15+
_Friendly reminders:_
16+
17+
* I have completed these projects under my "20 Days 20 DevOps Projects" challenge.
18+
* Projects named as Project-1 thru Project-20 as part of this challenge
19+
* I have been using same Jenkins, Nexus and SonarQube servers from Project-5 and kops server from Project-14.
20+
* This project cannot be completed without having same setup.
21+
* Make sure you configure jenkins credentials, global tool and system with same credential names used in Jenkinsfile.
22+
* Make sure you have necessary tools installed as mentioned in previous projects.
23+
* You may need to update Sonar webhook and Github webhook with new url.
24+
* You may need new Token for integrations.
25+
GOOD LUCK!
26+
27+
### Step-1: Jenkins, Sonar and Docker Integration
28+
29+
_Note: If you have been using the same Jenkins server from previous projects, Jenkins may run out of volume. In that case, go to AWS console, select Jenkins instance, click volume under Storage section. Acions --> Modify Volume. Increase volume form 8 to 16 GB._
30+
31+
Go to source code, we will use files under `cicd-kube` branch from below repository:
32+
```sh
33+
https://github.com/devopshydclub/vprofile-project.git
34+
```
35+
#### Jenkins-Sonar Integration
36+
37+
So far we should have 3 running servers(Jenkins, Sonar and kOps) with proper configuration setup from previous steps as mentioned in pre-requisites.
38+
39+
First we will create a new token in Sonar server.
40+
41+
![](images/sonar-token.png)
42+
43+
Go to Jenkins server, `Manage Jenkins` -> `Configure System` . Find section named as `SonarQube Servers`.
44+
```sh
45+
Name: sonar-pro # use the same name, it will be used in our Jenkinsfile
46+
Server URL: http://<private_ip_of_sonar_server>
47+
Server Authentication token: Add the new token as secret text
48+
```
49+
50+
![](images/jenkins-sonar-configuration.png)
51+
52+
Add below security group Inbound rule to Jenkins-SG:
53+
```sh
54+
Allow all traffic from Sonar-SG
55+
```
56+
57+
Add below security group Inbound rule to Jenkins-SG:
58+
```sh
59+
Allow all traffic from Jenkins-SG
60+
```
61+
62+
#### Jenkins-DockerHub Integration
63+
64+
We need to add our DockerHub credentials to Jenkins.( _PS: If you don't have an DockerHub account, you can create a free account._)
65+
66+
Go to `Manage Jenkins` -> `Manage Credentials` -> `Add credentials`. As ID we will give `dockerhub` which is used in Jenkinsfile.
67+
68+
![](images/dockerhub-creds.png)
69+
70+
#### Install Docker engine in Jenkins server
71+
72+
Next we will SSH into Jenkins server to install docker engine. Our Jenkins server is running on Ubuntu machine. We will follow official [documentation steps](https://docs.docker.com/engine/install/ubuntu/) to install docker for Ubuntu.
73+
74+
75+
After steps completed, we can check status od `docker` service.
76+
77+
![](images/docker-running.png)
78+
79+
The reason we are installing docker in Jenkins server, we will run docker commands during pipeline as jenkins user. Lets login as `jenkins` user and try to run any `docker` command.
80+
81+
![](images/permission-denied-error.png)
82+
83+
The reason for this permission error is, currently only `root` user is able to run docker commands. Also any user part of `docker` group can run docker commands. We will add jenkins user to docker group. First run below commands as root user, then switch to `jenkins` user to test `docker` commands.
84+
85+
![](images/jenkins-added-to-docker-grp.png)
86+
87+
To make sure `jenkins` user is added to docker grp, you can `reboot` server.
88+
89+
### Step-2: Jenkins Plugins Installation
90+
91+
Go to Jenkins server, `Manage Jenkins` -> `Manage Plugins` -> `Available`. We will install below plugins:
92+
```sh
93+
Docker Pipeline
94+
Docker
95+
Pipeline Utility Steps
96+
```
97+
Click `install without Restart`.
98+
99+
### Step-3: Kubernetes Cluster Setup
100+
101+
Next we will create our kubernetes cluster from `kops` instance. Lets SSH into kops instance. If you don't have a kops instance, please refer to `Project-14` for create one with necessary setup.
102+
103+
Now we will run kops command which will create kops cluster.(_Note: Don't forget to replace your domain name and s3 bucket name in the command._) Below command won't create cluster, it will create configuration of cluster.
104+
```sh
105+
kops create cluster --name=kubevpro.aws-devops-journey-of-rumeysadogan.net \
106+
--state=s3://vpro-kops-state-rd --zones=us-east-1a,us-east-1b \
107+
--node-count=2 --node-size=t3.small --master-size=t3.medium \
108+
--dns-zone=kubevpro.aws-devops-journey-of-rumeysadogan.net \
109+
--node-volume-size=8 --master-volume-size=8
110+
```
111+
112+
We can create cluster with below command, we need to specify the s3 bucket we use for state config.
113+
114+
```sh
115+
kops update cluster --name kubevpro.aws-devops-journey-of-rumeysadogan.net --state=s3://vpro-kops-state-rd --yes --admin
116+
```
117+
118+
It will take sometime to create cluster. We can install `helm` as next step.
119+
120+
### Step-4: Helm Installation
121+
122+
Helm is a package manager for Kubernetes. We will follow the helm installation steps from official [documentation](https://helm.sh/docs/intro/install/) for Ubuntu. Below steps shows how to download helm from binary. Always use official fdocumentation for installation steps to get latest version.
123+
124+
```sh
125+
cd /tmp
126+
wget https://get.helm.sh/helm-v3.10.3-linux-amd64.tar.gz
127+
tar xvzf helm-v3.10.3-linux-amd64.tar.gz
128+
cd linux-amd64/
129+
ls
130+
sudo mv helm /usr/local/bin/helm
131+
cd ~
132+
helm version
133+
```
134+
135+
### Step-5: Cluster state check
136+
137+
We can run `kubectl` command to check if our cluster is ready.
138+
```sh
139+
kubectl get nodes
140+
```
141+
142+
![](images/cluster-ready.png)
143+
144+
### Step-6: Git repo setup
145+
146+
We will create a GitHub repository with the name of `cicd-kube-docker`.
147+
then we will clone it to our kops instance.
148+
```sh
149+
git clone https://github.com/rumeysakdogan/cicd-kube-docker.git
150+
```
151+
152+
We will also clone the source code repository that we will be using a lot.
153+
```sh
154+
git clone https://github.com/devopshydclub/vprofile-project.git
155+
cd vprofile-project/
156+
ls
157+
git checkout vp-docker
158+
ls
159+
cp -r * ../cicd-kube-docker/
160+
cd ..
161+
cd cicd-kube-docker/
162+
ls
163+
```
164+
165+
We should see the copied files in our new repository directory. We will remove folders that are not needed.
166+
```sh
167+
rm -rf Docker-web/ Docker-db/ ansible/ compose/
168+
mv Docker-app/Dockerfile .
169+
rm -rf Docker-app/ helm/
170+
ls
171+
```
172+
173+
### Step-7: Helm charts setup
174+
175+
Go to `cicd-kube-docker` directory, we will create a directory called `helm` and run helm command to create our helm charts for vprofile project.
176+
177+
```sh
178+
cd cicd-kube-docker
179+
mkdir helm
180+
cd helm
181+
helm create vprofilecharts
182+
```
183+
184+
Helm will create a sample K8s templates under `templates` dirctory. We will remove all of them, and copy our K8s manifests from `kubernetes/vprofileapp` directory from our repo.
185+
186+
![](images/k8s-manifest-copied-to-helm-tmp.png)
187+
188+
We will run the application from latest image as a result of each build. For this reason we need to have a variable for imageTag instead of hardcoded value in `vproappdep.yml` file .
189+
190+
![](images/use-vars-behalf-image-tag.png)
191+
192+
After making above change now, we are ready to test our helm charts.
193+
194+
Go to root directory of your repository and create a new kubernetes namespace.
195+
```sh
196+
kubectl create ns test
197+
```
198+
199+
![](images/test-helm-stack.png)
200+
201+
We can also list our first stack from helm with below command:
202+
```sh
203+
helm list --namespace test
204+
```
205+
206+
![](images/helm-list.png)
207+
208+
Now we can delete our stack with below command:
209+
```sh
210+
helm delete vprofile-stack --namespace test
211+
```
212+
213+
We will create another namesapce which will be used in Jenkins:
214+
```sh
215+
kubectl create namespace prod
216+
```
217+
218+
Now we will add all files we have created under `cicd-kube-docker` repo to remote repository:
219+
```sh
220+
git add .
221+
git commit -m "adding helm charts"
222+
git push
223+
```
224+
225+
![](images/files-pushed-to-github.png)
226+
227+
### Step-8: Writing pipeline Code
228+
229+
We will create a Jenkinsfile in our source code repository. Open your local `cicd-kube-docker` repo in one of IDE. I will be using IntelliJ.
230+
Create `Jenkinsfile-rd` in the root directory.
231+
232+
233+
In the deploy stage of Jenkinsfile, we will use helm commands from kops instance. For this, we need to add our Kops instance as Jenkins slave.
234+
SSH into kops instance.
235+
236+
```sh
237+
sudo apt update && sudo apt install openjdk-11-jdk -y
238+
sudo mkdir /opt/jenkins-slave
239+
sudo chown ubuntu.ubuntu /opt/jenkins-slave -R
240+
java -version
241+
```
242+
243+
We need to update `Kops-SG` to allow `Jenkins-SG` to access this instance on port 22.
244+
245+
![](images/kops-sg.png)
246+
247+
Then, we need to go to Jenkins server and add Kops instance as jenkins slave. `Manage Jenkins` --> `Manage Nodes and Clouds` --> `new Node`
248+
```sh
249+
Name: kops
250+
Type: Permanent Agent
251+
Remote root directory: /opt/jenkins-slave
252+
Labels: KOPS # same will be used in Jenkinsfile
253+
Usage: Only build jobs with label expresiions matching this node
254+
Launch Method: Launch agents via SSH
255+
Host: Private IP of KOPS EC2 instance
256+
Credentials: Add new
257+
* Type: SSH username with private key
258+
* Username: ubuntu
259+
* Private Key: Paste kops-private key you have created before
260+
* ID: kops-login
261+
* Description: kops-login
262+
Host Key Verification Strategy: Non verifying Verification strategy
263+
```
264+
265+
Click `Launch Agent` to test the connection.
266+
267+
Once our `Jenkinsfile-rd` ready with all its contents, we will commit the changes to GitHub.
268+
269+
We have used SonarHome as `mysonarscanner4`in Jenkinsfile, we will go to Jenkins `Manage Jenkins` --> `Global Tool Configuration`. Find sonarQube and change name to `mysonarscanner4`. Then save it.
270+
271+
_If your pipeline fail in Quality Gate stage, create a new Quality gate in Sonar and add to your project. Make sure you create a Sonar webhook so that Sonarqube can communicate back with jenkins._
272+
273+
### Step-9: Execution
274+
275+
Create a new job in Jenkins with name of `kube-cicd` with type of Pipeline.
276+
```sh
277+
Pipeline Definition: Pipeline script from SCM
278+
SCM: Git
279+
Repository URL: https://github.com/rumeysakdogan/cicd-kube-docker.git
280+
branch: */master
281+
Script Path: Jenkinsfile-rd
282+
```
283+
284+
We are ready to click `Build Now`.
285+
286+
![](images/pipeline-success.png)
287+
288+
We can check our kubernetes deployment from `Kops instance`. SSH into Kops instance.
289+
290+
```sh
291+
helm list --namespace prod
292+
kubectl get all
293+
```
294+
295+
![](images/k8s-deployment-success.png)
296+
297+
We can get the LoadBalancer url and check application from browser.
298+
299+
![](images/login-page.png)
300+
301+
![](images/app-page.png)
302+
303+
![](images/db-running.png)
304+
305+
![](images/mc-running.png)
306+
307+
Lets check DockerHub repo for images:
308+
309+
![](images/dockerhub-imgs-pushed.png)
310+
311+
We also get slack notification as Success:
312+
313+
![](images/slack-notification.png)
314+
315+
### Step-10: Clean-Up
316+
317+
We can delete our cluster with below command:
318+
```sh
319+
kops delete cluster --name kubevpro.aws-devops-journey-of-rumeysadogan.net --state=s3://vpro-kops-state-rd --yes
320+
```
321+
322+
Then stop/terminate instances used during this project.
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)