파란하늘의 지식창고
article thumbnail
반응형

공부 목적으로 설치해 보는 과정을 정리한 것이기 때문에 실제 운영과 다릅니다.


sonarqube 소개

sonarqube는 30개 이상의 프로그래밍 언어에서 버그, 코드 스멜, 보안 취약점을 발견할 목적으로 정적 코드 분석을 자동 리뷰 수행하기 위한 지속적인 코드 품질 검사용 오픈소스 플랫폼이다.

https://www.sonarsource.com/products/sonarqube/

개발할 때 findbug, checkstyle, pmd를 사용하여 코드상 문제를 파악하고 수정할 수 있다.
sonarqube는 이런 분석 내용을 저장하고 해결된 내역을 기록하여 코드 품질을 관리할 수 있도록 도와준다.

sonarqube는 java 뿐만 아니라 C#, C, C++, Go, Kotlin, PHP, Python, Ruby, Scala, Swift, TypeScript 등 30여 개의 다양한 언어를 사용한 개발 코드의 품질을 관리할 수 있다.

IDE에서 직접 사용할 수 있는 sonarlint도 좋다.
sonarqube에서 확인할 수 있는 문제점들을 내 로컬 IDE에서 유사하게 빠르게 확인하고 수정할 수 있어 편리하다.
IntelliJ는 기본 추가되어 있고 eclipse의 경우 marketplace에서 검색해서 추가하면 된다.

https://www.sonarlint.org/

다만 sonarqube로 한 곳에서 체계적으로 여러 프로젝트의 코드 품질 관리 내역을 관리하고 이력을 보관하는 것은 sonarlint보다 sonarqube가 더 효율적이다.
sonarqube와 sonarlint를 병행하여 사용하면 좋지 않을까 싶다.

kubernetes에 sonarqube 설치하기

오래간만에 sonarqube를 kubernetes에 설치해보려고 하니 기존 설정을 kubernetes yaml로 변경한 설정으로는 설치가 되지 않았다.
(2019년도 7월 31일에 7.9.0 버전을 docker에 설치하여 사용한 적이 있다. )

2019.07.31 - [Study/CI&CD] - SonarQube 사용하기

sonarqube는 mssql, oracle, postgreSQL database 중 하나를 선택하여 저장해야 한다.
mssql을 저장소로 사용하였는데 sonarqube pod를 생성하기 전에 설정한 sonarqube catalog를 먼저 생성해두어야 한다.
현재 버전(9.9.0) 기준으로 kubernetes yaml 파일은 다음과 같다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sonarqube-deployment
  labels:
    app: sonarqube
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sonarqube
  template:
    metadata:
      labels:
        app: sonarqube
    spec:
      initContainers:
      - name: volume-mount-hack
        image: busybox
        command: ["sh", "-c", "chmod -R 777 /opt/sonarqube"]
        volumeMounts:
        - name: sonarqube-data
          mountPath: /opt/sonarqube/data
        - name: sonarqube-logs
          mountPath: /opt/sonarqube/logs
        - name: sonarqube-extensions
          mountPath: /opt/sonarqube/extensions
      - name: sysctl
        image: busybox
        securityContext:
          privileged: true
          runAsUser: 0
        command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
      containers:
      - name: sonarqube
        image: sonarqube
        ports:
        - containerPort: 9000
        env:
        - name: SONAR_JDBC_URL
          value: "jdbc:sqlserver://mssql-service;databaseName=sonarqube;encrypt=false"
        - name: SONAR_JDBC_USERNAME
          value: "sa"
        - name: SONAR_JDBC_PASSWORD
          valueFrom:
            secretKeyRef:
              key: mssql-sa-password
              name: mssql-secret
        volumeMounts:
        - name: sonarqube-data
          mountPath: /opt/sonarqube/data
        - name: sonarqube-logs
          mountPath: /opt/sonarqube/logs
        - name: sonarqube-extensions
          mountPath: /opt/sonarqube/extensions
      volumes:
      - name: sonarqube-data
        persistentVolumeClaim: 
          claimName: sonarqube-data-pvc
      - name: sonarqube-logs
        persistentVolumeClaim: 
          claimName: sonarqube-logs-pvc
      - name: sonarqube-extensions
        persistentVolumeClaim: 
          claimName: sonarqube-extensions-pvc
---
apiVersion: v1 
kind: Service 
metadata: 
  name: sonarqube-service 
  labels: 
    app: sonarqube 
spec: 
  selector: 
    app: sonarqube 
  ports: 
    - port: 9000 
      targetPort: 9000
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sonarqube-data-pv
  labels:
    app: sonarqube-data-pv
spec:
  storageClassName: ""
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/f/dev/data/sonarqube-data
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sonarqube-logs-pv
  labels:
    app: sonarqube-logs-pv
spec:
  storageClassName: ""
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/f/dev/data/sonarqube-logs
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sonarqube-extensions-pv
  labels:
    app: sonarqube-extensions-pv
spec:
  storageClassName: ""
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/f/dev/data/sonarqube-extensions
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonarqube-data-pvc
spec:
  volumeName: sonarqube-data-pv
  storageClassName: ""
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonarqube-logs-pvc
spec:
  volumeName: sonarqube-logs-pv
  storageClassName: ""
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonarqube-extensions-pvc
spec:
  volumeName: sonarqube-extensions-pv
  storageClassName: ""
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

공유 폴더의 permission denied 오류로 인해 따로 chmod 777 처리를 하였다.
mssql의 password는 secret을 호출하도록 처리하였는데 별도 secret을 사용하지 않는 경우 직접 명시해서 사용하면 된다.

ingress 설정에 다음과 같이 추가하였다.
만약 ingress를 사용하지 않는다면 node port나 load balancer로 service를 설정하여 사용하면 된다.

  - host: sonarqube.bluesky.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: sonarqube-service
            port:
              number: 9000

sonarqube 설정

내 경우 jenkins에서 maven sonarqube plugin을 호출하여 sonarqube를 사용한다.
이를 위해 sonarqube 쪽과 jenkins, 대상 project에 각각 설정이 필요하다.

sonarqube에 접속한다.


default admin 계정 정보는 admin/admin이다.
최초 로그인하면 비밀번호를 변경하라고 안내한다.

java 관련 plugin 추가

로그인 한 이후 java project에서 사용할 plugin들을 추가하면 된다.
내 경우 Checkstyle, Findbugs, PMD를 추가하였다.
administration -> Marketplace로 가면 plugin 사용 관련 주의 사항을 확인 처리하고 검색을 하면 install 항목이 활성화된다.

내 경우 Checkstyle, Findbugs, PMD를 추가하였다.

Token 생성하기

jenkins에서 sonarqube로 분석 결과를 저장할 수 있도록 권한을 부여할 token을 생성해야 한다.
최상단 오른쪽의 로그인 이모티콘 -> My Account를 선택한 후 Security 페이지에서 token을 생성한다.

 

 

Jenkins 설정

jenkins에서는 다음과 같은 maven 명령어를 사용하여 sonarqube를 사용한다.
해당 명령을 수행하는 job을 추가하면 된다.

mvn clean verify -B -U -Psonarqube sonar:sonar -Dsonar.ws.timeout=300 -Dsonar.projectKey=bluesky-boot -Dsonar.projectName="bluesky boot project"

sonar:sonar 명령을 수행한 분석 결과를 저장할 sonarqube의 주소와 접근 권한을 추가해야 하는데 공통 설정이기 때문에 jenkins에서 사용하는 maven의 settings.xml에 해당 설정을 추가한다.
(위에서 사용한 것처럼 mvn parameter로 추가하여 개별 설정으로 사용할 수도 있다.)
jenkins의 Global Tool Configuration에서 Install Automatically로 maven을 추가한 경우 {maven_home}/tools/hudson.tasks.Maven_MavenInstallation/maven/conf 에 settings.xml이 위치하고 있다.

settings.xml에 다음과 같이 sonar.host.url과 sonar.login properties를 추가한다.

<settings>
  <profiles>
    // 중간 생략
    <profile> 
      <id>sonarqube</id> 
      <properties> 
        <sonar.host.url>http://sonarqube-service:9000</sonar.host.url> 
        <sonar.login>[sonarqube에서 생성한 토큰 값]</sonar.login> 
      </properties> 
    </profile> 
  </profiles>
</settings>

sonarqube라는 profile로 maven을 실행하면 위 설정된 값을 사용하게 된다.

Project 설정

java project에는 다음과 같은 테스트 코드 관련 plugin 설정을 추가한다.

<plugin> 
    <groupId>org.apache.maven.plugin</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>${maven-surefire-plugin.version}</version> 
    <configuration> 
        <includes> 
            <include>**/*Test.java</include> 
            <include>**/*Tests.java</include> 
        </includes> 
    </configuration> 
</plugin> 
<plugin> 
    <groupId>org.jacoco</groupId> 
    <artifactId>jacoco-maven-plugin</artifactId> 
    <version>${jacoco-maven-plugin.version}</version> 
    <executions> 
        <execution> 
            <id>prepare-agent</id> 
            <goals> 
                <goal>prepare-agent</goal> 
            </goals> 
        </execution> 
        <execution> 
            <id>report</id> 
            <phase>test</phase> 
            <goals> 
                <goal>report</goal> 
            </goals> 
        </execution> 
    </executions> 
</plugin>

jenkins에서 sonar:sonar가 실행되면 위에 추가된 플러그인을 사용하여 *Test.java, *Tests.java 이름의 파일들의 test report를 생성하게 되고 sonarqube로 저장하게 된다.

Maven을 사용한 프로젝트가 아닌 경우

위의 경우는 maven을 사용한 경우이다.
만약 maven을 사용한 프로젝트가 아니라면 관련 설정 가진 sonar-project.properties를 해당 프로젝트에 설정하고 SonarScanner를 실행하면 된다.

https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner/

jenkins에서 SonarQube Scanner plugin을 설치하고 각 프로젝트의 개별 설정을 불러와서 사용하면 된다.

Maven 프로젝트의 경우 Maven의 프로젝트 구조를 따로 선언하고 관리할 필요가 없어서 이 plugin 대신 maven plugin을 사용하였다.

SonarScanner를 사용을 한 경우는 이전에 소개했던 글을 참고하면 된다.

2019.07.31 - [Study/CI&CD] - SonarQube 사용하기

 


이와 같이 sonarqube를 사용하여 jenkins에서 빌드하면 결과가 저장되어 확인할 수 있게 된다.

이렇게 확인한 문제점들을 고치고 다시 빌드하면 해결된 부분에 대해 반영되어 기술 부채가 줄어드는 것을 확인할 수 있게 된다.

반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요