Jenkins is an automation server used to build and test applications automatically. Jenkins provides a download for Windows and several Linux distributions. Jenkins also provides a Docker image for running Jenkins in a Docker container. In an earlier article, "Getting Started with Kubernetes on Amazon Web Services (AWS)," we discussed installing Kubernetes cluster on AWS using a CloudFormation stack. In this article, we shall run Jenkins using the Docker image "Jenkins" on the Kubernetes cluster. This article has the following sections:
- Setting the Environment
- Starting Jenkins
- Starting Jenkins with Imperative Syntax
- Starting Jenkins Declaratively
- Accessing Jenkins Dashboard
As a pre-requisite, we need to create a Kubernetes cluster on AWS EC2. The procedure to create a production-grade Kubernetes cluster on AWS using CloudFormation is discussed in an earlier article, "Getting Started with Kubernetes on Amazon Web Services (AWS)."
Having installed a Kubernetes cluster, next we shall run Jenkins on the cluster. We shall be using the Docker image "jenkins," which is available on the Docker Hub. Two options are available to run Jenkins on Kubernetes:
- Using Imperative Syntax on the Command Line
- Using Declarative Configuration Files
We shall discuss each of these approaches.
To run a Docker image on Kubernetes cluster using imperative syntax, use the kubectl run command:
./kubectl run Jenkins --image=Jenkins --replicas=3 --port=8080
A Kubernetes deployment called "jenkins" gets created, as shown in Figure 1. List the Kubernetes Pods cluster wide with the following command:
./kubectl get pods -o wide
The three Pods get listed. One Pod is running on one worker node and two Pods are running on another worker node. Initially, the Pods could be created as indicated by the ContainerCreating status in Figure 1.
Figure 1: Creating a Kubernetes Deployment for Jenkins
After a while (1-2 minutes or sooner), the three Pods are listed as Running, as shown in Figure 2.
Figure 2: Pods in Kubernetes Cluster Running
Next, expose a Kubernetes service of type LoadBalancer on port 8080. A LoadBalancer type service creates an AWS EC2 LoadBalancer to distribute client load across the cluster.
./kubectl expose deployment Jenkins --port --type=LoadBalancer
Subsequently, list the services.
./kubectl get services
The "Jenkins" service gets created and listed, as shown in Figure 3.
Figure 3: Creating and listing a Kubernetes Service for Jenkins
Describe the "jenkins" service.
./kubectl describe svc Jenkins
The service description lists the service labels, selector, type, and endpoints, as shown in Figure 4. The load balancer could be created initially, as indicated by the "creating load balancer" message.
Figure 4: Describing the Jenkins Service
The LoadBalancer is shown in Figure 5 and should be InService.
Figure 5: LoadBalancer InService
The Jenkins Dashboard may be accessed at the URL <public dns of load balancer>:8080, as we shall discuss in a later section.
In this section, we shall use a declarative approach to running Jenkins on Kubernetes. For this, we need to create two configuration files:
- The jenkins-rc.yaml file for the Kuebrnetes replication controller
- The jenkins-service.yaml file for the Kubernetes service
The jenkins-rc.yaml file specifies the replication controller for Jenkins and includes the labels, the number of replicas to create, the Docker image to use, and the ports for the application. The jenkins-rc.yaml file is listed here:
--- apiVersion: v1 kind: ReplicationController metadata: labels: app: jenkinsapp name: jenkins-rc spec: replicas: 3 selector: app: jenkinsapp template: metadata: labels: app: jenkinsapp spec: containers: - image: jenkins name: jenkins ports: - containerPort: 50000 - containerPort: 8080
The jenkins-service.yaml file specifies the Jenkins service to create, including the ports where the service is exposed. The service selector expression app: jenkinsapp, which translates to app=jenkinsapp when the service is created, must be the same as one of the labels in the replication controller spec template. The app: jenkinsapp label is included in the spec>template>metadata>labels field of the jenkins-rc.yaml file. The jenkins-service.yaml file is listed next:
--- apiVersion: v1 kind: Service metadata: labels: app: jenkinsapp name: jenkins spec: ports: - port: 50000 name: api - port: 8080 name: web selector: app: jenkinsapp
The jenkins-rc.yaml file and the jenkins-service.yaml file must be valid YAML and the formatting may be validated in a YAML Lint. Additionally, the syntax of the configuration files must conform to the schema for the replication controller and the service, respectively. The jenkins-service.yaml file is shown in vi in Figure 6.
Figure 6: The jenkins-service.yaml file in vi
The jenkins-service.yaml file and the jenkins-rc.yaml file need to be created in or copied to the Kuebrnetes controller instance. Run the following command to create a replication controller:
./kubectl create -f jenkins-rc.yaml
The replication controller gets created, as indicated by a message in Figure 7. List the cluster-wide Pods:
./kubectl get pods -o wide
The three Pods, one on each node, get listed (see Figure 7).
Figure 7: Creating Replication Controller and listing Pods
Next, create a Kubernetes service:
./kubectl create -f jenkins-service.yaml
The "Jenkins" service gets created, as shown in Figure 8. List the services.
./kubectl get services
The "Jenkins" service gets listed, as shown in Figure 10 also.
Figure 8: Creating and listing Kubernetes Service for Jenkins
An EC2 LoadBalancer for the Jenkins service gets created, as shown in the AWS Management console in Figure 9.
Figure 9: LoadBalancer for the Kubernetes Service
Select the Listeners tab and TCP listeners for Load Balancer Ports 8080 and 50000 should be available, as shown in Figure 10.
Figure 10: LoadBalancer Listeners
The LoadBalancer status should be InService for all the instances, as shown in Figure 11.
Figure 11: Instances InService
List the replication controller:
./kubectl get rc
The jenkins-rc replication controller should get listed, as shown in Figure 12.
Figure 12: Listing the Replication Controller
An issue presently with the Docker image "jenkins" is that it generates a different password for each of the Pods. To avoid generating multiple passwords that would make it infeasible to log in to the Jenkins Dashboard, scale the Kubernetes replication controller to one replica.
./kubectl scale jenkins-rc --replicas=1
The replication controller gets scaled down to one replica, as shown in Figure 13. Subsequently, one Pod gets listed with the ./kubectl get pods command.
Figure 13: Scaling down the Replication Controller
To access the Jenkins Dashboard, we need to find the password that is automatically generated when the Kuebrnetes replication controller is created. The password may be found from the logs of a Pod by using the following command in which <pod> is the Pod name.
./kubectl logs <pod>
As listed in the logs in Figure 14, an "admin" user has been created and a password generated. Copy the password.
Figure 14: Obtaining the password from the Pod logs
The Jenkins Dashboard may be accessed at URL http://<lb dns>:8080, in which <lb dns> is the DNS of the LoadBalancer for the Jenkins Kubernetes service. Obtain the Public DNS from the AWS Management Console, as shown in Figure 15.
Figure 15: Obtaining the DNS name of the load balancer
Open the URL in a browser to display the Getting Started page, as shown in Figure 16. Specify the Administrator password and click Continue.
Figure 16: Starting Jenkins Dashboard
In Customize Jenkins, click Install suggested plugins, as shown in Figure 17.
Figure 17: Install suggested plugins
In Create First Admin User, an admin user may be created (optionally), as shown in Figure 18. Alternatively, click Continue as admin to skip creating an Admin user.
Figure 18: Creating or skipping creating first admin user
If creating the first admin user is skipped, the username "admin" and the automatically generated password must be used to log in to Jenkins Dashboard. Click Start using Jenkins, as shown in Figure 19.
Figure 19: Start Using Jenkins
The Jenkins Dashboard gets displayed, as shown in Figure 20.
Figure 20: Jenkins Dashboard
In this article, we discussed using the Docker image "jenkins" to create a Kubernetes service and replication controller for a Jenkins automation server. This article concludes a two-article tutorial on using Jenkins on a Kubernetes cluster.