本文中PostgreSQL使用 Ceph RBD  作为持久卷,SonarQube使用 NFS 作为持久卷。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ echo  -n sonar | base64 c29uYXI= $ echo  -n Passw0rd | base64 UGFzc3cwcmQ= $ echo  -n sonardb | base64 c29uYXJkYg== $ tr --delete '\n'  < mysql-root-pwd.txt > .strippedmysql-root-pwd.txt && mv .strippedmysql-root-pwd.txt mysql-root-pwd.txt OR $ kubectl create secret generic mysql-secrets --from-literal=root-user=root --from-literal=root-password=Passw0rd --from-literal=mysql-database=sonardb --from-literal=mysql-user=sonar --from-literal=mysql-password=sonar -n sonar OR $ kubectl create secret generic mysql-root-pwd --from-file=mysql-root-pwd.txt -n sonar 
1 2 3 4 5 6 7 8 9 10 11 12 $ cat pg-secrets.yaml apiVersion: v1 kind: Secret metadata:   name: postgres-secrets   namespace: sonar   labels:     app: postgres data:   postgres-db: c29uYXJkYg==   postgres-user: c29uYXI=   postgres-password: c29uYXI= 
1 $ kubectl create -f pg-secrets.yaml 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ kubectl get secrets -n sonar NAME                  TYPE                                  DATA      AGE ceph-secret           kubernetes.io/rbd                     1         8d default-token-fzbwt   kubernetes.io/service-account-token   3         16d postgres-secrets      Opaque                                3         3d $ kubectl describe secrets/postgres-secrets  -n sonar Name:         postgres-secrets Namespace:    sonar Labels:       app=postgres Annotations:  <none> Type:  Opaque Data ==== postgres-db:        7 bytes postgres-password:  5 bytes postgres-user:      5 bytes 
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 $ cat pg-statefulset.yaml  apiVersion: v1 kind: Service metadata:   name: postgres   namespace: sonar   labels:     app: postgres spec:   ports:     - port: 5432   clusterIP: None   selector:     app: postgres --- apiVersion: apps/v1beta1 kind: StatefulSet metadata:   name: postgres   namespace: sonar   labels:     app: postgres spec:   serviceName: postgres   replicas: 1   template:     metadata:       labels:         app: postgres     spec:       terminationGracePeriodSeconds: 10       containers:       - name: postgresql         image: 10.0.77.16/library/postgres:10.3         imagePullPolicy: IfNotPresent         ports:         - containerPort: 5432           name: postgresql         env:         - name: POSTGRES_USER           valueFrom:             secretKeyRef:               name: postgres-secrets               key: postgres-user         - name: POSTGRES_DB           valueFrom:             secretKeyRef:               name: postgres-secrets               key: postgres-db         - name: POSTGRES_PASSWORD           valueFrom:             secretKeyRef:               name: postgres-secrets               key: postgres-password         - name: PGDATA           value: /var/lib/postgresql/data/pgdata         volumeMounts:         - name: postgres-volume           mountPath: /var/lib/postgresql/data       imagePullSecrets:          - name: registrykey   volumeClaimTemplates:   - metadata:       name: postgres-volume     spec:       accessModes:         - ReadWriteOnce       storageClassName: ceph-postgres       resources:         requests:           storage: 10Gi 
1 $ kubectl create -f pg-statefulset.yaml 
volumeClaimTemplates中定义了PVC,并指定了storageClassName: "ceph-postgres",会根据PVC动态创建Pod所需的PV。
 
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 $ kubectl get pvc -n sonar NAME                         STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE postgres-volume-postgres-0   Bound     pvc-df69da97-2e7a-11e8-b7b9-0050568879ea   10Gi       RWO            ceph-postgres   5m $ kubectl get pv -n sonar NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                              STORAGECLASS    REASON    AGE pvc-df69da97-2e7a-11e8-b7b9-0050568879ea   10Gi       RWO            Delete           Bound     sonar/postgres-volume-postgres-0   ceph-postgres             7m $ kubectl describe persistentvolume  pvc-df69da97-2e7a-11e8-b7b9-0050568879ea Name:            pvc-df69da97-2e7a-11e8-b7b9-0050568879ea Labels:          <none> Annotations:     kubernetes.io/createdby=rbd-dynamic-provisioner                  pv.kubernetes.io/bound-by-controller=yes                  pv.kubernetes.io/provisioned-by=kubernetes.io/rbd StorageClass:    ceph-postgres Status:          Bound Claim:           sonar/postgres-volume-postgres-0 Reclaim Policy:  Delete Access Modes:    RWO Capacity:        10Gi Message:          Source:     Type:          RBD (a Rados Block Device mount on the host that shares a pod's lifetime)      CephMonitors:  [10.0.77.17:6789]     RBDImage:      kubernetes-dynamic-pvc-df734e53-2e7a-11e8-93af-00505688047e     FSType:        xfs     RBDPool:       rbd     RadosUser:     admin     Keyring:       /etc/ceph/keyring     SecretRef:     &{ceph-secret }     ReadOnly:      false Events:            <none> 
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 $ cat sonar-rc.yaml apiVersion: v1 kind: Service metadata:   name: sonar   namespace: sonar spec:   type: NodePort   ports:   - port: 9000     protocol: TCP     nodePort: 30001   selector:     name: sonar --- apiVersion: v1 kind: ReplicationController metadata:   name: sonar   namespace: sonar   labels:     name: sonar spec:   replicas: 1   selector:     name: sonar   template:     metadata:       labels:         name: sonar     spec:       containers:       - name: sonar         image: 10.0.77.16/library/sonarqube:6.7         env:         - name: SONARQUBE_JDBC_USERNAME           valueFrom:             secretKeyRef:               name: postgres-secrets               key: postgres-user         - name: SONARQUBE_JDBC_PASSWORD           valueFrom:             secretKeyRef:               name: postgres-secrets               key: postgres-password         - name: SONARQUBE_JDBC_URL           value: jdbc:postgresql://postgres:5432/sonardb         ports:         - containerPort: 9000         volumeMounts:         - mountPath: "/opt/sonarqube/conf"           name: sonar-conf         - mountPath: "/opt/sonarqube/data"           name: sonar-data         - mountPath: "/opt/sonarqube/extensions"           name: sonar-extensions         - mountPath: "/opt/sonarqube/logs"           name: sonar-logs       volumes:         - name: sonar-conf           nfs:             server: 10.0.77.16             path: "/nfs/sonar/conf"         - name: sonar-data           nfs:             server: 10.0.77.16             path: "/nfs/sonar/data"         - name: sonar-extensions           nfs:             server: 10.0.77.16             path: "/nfs/sonar/extensions"         - name: sonar-logs           nfs:             server: 10.0.77.16             path: "/nfs/sonar/logs" 
1 $ kubectl create -f sonar-rc.yaml 
使用默认用户、密码 admin/admin 访问SonarQube http://k8s-node-ip:30001 
Plugin Library 
SonarQube v6.7预装好的Plugins如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ kubectl get pods -n sonar NAME          READY     STATUS    RESTARTS   AGE postgres-0    1/1       Running   0          15h sonar-wmvnf   1/1       Running   0          15h $ kubectl exec  -n sonar sonar-wmvnf -it -- bash root@sonar-wmvnf:/opt/sonarqube/extensions/plugins total 40464 -rw-r--r-- 1 sonarqube sonarqube 2703958 Nov  6 08:12 sonar-csharp-plugin-6.5.0.3766.jar -rw-r--r-- 1 sonarqube sonarqube 1618672 Nov  6 08:12 sonar-flex-plugin-2.3.jar -rw-r--r-- 1 sonarqube sonarqube 6759535 Nov  6 15:31 sonar-java-plugin-4.15.0.12310.jar -rw-r--r-- 1 sonarqube sonarqube 3355702 Nov  6 08:12 sonar-javascript-plugin-3.2.0.5506.jar -rw-r--r-- 1 sonarqube sonarqube 3022870 Nov  6 16:50 sonar-php-plugin-2.11.0.2485.jar -rw-r--r-- 1 sonarqube sonarqube 4024311 Nov  6 08:12 sonar-python-plugin-1.8.0.1496.jar -rw-r--r-- 1 sonarqube sonarqube 3625962 Nov  6 08:12 sonar-scm-git-plugin-1.3.0.869.jar -rw-r--r-- 1 sonarqube sonarqube 6680471 Nov  6 08:12 sonar-scm-svn-plugin-1.6.0.860.jar -rw-r--r-- 1 sonarqube sonarqube 2250667 Nov  6 08:12 sonar-typescript-plugin-1.1.0.1079.jar -rw-r--r-- 1 sonarqube sonarqube 7368250 Nov  6 08:12 sonar-xml-plugin-1.4.3.1027.jar 
Analyzing with SonarQube Scanner 
1 2 3 4 5 root@sonar-wmvnf:~ root@sonar-wmvnf:/opt/sonarqube/extensions/downloads root@sonar-wmvnf:/opt/sonarqube/extensions/downloads root@sonar-wmvnf:/opt/sonarqube root@sonar-wmvnf:/opt/sonarqube 
增加 SonarQube Scanner 的环境变量
1 2 3 4 5 6 7 $ kubectl cp sonar/sonar-wmvnf:/etc/profile ./ tar: Removing leading `/' from member names  $ vi profile ...... /opt/sonarqube/sonar-scanner/bin ...... 
1 2 3 4 5 6 7 8 9 10 11 12 $ kubectl cp ./profile sonar/sonar-wmvnf:/etc/ root@sonar-wmvnf:/opt/sonarqube root@sonar-wmvnf:/opt/sonarqube INFO:  INFO: usage: sonar-scanner [options] INFO:  INFO: Options: INFO:  -D,--define <arg>     Define property INFO:  -h,--help              Display help  information INFO:  -v,--version          Display version information INFO:  -X,--debug            Produce execution debug output 
配置 SonarQube Scanner 属性
1 2 3 4 $ cat sonar-scanner.properties sonar.host.url=http://localhost:9000 sonar.sourceEncoding=UTF-8 
1 $ kubectl cp ./sonar-scanner.properties sonar/sonar-wmvnf:/opt/sonarqube/sonar-scanner/conf/sonar-scanner.properties 
配置 Python 代码分析
1 2 3 4 5 6 7 8 9 10 11 $ cat sonar-project.properties sonar.projectKey=my:python sonar.projectName=python sonar.projectVersion=1.0 sonar.sources=. sonar.sourceEncoding=UTF-8 sonar.language=py 
1 2 3 4 5 root@sonar-wmvnf:/opt/sonarqube/conf $ kubectl cp ./sonar-project.properties sonar/sonar-wmvnf:/opt/sonarqube/conf/python/sonar-project.properties root@sonar-wmvnf:/opt/sonarqube/conf 
执行分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 root@sonar-wmvnf:/opt/sonarqube/conf/python INFO: Scanner configuration file: /opt/sonarqube/sonar-scanner/conf/sonar-scanner.properties INFO: Project root configuration file: /opt/sonarqube/conf/python/sonar-project.properties INFO: SonarQube Scanner 3.1.0.1141 ...... ...... INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard/index/my:python INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report INFO: More about the report processing at http://localhost:9000/api/ce/task?id=AWJW_N6U1qxTjZHyQmBu INFO: Task total time: 4.424 s INFO: ------------------------------------------------------------------------ INFO: EXECUTION SUCCESS INFO: ------------------------------------------------------------------------ INFO: Total time: 6.144s INFO: Final Memory: 11M/335M INFO: ------------------------------------------------------------------------ 
[Analyzing with SonarQube Scanner for Jenkins](Analyzing with SonarQube Scanner for Jenkins) 
 
Reference