4 분 소요

이전에 이 글에서 젠킨스를 도입해보았다. 이번에는 젠킨스와 소나큐브를 연동하여 정적 검사를 통해 코드 품질을 향상시켜보자.

0. SonarQube란?

정적 코드 분석 도구

간단하게 정적 분석은 프로그램을 실행하지 않은 상태에서 소스 코드나 컴파일된 코드를 이용해 프로그램을 분석하는 방법이며, 동적 분석은 프로그램을 실제 환경이나 가상 환경에서 실행해 보면서 분석하는 방법이다.

정적 분석은 소스 코드의 모든 부분을 확인할 수 있지만, 실행 환경에서의 상태를 정확히 알 수 없기 때문에 실행할 때에만 알 수 있는 데이터가 필요한 경우 정확히 분석할 수 없다.
반대로 동적 분석은 실제로 실행해 보면서 분석하기 때문에 실행 환경에서의 상태를 잘 알 수 있지만, 프로그램을 실행할 수 있는 환경을 구축하기 어려울 때가 많고 소스 코드의 모든 부분을 테스트해 보기 힘들다는 문제가 있다.

이렇게 각 분석 방식은 장단점이 존재하기 때문에 정적 분석은 주로 개발 단계에서 소스 코드의 구조적인 문제나 실수를 찾아내는 데 사용하며 동적 분석은 테스트나 모니터링할 때 사용한다.
스크린샷 2023-03-17 오후 2 07 25

SonarQube

SonarQube는 위에서 소개한 정적 코드 분석 도구 중 하나이다.
정적 코드 분석 도구에는 PMD, FindBugs, CheckStyle 등이 있다.
내가 SonarQube를 선택하게 된 주된 이유는 레퍼런스가 많고 Github이나 Jenkins와의 연동을 통해 자동 정적 코드 분석을 구성할 수 있기 때문이다.

그렇다면 SonarQube의 장점에는 어떤 것이 있을까?

  • 지속적인 인스펙션
    • 지속적인 통합과 같이 빌드와 연동하여 지속적으로 코드에 대한 인스펙션을 수행합니다.
  • 품질 중앙화
    • 개발된 조직의 코드의 품질을 중앙 저장소에서 가시화하고 단일 위치에서 관리합니다.
  • DevOps와의 통합
    • 다양한 빌드 시스템, CI 엔진과 통합되어 DevOps 실천을 지원합니다.
  • 품질 요구사항 설정
    • 품질 게이트를 통해 표준화된 코드 품질 요구사항을 설정합니다.
  • 다중 언어 분석
    • 20개가 넘는 프로그램 언어에 대한 코드 분석을 지원합니다.
  • 플러그인을 통한 확장
    • 다수의 플러그인을 통해 SonarQube의 기능을 확장할 수 있습니다.
  • 오픈소스 프로젝트
    • 오픈소스 프로젝트로 특정 범위까지 무료로 사용 가능하다.

지금부터 이런 장점이 있는 SonarQube를 프로젝트에 직접 적용해보자!

1. SonarQube 설치하기 (with. Docker Compose)

이 글을 참고했다.

설치 순서는 아래와 같다.

  1. AWS EC2에 docker-compose를 먼저 설치한다.
  2. 이후 docker-compose.yml 파일을 이용해 sonarqube를 구동한다. (docker는 미리 설치되어 있다고 가정)
  3. sonar rule 세팅은 하지 않는다.
  4. default ID/Password는 admin/admin 이다.

1) 폴더 만들기

우분투 인스턴스에 접속해서 진행한다.
docker 폴더 생성 후(나는 젠킨스를 도커컴포즈를 통해 실행하고 있기 때문에 이미 만들어져 있었다) 그 안에 sonarqube 폴더를 만들자.

그리고 sonarqube 폴더 안에 docker-compose.yml을 생성하자.
폴더 구조는 아래와 같다.

docker
⎿ sonarqube
 ⎿ docker-compose.yml

2) docker compose 작성

version: "2"

services:
  sonarqube:
    image: sonarqube:lts
    container_name: sonarqube
    ports:
      - "9000:9000"
    ulimits:
      nofile:
        soft: "262144"
        hard: "262144"
    networks:
      - sonarnet
    environment:
      - sonar.jdbc.url=jdbc:postgresql://db:5432/sonar
    volumes:
      - sonarqube_conf:/opt/sonarqube/conf
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs

  db:
    image: postgres
    container_name: postgres_sonar
    ports:
      - "5432:5432"
    networks:
      - sonarnet
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

networks:
  sonarnet:
    driver: bridge

volumes:
  sonarqube_conf:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql:
  postgresql_data:
  • sonarqube와 db라는 서비스 (도커 컨테이너)로 구성되고 이들간은 bridge모드로 네트워크를 서로 연결한다. (db:5432/sonar 로 요청가능한 이유가 이것임)
  • ulimits 이하 부분이 없으면 기동시에 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 등과 같은 오류가 발생할 수 있다.
    • (호스트 서버) root로 해당 파일을 오픈한다.
      (당장 적용은 CLI에서 sudo sysctl -w vm.max_map_count=262144 )
      vi /etc/sysctl.conf
      # 아래 내용 추가
      vm.max_map_count=262144
      
    • (docker-compose.yml) 아래 내용 추가
      ulimits:
      nofile:
        soft: "262144"
        hard: "262144"
      
  • AWS EC2위에서 셋업했으므로 Security Group에서 9000 포트를 오픈한다.
    (DB 접속 필요시 5432 포트도 오픈)

3) SonarQube 실행

$ docker-compose up -d

4) 브라우저 접속

http://[EC2_IP]:9000으로 접속하면 아래와 같은 화면이 뜬다.
스크린샷 2023-03-16 오후 10 36 30

초기에는 IDPassword 모두 admin이다.
비밀번호 변경 후 로그인하면 아래와 같은 화면이 나온다.
스크린샷 2023-03-16 오후 10 40 14

2. Jenkins와 연동하기

이 글이 글을 참고했다.

1) Sonarqube Token 생성

소나큐브 브라우저에 접속한 뒤 시작하자!

Administration -> Security -> Users -> Tokens 버튼을 눌러서 Token을 생성한다.

스크린샷 2023-03-16 오후 10 57 19

Generate Tokens 입력창 안에 Token 명을 입력한뒤 Generate 버튼을 누른다. (나는 jenkinsXsonar라는 이름으로 토큰을 생성했다.)
이후 토큰 값이 생성되면 copy 버튼을 누르고 메모장 같은 노트 어플에 복사해 두도록 한다.
스크린샷 2023-03-17 오전 11 19 45

2) Sonarqube 프로젝트 생성

다음은 젠킨스와 연동할 소나큐브 프로젝트를 생성한다.

Projects -> Add a project 버튼을 눌러 새로운 Sonarqube 프로젝트 생성

스크린샷 2023-03-16 오후 11 03 50

Project Key 및 Display Name 입력

스크린샷 2023-03-16 오후 11 07 05

3) Jenkins SonarQube Scanner Plugin 추가 및 설정

여기서부터는 젠킨스 브라우저에 접속하여 진행한다.

Jenkins 관리 -> Plugin Manager에서 SonarQube Scanner 플러그인 설치

젠킨스에서 소나큐브와 연동할 수 있는 플러그인을 설치한다. 플러그인은 Jenkins웹페이지 좌측 메뉴에서 에서 Jenkins관리 > 플러그인 관리를 클릭 후, 설치 가능 탭을 클릭한다. 이후 검색창에 아래와 같이 “Sonarqube scanner” 를 입력 후 체크박스를 선택하고 Install without restart를 선택하여 설치한다.
스크린샷 2023-03-16 오후 11 10 22

Jenkins 관리 -> Global Tool Configuration에서 SonarQube Scanner 추가

Jenkins관리 메뉴에서 Global Tool Configuration 클릭한다. 바로 전 플러그인을 설치했기 때문에 SonarQube Scanner라는 항목이 확인 가능하다. ‘Add SonarQube Scanner’ 클릭, 스캐너의 이름을 정하고 버전 확인 후 저장버튼을 클릭 (나는 version을 따로 지정하지 않았다.)
스크린샷 2023-03-16 오후 11 15 37

Jenkins 관리 -> 시스템 설정에서 SonarQube servers 설정

jenkins관리에 시스템 설정 메뉴를 클릭 후 SonarQube servers 항목의 ‘Add SonarQube’를 클릭한다.
이후 확인되는 확장 탭에서 Server이름을 기입하고 현재 소나큐브가 구동되고 있는 ip와 port를 입력하고 저장한다. (나는 소나큐브를 구동하고 있는 EC2 IP를 적었다.)
스크린샷 2023-03-16 오후 11 19 33

4) Jenkins Item 구성 설정

Jenkins Item -> 구성 선택

스크린샷 2023-03-16 오후 11 21 49

Add build step에서 Execute SonarQube Scanner 선택

스크린샷 2023-03-16 오후 11 24 09

항목 중 Analysis properties에 아래 내용 기입

sonar.login=*****************************************
sonar.projectKey=sonarpilot
sonar.projectName=sonarpilot
sonar.host.url=http://*****:9000/
sonar.report.export.path=sonar-report.json
detekt.sonar.kotlin.config.path=default-detekt-config.yml
sonar.sources=src/main/java,src/main/resources
sonar.java.sourcesion=1.0
sonar.sourceEncoding=UTF-8
sonar.java.binaries=build/classes
  • sonar.login: 소나큐브에서 발급한 token (이전에 복사해두었던 토큰 값 사용!)
  • sonar.projectKey: 소나큐브 프로젝트 생성 시 Key 값
  • sonar.projectName: 소나큐브 프로젝트 이름
  • sonar.host.url: 소나큐브 스캐너가 구동되고 있는 ip:port (필자의 경우 9000번 포트 사용)
  • sonar.java.binaries: gradle이라면 build/classes, maven이라면 target/classes를 작성한다.

스크린샷 2023-03-16 오후 11 27 54

저장 후 Build now를 클릭하여 Build가 정상적으로 실행되는지 확인한다.

스크린샷 2023-03-17 오전 12 05 29

5) Sonarqube 결과 화면

배포할 원격서버의 ip:port를 통해 빌드가 정상적으로 이루어짐이 확인되었다면,
Sonarqube가 설치된 http://ip:port로 접속하여 생성했던 project에 분석 Overview가 출력되었는지 확인한다.
스크린샷 2023-03-17 오전 12 08 06

프로젝트 -> Issues에서 아래와 같이 상세한 정보들을 볼 수 있다.
스크린샷 2023-03-17 오전 12 09 40

이 글을 참고했다.

SonarQube에서 관리해주는 소프트웨어 품질에 대해 간단하게 소개해보면

  • Code Smell : 심각한 이슈는 아니지만 베스트 프렉티스에서 사소한 이슈들로 모듈성(modularity), 이해가능성(understandability), 변경가능성(changeability), 테스트용의성(testability), 재사용성(reusability) 등이 포함된다.
  • Bugs : 일반적으로 잠재적인 버그 혹은 실행시간에 예상되는 동작을 하지 않는 코드를 나타낸다.
  • Vulnerabilities : 해커들에게 잠재적인 약점이 될 수 있는 보안상의 이슈를 말한다. SQL 인젝션, 크로스 사이트 스크립팅과 같은 보안 취약성을 찾아낸다.
  • Duplications : 코드 중복은 코드의 품질을 저해시키는 가장 큰 요인 중 하나이다.
  • Unit Test : 단위테스트 커버리지를 통해 단위 테스트의 수행 정도와 수행한 테스트의 성공/실패 정보를 제공한다.
  • Complexity : 코드의 순환 복잡도, 인지 복잡도를 측정합니다.
  • Size : 소스코드 사이즈와 관련된 다양한 지표를 제공합니다.

(🎉 이제 열심히 코드를 고쳐보자! ㅠㅠ SonarQube를 적용한 직후여서 Code smell이 정말 많다.. )



💛 개인 공부 기록용 블로그입니다. 👻

맨 위로 이동하기

태그:

카테고리:

업데이트: