Thursday, November 21, 2024
HomeCloudAzureHow to Deploy SonarQube on Azure Kubernetes service

How to Deploy SonarQube on Azure Kubernetes service

SonarQube is a web-based open source platform used to measure and analyze the source code quality. Code quality analysis makes your code more reliable and more readable.

SonarQube is written in Java but it can analyze and manage code of more than 20 programming languages, including c/c++, PL/SQL, Cobol etc through plugins. Plugins extend the functionality of SonarQube. More than 50 plugins are available.

SonarQube is maintained by SonarSource.

Find about more benefits on https://foxutech.com/benefits-of-sonarqube/

In this post we are going to see how to deploy the SonarQube on Azure Kubernetes Service (AKS), as we have seen in last post How to setup AKS via terraform, I may recommend to use that and setup your environment in Azure.

Prerequisites

  • Azure Kubernetes Service up and running
  • Kubectl installed in the VM or machine you are going to manage the AKS.
  • Postgresql server available, if not please find the optional step below. If you are creating new server, please make sure you have terraform installed in the VM.

Provision Azure PostgreSQL Server (Optional)

You can check our repository https://github.com/foxutech/kubernetes.git.

# git clone https://github.com/foxutech/kubernetes.git 
# cd kubernetes/sonarqube/database

Change the required values in the variables.tf or main.tf file. Once all done, please run following terraform commands,

# terraform init 
# terraform plan 
# terraform apply

This should help you to create the azure PostgreSQL server, please use the details in the deployment manifest.

Create PersistentVolumeClaims to store SonarQube data

AKS comes with built-in Storage Classes for HDD (default) and SSD (premium) storage: Please refer more details on azure portal and check the storage classes using

# kubectl get sc

As we need to create 2 PVCs as SonarQube uses two locations to store data /opt/sonarqube/data/ and /opt/sonarqube/extensions/. Once you check out the directory, you need to change the directory to kubernetes/sonarqube/application and run the commands or copy the file below and create a files.

PVC for Sonar’s data directory

# cat sonar-data.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonar-data
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: default
  resources:
    requests:
      storage: 30Gi

PVC for Sonar’s extensions directory

# cat sonar-extensions.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonar-extensions
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: default
  resources:
    requests:
      storage: 30Gi

Create the PVC now using following commands,

# kubectl apply -f sonar-data.yaml
# kubectl apply -f sonar-extensions.yaml

Create a Secret to store PostgreSQL password

Kubernetes has a built-in capability to store secrets. To create a secret, you need to base64 encode a secret value

# echo -n 'myson@rTempP@$$' | base64
bXlzb25AclRlbXBQQCQk

and create a k8s secret using YAML file as below,

# cat sonar-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: postgres
type: Opaque
data:
  #my password is myson@rTempP@$$, change it before using
  password: bXlzb25AclRlbXBQQCQk

Create a deployment

After creating PVCs and Postgres secret we are ready to deploy using the following YAML file

Please note, here what we did,

  • We have set container limits so that it cannot put cluster node into Out-of-memory state and also used init-containers to set the permissions and elasticsearch vm.max_map_count. (This is mandatory, otherwise you may end with elasticsearch error)
  • We use environment variables to pass database connection info to container
# cat sonar-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sonarqube
  labels:
    app: sonarqube
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sonarqube
  template:
    metadata:
      labels:
        app: sonarqube
    spec:
      terminationGracePeriodSeconds: 15
      initContainers:
        - name: fix-the-volume-permission-extension
          image: busybox
          command:
          - sh
          - -c
          - chown -R 1000:1000 /opt/sonarqube/extensions
          securityContext:
            privileged: true
          volumeMounts:
          - name: sonar-extensions
            mountPath: /opt/sonarqube/extensions
        - name: fix-the-volume-permission-data
          image: busybox
          command:
          - sh
          - -c
          - chown -R 1000:1000 /opt/sonarqube/data
          securityContext:
            privileged: true
          volumeMounts:
          - name: sonar-data
            mountPath: /opt/sonarqube/data
      containers:
        - name: sonarqube
          image: sonarqube
          resources:
            requests:
              cpu: 500m
              memory: 1024Mi
            limits:
              cpu: 2000m
              memory: 2048Mi
          ports:
          - name: sonarqube
            containerPort: 9000
          env:
          - name: SONARQUBE_JDBC_USERNAME
            value: "foxutech@devops-tools"
          - name: SONARQUBE_JDBC_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres
                key: password
          - name: SONARQUBE_JDBC_URL
            value: "jdbc:postgresql://devops-tools.postgres.database.azure.com/sonarqube"
          volumeMounts:
            - mountPath: /opt/sonarqube/data/
              name: sonar-data
            - mountPath: /opt/sonarqube/extensions/
              name: sonar-extensions
      initContainers:
        - name: sonarqube-es-init
          image: busybox:1.27.2
          command: ['sysctl', '-w', 'vm.max_map_count=262144']
          securityContext:
            privileged: true
      volumes:
      - name: sonar-data
        persistentVolumeClaim:
          claimName: sonar-data
      - name: sonar-extensions
        persistentVolumeClaim:
          claimName: sonar-extensions
# kubectl apply -f sonar-deployment.yaml
deployment.extensions/sonarqube created
# kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
sonarqube-5c5976bdf5-2dcxv   1/1       Running   0          55m

Once the pod up and running, check the pod logs to check the service is up and running.

# kubectl logs -f sonarqube-5c5976bdf5-2dcxv   
2022.04.29 15:46:54 INFO  ce[][o.s.c.c.CePluginRepository] Load plugins
2022.04.29 15:46:55 INFO  ce[][o.s.c.c.ComputeEngineContainerImpl] Running Community edition
2022.04.29 15:46:56 INFO  ce[][o.s.ce.app.CeServer] Compute Engine is started
2022.04.29 15:46:56 INFO  app[][o.s.a.SchedulerImpl] Process[ce] is up
2022.04.29 15:46:56 INFO  app[][o.s.a.SchedulerImpl] SonarQube is operational

Create the Kubernetes Service

Once you see the service is up, now lets create the Kubernetes service to expose the application to external.

# cat sonar-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: sonarqube
  name: sonarqube
spec:
  ports:
    - name: sonar
      port: 80
      protocol: TCP
      targetPort: 9000
  selector:
    app: sonarqube
  type: LoadBalancer
# kubectl apply -f sonar-svc.yaml
service/sonarqube created
# kubectl get svc
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
sonarqube    LoadBalancer   10.0.255.65   20.85.188.179   80:32195/TCP   51m

Now we can hit EXTERNAL-IP address and login to SonarQube, you can find the external IP via command or you can go to services and ingresses in azure portal your AKS service and check the external IP in services tab.

That’s it! Now we have a SonarQube running on azure Kubernetes service. And if one of the nodes fails, pod will be automatically redeployed to a healthy node. For now we have seen Deploy SonarQube on Azure Kubernetes service. in upcoming post will see more example with some different scenarios.

RELATED ARTICLES
- Advertisment -

Most Popular

Recent Comments