For this case, we are going to use Google Cloud. There, a Kubernetes cluster will be created, Linux environment for development will be also created, and Jenkins will be deployed within Kubernetes.
This is part from the course of Linux Foundation called Implementing DevSecOps and it’s given by initcron.
Create a Kubernetes Cluster with GKE
First, it’s recommended to create a new project where the environment will be deployed. To do that, we just have to click in New Project.
For this case, the name is DevSecOps.
After creating the project, we should enable the Kubernetes Engine API. To enable it, we have to go to navegation menu → Kubernetes Engine → Clusters → Enable
we have to wait some minutes to have Kubernetes Engine Api activated.
When the Kubernetes, we can create the cluster with the following options.
- Cluster mode: Standard
- Release Channel: Rapid Channel
- Version: select the newest
As a result, we’ll have a Kubernetes cluster with 3 nodes.
Next, it’s recommended to create a firewall rule to allow connections from your public IP. to crteate the rule, we can do it from Navigation Menu → VPC Network → Firewall.
Then, we have to select the one which has the following naming convention: gke-cluster-X-XXXXX-all and add your IP.
Now it’s time to connecto to our cluster and the easiest way to do it, it’s using the cloud shell and execute the command suggested.
in this environment, this is the command:
1
gcloud container clusters get-credentials cluster-1 --zone us-central1-c --project devsecops-378701
After that, we can check the status of the cluster:
1
2
3
kubectl get nodes
kubectl config get-contexts
kubectl get pods --all-namespaces
Finally, check that we also have helm installed with the command helm version.
Creating a Linux Development Environment
The Linux VM is where our development environment will be. Here, we can test our apps with dockers before to put it in the deployment environment.
To create the Linux VM, we have to go to VM Instances and click in create instance wih those options:
- Size Disk: 30 GB
- Operating System: Ubuntu LTS
- Create or Import SSH Keys
- network tag: dev
- Startup Script: include this script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
apt-get update
apt-get install -y git wget
# Install Docker
apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
apt-key fingerprint 0EBFCD88
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install -yq docker-ce
cd /root
git clone https://github.com/codespaces-io/codespaces.git
curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
NOTE: Credits of the script and content of the course to initcron
Later, we have to create a FW rule to allow ssh connections from our IP.
Finally, to connect to the vm, we just use ssh and check docker is installed:
1
ssh user@ip
With that, we can confirm that our dev environment was successfully deployed.
Installing Jenkins
The objective of installing Jenkins is to use continuous integration. In this case, we’re going to use Helm. Remember that Helm is the package manager of Kubernetes.
To install Jenkins, we should follow those steps:
- add Jenkins repository
1 2
helm repo add Jenkins [https://charts.Jenkins.io](https://charts.Jenkins.io) helm repo update
- Create a namespace for CI
1
kubectl create namespace ci
- Create Jenkins.values.yaml file:
1 2 3 4 5 6 7 8
controller: serviceType: NodePort resources: requests: cpu: "400m" memory: "512Mi" limits: cpu: "2000m"
- Install Jenkins
1
helm install -n ci --values Jenkins.values.yaml Jenkins Jenkins/Jenkins
When the installation is donde, we have to follow the steps of the output to get the admin password and then login.
1
2
3
4
5
6
kubectl exec --namespace ci -it svc/Jenkins -c Jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
[output]t3P4I48zb90j7Dbr3aBC8J
export NODE_PORT=$(kubectl get --namespace ci -o jsonpath="{.spec.ports[0].nodePort}" services Jenkins)
export NODE_IP=$(kubectl get nodes --namespace ci -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
[output]http://10.128.0.6:31893
according to the previous output, we have to access this webpage http://10.128.0.6:319893. However, it’s an internal IP and we have to find the external IP adress. To find the external IP, we have to execute this command:
1
kubectl get nodes -o wide
In this case, the url is: http://35.223.160.114:31893/
Now, it’s time to configure Jenkins:
- change admin password.
- Go to Manage Jenkins → Plugin Manager → available plugins and install:
- Blue Ocean
- Configuration as Code
- Download now and install after restart
Setting a simple continuous Integration DevOps pipeline
Fort his case, we’re going to fork this java repo: https://github.com/lfs262/dso-demo. In this repo, we can see the Jenkins file and see how the pipeline will be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
pipeline {
agent {
Kubernetes {
yamlFile 'build-agent.yaml'
defaultContainer 'maven'
idleMinutes 1
}
}
stages {
stage('Build') {
parallel {
stage('Compile') {
steps {
container('maven') {
sh 'mvn compile'
}
}
}
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
container('maven') {
sh 'mvn test'
}
}
}
}
}
stage('Package') {
parallel {
stage('Create Jarfile') {
steps {
container('maven') {
sh 'mvn package -DskipTests'
}
}
}
}
}
stage('Deploy to Dev') {
steps {
// TODO
sh "echo done"
}
}
}
}
After forking the repo, in Jenkins we have to go to Blue Ocean. Blue Ocean is the UI created to run pipelines.
From there, create a new pipeline, link with github account and follow the steps for Jenkins can pull the code, the Jenkins file, create the pipeline, and push status updates to the Git repository on the commit history.
Then, Copy the token and paste in Jenkins
After, create pipeline. This action will read the repository, find the Jenkins file, create the pipeline, and launch it.
Also, you can confirm that our Jenkins jobs will be launched as a Kubernetes pods.
if you have some error during the CI, it’s because you need to update blue ocean and github plugins.
This is a simple Kubernetes native continuous integration pipeline.