一、jenkins安装插件 1.1下载SonarQube插件进入Jenkins的系统管理->插件管理->可选插件，搜索框输入sonarqube，安装重启。1.2启用SonarQubeJenkins的系统管理->系统配置，添加SonarQube服务。二、SonarQube配置 2.1禁用审查结果上传到SCM功能2.2生成token添加jenkin用户 token：squ_4bc173eb520dd35c176104baa1b899a992e88c88三、jenkins配置 3.1添加令牌Jenkins的系统管理->系统配置->添加token类型切换成Secret text，粘贴token，点击添加。选上刚刚添加的令牌凭证，点击应用保存。3.2SonarQube Scanner 安装进入Jenkins的系统管理->全局工具配置，下滑找到图片里的地方，点击新增SonarQube Scanner，我们选择自动安装并选择最新的版本。四、非流水线项目添加代码审查 4.1添加构建步骤编辑之前的自由风格构建的demo项目，在构建阶段新增步骤。analysis properties参数如下# 项目名称id，全局唯一 sonar.projectKey=sprint_boot_demo # 项目名称 sonar.projectName=sprint_boot_demo sonar.projectVersion=1.0 # 扫描路径，当前项目根目录 sonar.sources=./src # 排除目录 sonar.exclusions=**/test/**,**/target/** # jdk版本 sonar.java.source=1.17 sonar.java.target=1.17 # 字符编码 sonar.sourceEncoding=UTF-8 # binaries路径 sonar.java.binaries=target/classes4.2构建并查看结果jenkins点击立即构建，查看构建结果查看SonarQube扫描结果五、流水线项目添加代码审查 5.1创建sonar-project.properties文件项目根目录下，创建sonar-project.properties文件，内容如下# 项目名称id，全局唯一 sonar.projectKey=sprint_boot_demo # 项目名称 sonar.projectName=sprint_boot_demo sonar.projectVersion=1.0 # 扫描路径，当前项目根目录 sonar.sources=./src # 排除目录 sonar.exclusions=**/test/**,**/target/** # jdk版本 sonar.java.source=1.17 sonar.java.target=1.17 # 字符编码 sonar.sourceEncoding=UTF-8 # binaries路径 sonar.java.binaries=target/classes5.2修改Jenkinsfile加入SonarQube代码审查阶段pipeline { agent any stages { stage('拉取代码') { steps { echo '开始拉取代码' checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[url: 'https://gitee.com/axzys/sprint_boot_demo.git']]]) echo '拉取代码完成' } } stage('打包编译') { steps { echo '开始打包编译' sh 'mvn clean package' echo '打包编译完成' } } stage('代码审查') { steps { echo '开始代码审查' script { // 引入SonarQube scanner，名称与jenkins 全局工具SonarQube Scanner的name保持一致 def scannerHome = tool 'SonarQube' // 引入SonarQube Server，名称与jenkins 系统配置SonarQube servers的name保持一致 withSonarQubeEnv('SonarQube') { sh "${scannerHome}/bin/sonar-scanner" } } echo '代码审查完成' } } stage('部署项目') { steps { echo '开始部署项目' echo '部署项目完成' } } } } 5.3构建测试
一、部署1、下载下载地址：https://github.com/SonarSource/helm-chart-sonarqube/releases/download/sonarqube-2025.3.0-sonarqube-dce-2025.3.0/sonarqube-2025.3.0.tgz 解压：tar zxav sonarqube-2025.3.0.tgz 把模板输出： helm template my-sonarqube . > test.yaml 2、yaml文件--- # Source: sonarqube/charts/postgresql/templates/secrets.yaml apiVersion: v1 kind: Secret metadata: name: my-sonarqube-postgresql labels: app.kubernetes.io/name: postgresql helm.sh/chart: postgresql-10.15.0 app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm namespace: default type: Opaque data: postgresql-postgres-password: "Tlp4MmJXa3hKbA==" postgresql-password: "c29uYXJQYXNz" --- # Source: sonarqube/templates/secret.yaml --- apiVersion: v1 kind: Secret metadata: name: my-sonarqube-sonarqube-monitoring-passcode labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm type: Opaque data: SONAR_WEB_SYSTEMPASSCODE: "MzMwNzA1OTVBYmNA" --- # Source: sonarqube/templates/secret.yaml --- apiVersion: v1 kind: Secret metadata: name: my-sonarqube-sonarqube-http-proxies labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm type: Opaque stringData: PLUGINS-HTTP-PROXY: "" PLUGINS-HTTPS-PROXY: "" PLUGINS-NO-PROXY: "" PROMETHEUS-EXPORTER-HTTP-PROXY: "" PROMETHEUS-EXPORTER-HTTPS-PROXY: "" PROMETHEUS-EXPORTER-NO-PROXY: "" --- # Source: sonarqube/templates/config.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-config labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: sonar.properties: | --- # Source: sonarqube/templates/init-fs.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-init-fs labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: init_fs.sh: |- chown -R 1000:0 /opt/sonarqube/data chown -R 1000:0 /opt/sonarqube/temp chown -R 1000:0 /opt/sonarqube/logs --- # Source: sonarqube/templates/init-sysctl.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-init-sysctl labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: init_sysctl.sh: |- set -o errexit set -o xtrace vmMaxMapCount=524288 if [[ "$(sysctl -n vm.max_map_count)" -lt $vmMaxMapCount ]]; then sysctl -w vm.max_map_count=$vmMaxMapCount if [[ "$(sysctl -n vm.max_map_count)" -lt $vmMaxMapCount ]]; then echo "Failed to set initSysctl.vmMaxMapCount"; exit 1 fi fi fsFileMax=131072 if [[ "$(sysctl -n fs.file-max)" -lt $fsFileMax ]]; then sysctl -w fs.file-max=$fsFileMax if [[ "$(sysctl -n fs.file-max)" -lt $fsFileMax ]]; then echo "Failed to set initSysctl.fsFileMax"; exit 1 fi fi nofile=131072 if [[ "$(ulimit -n)" != "unlimited" ]]; then if [[ "$(ulimit -n)" -lt $nofile ]]; then ulimit -n $nofile if [[ "$(ulimit -n)" -lt $nofile ]]; then echo "Failed to set initSysctl.nofile"; exit 1 fi fi fi nproc=8192 if [[ "$(ulimit -u)" != "unlimited" ]]; then if [[ "$(ulimit -u)" -lt $nproc ]]; then ulimit -u $nproc if [[ "$(ulimit -u)" -lt $nproc ]]; then echo "Failed to set initSysctl.nproc"; exit 1 fi fi fi --- # Source: sonarqube/templates/install-plugins.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-install-plugins labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: install_plugins.sh: |- --- # Source: sonarqube/templates/jdbc-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-jdbc-config labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: SONAR_JDBC_USERNAME: "sonarUser" SONAR_JDBC_URL: "jdbc:postgresql://my-sonarqube-postgresql:5432/sonarDB" --- # Source: sonarqube/templates/prometheus-ce-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-prometheus-ce-config labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: prometheus-ce-config.yaml: |- rules: - pattern: .* --- # Source: sonarqube/templates/prometheus-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-sonarqube-sonarqube-prometheus-config labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm data: prometheus-config.yaml: |- rules: - pattern: .* --- # Source: sonarqube/templates/pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: my-sonarqube-sonarqube labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm spec: accessModes: - "ReadWriteOnce" resources: requests: storage: "5Gi" storageClassName: "ceph-cephfs" --- # Source: sonarqube/charts/postgresql/templates/svc-headless.yaml apiVersion: v1 kind: Service metadata: name: my-sonarqube-postgresql-headless labels: app.kubernetes.io/name: postgresql helm.sh/chart: postgresql-10.15.0 app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm # Use this annotation in addition to the actual publishNotReadyAddresses # field below because the annotation will stop being respected soon but the # field is broken in some versions of Kubernetes: # https://github.com/kubernetes/kubernetes/issues/58662 service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" namespace: default spec: type: ClusterIP clusterIP: None # We want all pods in the StatefulSet to have their addresses published for # the sake of the other Postgresql pods even before they're ready, since they # have to be able to talk to each other in order to become ready. publishNotReadyAddresses: true ports: - name: tcp-postgresql port: 5432 targetPort: tcp-postgresql selector: app.kubernetes.io/name: postgresql app.kubernetes.io/instance: my-sonarqube --- # Source: sonarqube/charts/postgresql/templates/svc.yaml apiVersion: v1 kind: Service metadata: name: my-sonarqube-postgresql labels: app.kubernetes.io/name: postgresql helm.sh/chart: postgresql-10.15.0 app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm annotations: namespace: default spec: type: ClusterIP ports: - name: tcp-postgresql port: 5432 targetPort: tcp-postgresql selector: app.kubernetes.io/name: postgresql app.kubernetes.io/instance: my-sonarqube role: primary --- # Source: sonarqube/templates/service.yaml apiVersion: v1 kind: Service metadata: name: my-sonarqube-sonarqube labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm spec: type: ClusterIP ports: - port: 9000 targetPort: http protocol: TCP name: http selector: app: sonarqube release: my-sonarqube --- # Source: sonarqube/charts/postgresql/templates/statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: my-sonarqube-postgresql labels: app.kubernetes.io/name: postgresql helm.sh/chart: postgresql-10.15.0 app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm app.kubernetes.io/component: primary annotations: namespace: default spec: serviceName: my-sonarqube-postgresql-headless replicas: 1 updateStrategy: type: RollingUpdate selector: matchLabels: app.kubernetes.io/name: postgresql app.kubernetes.io/instance: my-sonarqube role: primary template: metadata: name: my-sonarqube-postgresql labels: app.kubernetes.io/name: postgresql helm.sh/chart: postgresql-10.15.0 app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm role: primary app.kubernetes.io/component: primary spec: affinity: podAffinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchLabels: app.kubernetes.io/name: postgresql app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/component: primary namespaces: - "default" topologyKey: kubernetes.io/hostname weight: 1 nodeAffinity: securityContext: fsGroup: 1001 automountServiceAccountToken: false containers: - name: my-sonarqube-postgresql image: registry.cn-guangzhou.aliyuncs.com/xingcangku/bitnami-postgresql:11.14.0-debian-10-r22 imagePullPolicy: "IfNotPresent" resources: limits: cpu: 2 memory: 2Gi requests: cpu: 100m memory: 200Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL runAsNonRoot: true runAsUser: 1001 seccompProfile: type: RuntimeDefault env: - name: BITNAMI_DEBUG value: "false" - name: POSTGRESQL_PORT_NUMBER value: "5432" - name: POSTGRESQL_VOLUME_DIR value: "/bitnami/postgresql" - name: PGDATA value: "/bitnami/postgresql/data" - name: POSTGRES_POSTGRES_PASSWORD valueFrom: secretKeyRef: name: my-sonarqube-postgresql key: postgresql-postgres-password - name: POSTGRES_USER value: "sonarUser" - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: my-sonarqube-postgresql key: postgresql-password - name: POSTGRES_DB value: "sonarDB" - name: POSTGRESQL_ENABLE_LDAP value: "no" - name: POSTGRESQL_ENABLE_TLS value: "no" - name: POSTGRESQL_LOG_HOSTNAME value: "false" - name: POSTGRESQL_LOG_CONNECTIONS value: "false" - name: POSTGRESQL_LOG_DISCONNECTIONS value: "false" - name: POSTGRESQL_PGAUDIT_LOG_CATALOG value: "off" - name: POSTGRESQL_CLIENT_MIN_MESSAGES value: "error" - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES value: "pgaudit" ports: - name: tcp-postgresql containerPort: 5432 livenessProbe: exec: command: - /bin/sh - -c - exec pg_isready -U "sonarUser" -d "dbname=sonarDB" -h 127.0.0.1 -p 5432 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 6 readinessProbe: exec: command: - /bin/sh - -c - -e - | exec pg_isready -U "sonarUser" -d "dbname=sonarDB" -h 127.0.0.1 -p 5432 [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 6 volumeMounts: - name: dshm mountPath: /dev/shm - name: data mountPath: /bitnami/postgresql subPath: volumes: - name: dshm emptyDir: medium: Memory volumeClaimTemplates: - metadata: name: data spec: accessModes: - "ReadWriteOnce" resources: requests: storage: "2Gi" storageClassName: ceph-cephfs --- # Source: sonarqube/templates/sonarqube-sts.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: my-sonarqube-sonarqube labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm app.kubernetes.io/name: my-sonarqube app.kubernetes.io/instance: my-sonarqube app.kubernetes.io/managed-by: Helm app.kubernetes.io/part-of: sonarqube app.kubernetes.io/component: my-sonarqube-sonarqube app.kubernetes.io/version: "25.5.0.107428-community" spec: replicas: 1 revisionHistoryLimit: 10 serviceName: my-sonarqube-sonarqube selector: matchLabels: app: sonarqube release: my-sonarqube template: metadata: annotations: checksum/config: 514ba5726581aabed2df14f0c3d95431e4f1150f3ee3c9790dae426c0b0effd3 checksum/init-fs: 2da6aac9b4e90ad2a2853245bcc71bf2b9a53bdf6db658a594551108671976e7 checksum/init-sysctl: a03f942e6089eda338af09ad886a4380f621c295548e9917a0e6113248ebb1aa checksum/plugins: 6b6fe750b5fb43bd030dbbe4e3ece53e5f37f595a480d504dd7e960bd5b9832a checksum/secret: 38377e36e39acacccf767e5fc68414a302d1868b7b9a99cb72e38f229023ca39 checksum/prometheus-config: c831c80bb8be92b75164340491b49ab104f5b865f53618ebcffe35fd03c4c034 checksum/prometheus-ce-config: a481713e44ccc5524e48597df39ba6f9a561fecd8b48fce7f6062602d8229613 labels: app: sonarqube release: my-sonarqube spec: automountServiceAccountToken: false securityContext: fsGroup: 0 initContainers: - name: "wait-for-db" image: registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL readOnlyRootFilesystem: true runAsGroup: 0 runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault command: ["/bin/bash", "-c"] args: ['set -o pipefail;for i in {1..200};do (echo > /dev/tcp/my-sonarqube-postgresql/5432) && exit 0; sleep 2;done; exit 1'] - name: init-sysctl image: registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community imagePullPolicy: IfNotPresent securityContext: privileged: true readOnlyRootFilesystem: true runAsUser: 0 command: ["/bin/bash", "-e", "/tmp/scripts/init_sysctl.sh"] volumeMounts: - name: init-sysctl mountPath: /tmp/scripts/ env: - name: SONAR_WEB_CONTEXT value: / - name: SONAR_WEB_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml - name: SONAR_CE_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml - name: inject-prometheus-exporter image: registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL readOnlyRootFilesystem: true runAsGroup: 0 runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault command: ["/bin/sh", "-c"] args: ["curl -s 'https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar' --output /data/jmx_prometheus_javaagent.jar -v"] volumeMounts: - mountPath: /data name: sonarqube subPath: data env: - name: http_proxy valueFrom: secretKeyRef: name: my-sonarqube-sonarqube-http-proxies key: PROMETHEUS-EXPORTER-HTTP-PROXY - name: https_proxy valueFrom: secretKeyRef: name: my-sonarqube-sonarqube-http-proxies key: PROMETHEUS-EXPORTER-HTTPS-PROXY - name: no_proxy valueFrom: secretKeyRef: name: my-sonarqube-sonarqube-http-proxies key: PROMETHEUS-EXPORTER-NO-PROXY - name: SONAR_WEB_CONTEXT value: / - name: SONAR_WEB_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml - name: SONAR_CE_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml - name: init-fs image: registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community imagePullPolicy: IfNotPresent securityContext: capabilities: add: - CHOWN drop: - ALL privileged: false readOnlyRootFilesystem: true runAsGroup: 0 runAsNonRoot: false runAsUser: 0 seccompProfile: type: RuntimeDefault command: ["sh", "-e", "/tmp/scripts/init_fs.sh"] volumeMounts: - name: init-fs mountPath: /tmp/scripts/ - mountPath: /opt/sonarqube/data name: sonarqube subPath: data - mountPath: /opt/sonarqube/temp name: sonarqube subPath: temp - mountPath: /opt/sonarqube/logs name: sonarqube subPath: logs - mountPath: /tmp name: tmp-dir - mountPath: /opt/sonarqube/extensions name: sonarqube subPath: extensions containers: - name: sonarqube image: registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community imagePullPolicy: IfNotPresent ports: - name: http containerPort: 9000 protocol: TCP - name: monitoring-web containerPort: 8000 protocol: TCP - name: monitoring-ce containerPort: 8001 protocol: TCP resources: limits: cpu: 800m ephemeral-storage: 512000M memory: 6144M requests: cpu: 400m ephemeral-storage: 1536M memory: 2048M env: - name: SONAR_HELM_CHART_VERSION value: 2025.3.0 - name: SONAR_JDBC_PASSWORD valueFrom: secretKeyRef: name: my-sonarqube-postgresql key: postgresql-password - name: SONAR_WEB_SYSTEMPASSCODE valueFrom: secretKeyRef: name: my-sonarqube-sonarqube-monitoring-passcode key: SONAR_WEB_SYSTEMPASSCODE - name: SONAR_WEB_CONTEXT value: / - name: SONAR_WEB_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml - name: SONAR_CE_JAVAOPTS value: -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml envFrom: - configMapRef: name: my-sonarqube-sonarqube-jdbc-config livenessProbe: exec: command: - sh - -c - | wget --no-proxy --quiet -O /dev/null --timeout=1 --header="X-Sonar-Passcode: $SONAR_WEB_SYSTEMPASSCODE" "http://localhost:9000/api/system/liveness" failureThreshold: 6 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 1 readinessProbe: exec: command: - sh - -c - | #!/bin/bash # A Sonarqube container is considered ready if the status is UP, DB_MIGRATION_NEEDED or DB_MIGRATION_RUNNING # status about migration are added to prevent the node to be kill while SonarQube is upgrading the database. if wget --no-proxy -qO- http://localhost:9000/api/system/status | grep -q -e '"status":"UP"' -e '"status":"DB_MIGRATION_NEEDED"' -e '"status":"DB_MIGRATION_RUNNING"'; then exit 0 fi exit 1 failureThreshold: 6 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 1 startupProbe: httpGet: scheme: HTTP path: /api/system/status port: http initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 24 timeoutSeconds: 1 securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL runAsGroup: 0 runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault volumeMounts: - mountPath: /opt/sonarqube/data name: sonarqube subPath: data - mountPath: /opt/sonarqube/temp name: sonarqube subPath: temp - mountPath: /opt/sonarqube/logs name: sonarqube subPath: logs - mountPath: /tmp name: tmp-dir - mountPath: /opt/sonarqube/extensions name: sonarqube subPath: extensions - mountPath: /opt/sonarqube/conf/prometheus-config.yaml subPath: prometheus-config.yaml name: prometheus-config - mountPath: /opt/sonarqube/conf/prometheus-ce-config.yaml subPath: prometheus-ce-config.yaml name: prometheus-ce-config serviceAccountName: default volumes: - name: init-sysctl configMap: name: my-sonarqube-sonarqube-init-sysctl items: - key: init_sysctl.sh path: init_sysctl.sh - name: init-fs configMap: name: my-sonarqube-sonarqube-init-fs items: - key: init_fs.sh path: init_fs.sh - name: prometheus-config configMap: name: my-sonarqube-sonarqube-prometheus-config items: - key: prometheus-config.yaml path: prometheus-config.yaml - name: prometheus-ce-config configMap: name: my-sonarqube-sonarqube-prometheus-ce-config items: - key: prometheus-ce-config.yaml path: prometheus-ce-config.yaml - name: sonarqube persistentVolumeClaim: claimName: my-sonarqube-sonarqube - name : tmp-dir emptyDir: {} --- # Source: sonarqube/templates/tests/sonarqube-test.yaml apiVersion: v1 kind: Pod metadata: name: "my-sonarqube-ui-test" annotations: "helm.sh/hook": test-success labels: app: sonarqube chart: sonarqube-2025.3.0 release: my-sonarqube heritage: Helm spec: automountServiceAccountToken: false containers: - name: my-sonarqube-ui-test image: "registry.cn-guangzhou.aliyuncs.com/xingcangku/sonarqube-community:25.5.0.107428-community" imagePullPolicy: IfNotPresent command: ['wget'] args: [ '--retry-connrefused', '--waitretry=1', '--timeout=5', '-t', '12', '-qO-', 'my-sonarqube-sonarqube:9000/api/system/status' ] resources: limits: cpu: 500m ephemeral-storage: 1000M memory: 200M requests: cpu: 500m ephemeral-storage: 100M memory: 200M restartPolicy: Never 3、安装kubectl apply -f test.yaml4、svcapiVersion: v1 kind: Service metadata: name: sonarqube-nodeport spec: type: NodePort ports: - port: 9000 targetPort: 9000 nodePort: 32309 selector: app: sonarqube release: my-sonarqube5、启动的时候慢是正常的。http://192.168.3.200:32309/6、修改hosts文件notepad C:\Windows\System32\drivers\etc\hosts 6、给其他业务pod添加root@k8s01:~/helm/sonarqube# kubectl get svc -n traefik | grep traefik traefik-crds LoadBalancer 10.101.202.240 <pending> 80:31080/TCP,443:32480/TCP 87mroot@k8s01:~/helm/sonarqube# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d my-sonarqube-postgresql ClusterIP 10.102.103.88 <none> 5432/TCP 23h my-sonarqube-postgresql-headless ClusterIP None <none> 5432/TCP 23h my-sonarqube-sonarqube ClusterIP 10.107.136.0 <none> 9000/TCP 23h sonarqube-nodeport NodePort 10.106.168.209 <none> 9000:32309/TCP 22h test-app ClusterIP 10.101.249.224 <none> 80/TCP 6d23h apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: sonarqube-ingress namespace: default # 确保与 SonarQube 服务同命名空间 spec: entryPoints: - web # HTTP 入口（如需 HTTPS 使用 websecure） routes: - match: Host(`sonarqube.local.com`) kind: Rule services: - name: my-sonarqube-sonarqube # 使用 ClusterIP 服务 port: 9000这样可以实验出流量的两个走发 1、直接走业务pod本身的端口 2、先走traefik然后由它来分发给业务pod