DevOps tool-chain setup on Kubernetes cluster. Part - 1/3
Tags: kubernetes, devops
Published: 2018-06-23 20:25:00

---
title: DevOps tool-chain setup on Kubernetes cluster. Part - 1/3
published: true
description: 
tags: #Kubernetes #DevOps
---

![alt text](https://thepracticaldev.s3.amazonaws.com/i/298l0v54pjqkldy2j34e.png "Kubernetes")
##Introduction
DevOps has become a part of the software lifecycle management with CI/CD pipeline to deliver a change to production in an automated way.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/8ko3m7l823612pap65zd.png "DevOps")

In CI/CD pipeline the popular open source tools are Github for source code repository, Jenkins for Continuous Integration, build, test & deployment orchestration, SonarQube for static code analysis and Nexus for artifacts repository. There are many open source tools available for testing too. This article is not much about DevOps or CI/CD pipline rather it will describe how to create the CI/CD pipeline on Kubernetes cluster environment using kubectl. 

###Containers:
These are methods of operating system virtualization that allows us to run an application and its dependencies in resource-isolated processes. Containers allows a developer to package an application with parts it needs, such as libraries and other dependencies, and ship it all out as one package. There are many container options that are available and Docker is one such open source container which is very widely used.

###Kubernetes:
It is a portable open-source platform for managing containerised workloads and services that facilitates both declarative configuration and automation. Kubernetes has become the default tool to manage the containers in most of the public, private & hybrid cloud and also on the bare metal systems.

This write-up describes on how to create Kubernetes cluster with Jenkins, Sonar, Nexus as pods on AWS cloud. It doesnt includes details about functionality of Jenkins, SonarQube, Nexus.

I have already write an article on setting up a Kubernetes cluster on AWS Cloud with one master and two worker nodes. For futher details refer the link - https://dev.to/sr_balaji/kubernetes-cluster-setup-on-aws-13m6

![alt text](https://thepracticaldev.s3.amazonaws.com/i/739ut1xpewm555pf418f.png "Kubernetes node details")

###Kubernetes components
The list of Kubernetes components that is used in this cluster are detalied below. I have provided a very high-level details on the Kubernetes components. For further details please refer https://kubernetes.io.

- Cluster: It is set of a physical or virtual machine and, in Kubernetes, all machine are managed as a cluster.

- Node: It is a worker machine in Kubernetes. It may be a Virtual or physical machine. (In this article I have used EC2 instance to provision the Kubernetes Cluster)

- Pod: It is a group of one or more containers (such as Docker containers), with shared storage/network, and a set of specifications to run the containers. A pod’s contents are always co-located, co-scheduled and runs in a shared context.

- Deployment: It provides declarative updates for Pods and ReplicaSets.

- Persistent Volume: It is a piece of storage in the cluster that has been provisioned by an administrator. It is a node in cluster resource.

- Persistent Volume Claim: It is a request for storage by an user.

- Service: It is an abstraction that defines a logical set of Pod(s)

- Storageclass: It provides a way for administrators to describe the “classes” of storage they offer.

###Kubernetes Cluster environment
In this Kubernetes cluster, I have created a single instance of the Jenkins, SonarQube & Nexus and configured in such a way that one instance of these servers is always available. The data of these servers are persisted, and even in the event of these servers getting crashed, it rebuilds automatically with the data that are preserved.

I have created separate storage class for Jenkins, SonarQube & Nexus with data persistence. Each of the servers are available as a separate pod with their ports exposed as a service. I have used deployment to create pods for individual tools.

###Jenkins Setup on the Kubernetes cluster
Jenkins is an open source  Continuous Integration (CI)/Continuous Delivery (CD) orchestration tool. It offers a simple way to set up a CI/CD environment for any languages & source code repositories. I have created the following list of Kubernetes components to host Jenkins server on the cluster.

####Storage class for Jenkins
I have created the storage class on the cluster for Jenkins data.


```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: jenkins-storage
  labels: 
    app: jenkins-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  zone: eu-west-2a
allowVolumeExpansion: true

```
####Persistent Volume for Jenkins
I have created a Persistent Volume claim and allocated 2GB as the storage space to presist Jenkins data.

```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: jenkins-data
  annotations:
    volume.beta.kubernetes.io/storage-class: "jenkins-storage"
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
```
####Deployment for Jenkins
I have created a deployment script which pulls the Jenkins official image from internet and I have configured Jenkins with the default port 8080. Its data are persisted on the persistent volume which is created in the previous step. This deployment is created with single Replica which means Kubernetes will make sure that one instance of Jenkins is always up & running. In this configuration the port is not exposed to the cluster which will be covered in the next section. 

```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: jenkins
        image: jenkins:2.60.3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        volumeMounts:
          - name: jenkins-home
            mountPath: /var/jenkins_home
      volumes:
        - name: jenkins-home
          persistentVolumeClaim:
            claimName: jenkins-data
```

####Service for Jenkins
I have created a Service to expose Jenkins on port 9500 rather than on its default port. 


```yaml
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  labels:
    app: jenkins
spec:
  type: NodePort
  ports:
    - port: 9500
      targetPort: 8080
      name: jenkinsport
  selector:
    app: jenkins
  type: LoadBalancer
    
```

I have created storage class, persistent volume, deployment, and service for Jenkins so far. All the components for Jenkins are created and it is up running.


```shell
$kubectl get deployment
$kubectl get pod
$kubectl get svc
```
###Conclusion
In this article, I have covered on how to setup Jenkins with single Replicaset on a Kubernetes cluster. I will cover the setup of SonarQube and Nexus in the next articles.

#####Note:
yaml files are space sensitive and the scripts that are available in this article  might have tab spaces instead of whitespace. These scripts will fail, if you copy and paste without changing the tab to whitespace.