Install and Deploy SonarQube in Kubernetes Cluster

Deploy SonarQube in Kubernetes Cluster with PostgreSQL

In this blog post, we are going to configure and run SonarQube with a database such as PostgreSQL, in kubernetes.

To follow along I assume you have a Kubernetes cluster running and are familiar with kubernetes Service, Statefulset, Configmap, PersistentVolume, PersistentVolumeClaim and Docker images.

Our aim is to run a sonarQube on kubernetes. if one of the nodes fails, pod will be automatically redeployed to a healthy node.

To Deploy SonarQube on Kubernetes we need to follow below steps:

1) Create Persistent Storage Volume for postgresSql.
2) PostgreSQL Statefulset to deployment.
3) Expose PostgreSQL Service
4) Create Persistent storage volume for SonarQube.
5) SonarQube Deployment
6) Expose SonarQube Service.

My Setup:

1) Create Persistent Storage Volume for postgresSql.

Since the data is persistent we don’t want to save our data inside the container’s storage. Instead, we want to mount external storage inside the Pod. In this Case even if Pod dies, our data stays safe. So We used “longhorn-static” Storage Class for provision the storage. To install Longhorn on any Kubernetes cluster refer the link.

Longhorn Provide very powerful UI. I assume you have a longhorn UI Access. To install Longhorn UI refer link. Click on volume –> Create Volume. Fill the details of Name, Size, replica.

Now create the PV/PVC for volume.

Provide the PV and PVC name’s along with namespace(In our case we used default namespace).

2) PostgreSQL Statefulset to deployment.

Now We have to create the postgres statefulset Yaml template. The statefulset Yaml template look like.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-statefulset
spec:
  selector:
    matchLabels:
      app: postgresdb
  serviceName: "postgresdb"
  replicas: 1
  template:
    metadata:
      labels:   
        app: postgresdb
    spec:
      containers:
      - name: postgres-pod
        image: postgres:latest
        ports:
        - containerPort: 5432
          name: postgresdb
        env:
        - name: POSTGRES_USER
          value: sonarqube
        - name: POSTGRES_PASSWORD
          value: "yourpassword"
        - name: POSTGRES_DB
          value: "sonardb"
        - name: PGDATA
          value: /var/lib/postgresql/data/sonardb
        volumeMounts:
        - name: postgres-pv-data
          mountPath: /var/lib/postgresql/data/
      volumes:
      - name: postgres-pv-data
        persistentVolumeClaim:
          claimName: postgres-datapv-claim

In this yaml file, we can see at the bottom of the file creating a volume claim automatically which we created earlier.

Now create the postgres statefulset.

# kubectl create -f postgresql-stateful.yaml 
statefulset.apps/postgres-statefulset created
#

Once you deploy the yaml. You can check on longhorn UI the volume will be attached with the postgres statefulset pod.

3) Expose PostgreSQL Service

Next resource to create is the postgres service so we access from SonarQube Pod. The postgres-service.yaml look like;

apiVersion: v1
kind: Service
metadata:
  name: postgresdb
  labels:
    app: postgresdb
spec:
  ports:
  - name: postgres
    protocol: TCP
    port: 5432
  selector:
    app: postgresdb

Create the service.

# kubectl apply -f postgres-service.yaml 
service/postgresdb created
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14h
postgresdb ClusterIP 10.97.21.29 <none> 5432/TCP 4s

Next, Try to access sonardb database by manually.

# kubectl get pod
NAME READY STATUS RESTARTS AGE
postgres-statefulset-0 1/1 Running 0 2m10s
# kubectl exec postgres-statefulset-0 -it -- /bin/bash
root@postgres-statefulset-0:/# psql -W sonardb -U sonarqube
Password: 
psql (13.0 (Debian 13.0-1.pgdg100+1))
Type "help" for help.

sonardb=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges 
-----------+-----------+----------+------------+------------+-------------------------
postgres | sonarqube | UTF8 | en_US.utf8 | en_US.utf8 | 
sonardb | sonarqube | UTF8 | en_US.utf8 | en_US.utf8 | 
template0 | sonarqube | UTF8 | en_US.utf8 | en_US.utf8 | =c/sonarqube +
| | | | | sonarqube=CTc/sonarqube
template1 | sonarqube | UTF8 | en_US.utf8 | en_US.utf8 | =c/sonarqube +
| | | | | sonarqube=CTc/sonarqube
(4 rows)

sonardb=# \q
root@postgres-statefulset-0:/#

Enter Password Which we set earlier  in postgres statefulset Yaml file.

4) Create persistent storage volume for SonarQube.

Similarly like previously using longhorn UI we created two PV’s for two locations to store data /opt/sonarqube/data/ and /opt/sonarqube/extensions/.

 

5) SonarQube Deployment.

After creating PVCs, we are ready to deploy using the following sonarqube YAML file.

--- 
apiVersion: apps/v1
kind: Deployment
metadata: 
  labels: 
    app: sonarqube-deployment
  name: sonarqube
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      app: sonarqube
  template:
    metadata:
      labels:
        app: sonarqube  
    spec: 
      containers: 
        - 
          env: 
            - 
              name: SONARQUBE_JDBC_USERNAME
              value: sonarqube
            - 
              name: SONARQUBE_JDBC_URL
              value: "jdbc:postgresql://postgresdb:5432/sonardb"
            - 
              name: SONARQUBE_JDBC_PASSWORD
              value: yourpassword
          image: "sonarqube:latest"
          name: sonarqube-pod
          ports: 
            - 
              containerPort: 9000
              protocol: TCP
          resources: 
            limits: 
              cpu: 2000m
              memory: 2048Mi
            requests: 
              cpu: 500m
              memory: 1024Mi
          volumeMounts: 
            - 
              mountPath: /opt/sonarqube/data/
              name: sonarqube-data
            - 
              mountPath: /opt/sonarqube/extensions/
              name: sonarqube-extensions
      volumes: 
        - 
          name: sonarqube-data
          persistentVolumeClaim: 
            claimName: sonarqube-datapv-claim
        - 
          name: sonarqube-extensions
          persistentVolumeClaim: 
            claimName: sonarqube-extensionspv-claim

 

Deploy the Yaml file.

# kubectl create -f sonarqube-deployment.yaml 
deployment.apps/sonarqube created
# # kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
postgres-statefulset-0       1/1     Running   0          50m
sonarqube-5ff76f99d8-nr7wh   1/1     Running   0          18m

 

6) Expose SonarQube Service publicly.

After SonarQube Deployment is up and running we need to create a public endpoint to access our service. you can download service here.

# kubectl apply -f sonarqube-service.yaml 
service/sonarqube-service created
## kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16h
postgresdb ClusterIP 10.97.21.29 <none> 5432/TCP 116m
sonarqube-service NodePort 10.109.198.175 <none> 9000:32000/TCP 49s

Now try to hit external IP address using http://<Your Public IP or DNS Name>:32000

Default user Permission are Login: admin. Password: admin

After login on SonarQube you can play with your own.

Now we have a SonarQube running on Kubernetes with PostgreSQL.

You can download the yaml file’s from git. Hope this post will help Devops beginners. Please share you feedback and Comments. Stay tune for more updates with ittroubleshooter.in …!!!

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of