SonarQube 설치 및 Jenkins 연동 매뉴얼

목차

  1. 사전 요구사항
  2. SonarQube 서버 설정
  3. Jenkins 플러그인 설치 및 설정
  4. SonarQube 프로젝트 설정
  5. Jenkins 파이프라인 연동
  6. Quality Gates 설정
  7. 연동 테스트
  8. 문제 해결
  9. 베스트 프랙티스
  10. 유지보수

1. 사전 요구사항

  • Kubernetes 클러스터 (minikube, k8s 등)
  • Helm 3.x 설치
  • kubectl 설치 및 클러스터 접근 권한
  • Jenkins 서버 실행 중
  • Jenkins 관리자 콘솔 접근 권한
  • Jenkins ↔ SonarQube 간 네트워크 연결 가능

2. SonarQube 서버 설정

2.1 Helm Chart 설치

helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm repo update

helm install sonarqube sonarqube/sonarqube \
  --namespace sonarqube \
  --create-namespace \
  --values sonarqube.yaml

2.2 접근 확인

# Ingress 확인
curl -I http://sonarqube.127.0.0.1.nip.io

# 또는 포트 포워딩
kubectl port-forward svc/sonarqube-sonarqube 9000:9000 -n sonarqube

2.3 초기 계정

  • ID: admin
  • PW: admin (최초 로그인 시 변경 필요)

2.4 토큰 생성

  1. 프로필 → My Account → Security → Generate Tokens

    image.png

    image.png

  2. 토큰 이름: jenkins-integration , 타입: Global Analysis Token

    Generate Tokens
    Name : jenkins-integration
    Type : Project Analysis Token
    Project : apps-demo
    Expires in : No expiration
  3. 생성 후 Jenkins에 등록

    • id: sonarqube-token secret: token

3. Jenkins 플러그인 설치 및 설정

3.1 필수 플러그인

  • SonarQube Scanner for Jenkins
  • Quality Gates Plugin

3.2 Scanner 도구 설정

  • Jenkins 관리 → Global Tool Configuration

    image.png

  • SonarQube Scanner 추가 (자동 설치), 여기서 사용할 이름은 젠킨스 파일에서 호출할 커멘드 지정 이름.

    image.png

    image.png

3.3 SonarQube 서버 등록

  • Jenkins 관리 → 시스템 설정

  • Name: SonarQube

  • URL: http://sonarqube.127.0.0.1.nip.io

  • Credentials: sonarqube-token 아까 발급받은 sonarqube 시크릿키 Kind: Secret text

    image.png

    image.png


4. SonarQube 프로젝트 설정

4.2 Quality Profile

  • 기본 Sonar way 또는 사용자 정의

    image.png

4.3 sonar-project.properties 예시

  • 젠킨스 파일이 저장되는 곳에다가 이 설정파일을 등록한다.
# SonarQube project configuration
sonar.projectKey=app-demo
sonar.projectName=App Demo
sonar.projectVersion=1.0

# Source code location
sonar.sources=.
sonar.sourceEncoding=UTF-8

# Exclusions
sonar.exclusions=**/dist/**,**/venv/**,**/__pycache__/**,**/node_modules/**,**/.git/**,**/target/**,**/*.pyc,**/.pytest_cache/**,**/htmlcov/**

# Python specific settings (no test coverage files exist)
# sonar.python.coverage.reportPaths=coverage.xml
# sonar.python.xunit.reportPath=test-results.xml

# Language detection
sonar.language=py

# Test settings (no tests directory exists)
# sonar.tests=tests/
# sonar.test.inclusions=**/test_*.py,**/*_test.py

# Coverage exclusions
sonar.coverage.exclusions=**/test_*.py,**/*_test.py,**/conftest.py

# Duplication exclusions
sonar.cpd.exclusions=**/migrations/**

5. Jenkins 파이프라인 연동

5.0 Jenkinsfile 파라미터 예시

string(name: 'SONAR_HOST_URL', defaultValue: 'http://sonarqube.127.0.0.1.nip.io', description: 'SonarQube server URL')
string(name: 'SONAR_CREDENTIALS_ID', defaultValue: 'sonarqube-token', description: 'Jenkins credentialsId for SonarQube token')
string(name: 'SONAR_PROJECT_KEY', defaultValue: 'app-demo', description: 'SonarQube project key')
string(name: 'SONAR_PROJECT_NAME', defaultValue: 'App Demo', description: 'SonarQube project name')
booleanParam(name: 'ENABLE_SONAR', defaultValue: true, description: 'Enable SonarQube code analysis')
booleanParam(name: 'SONAR_QUALITY_GATE', defaultValue: true, description: 'Wait for SonarQube Quality Gate')

5.1 Jenkinsfile 예시

stage('SonarQube Analysis') {
  when {
    expression { return params.ENABLE_SONAR }
  }
  steps {
    script {
      echo "Starting SonarQube code analysis for project: ${params.SONAR_PROJECT_KEY}"
      
      // Jenkins SonarQube 플러그인의 표준 방식
      withSonarQubeEnv('SonarQube') {
        // Jenkins에서 관리하는 SonarScanner 도구 사용
        def scannerHome = tool 'sonar-scanner'
        sh """
          ${scannerHome}/bin/sonar-scanner \
            -Dsonar.projectKey=${params.SONAR_PROJECT_KEY} \
            -Dsonar.projectName="${params.SONAR_PROJECT_NAME}" \
            -Dsonar.projectVersion=${env.VERSION}
        """
      }
    }
  }
}

stage('SonarQube Quality Gate') {
  when {
    allOf {
      expression { 
        echo "ENABLE_SONAR: ${params.ENABLE_SONAR} (type: ${params.ENABLE_SONAR?.getClass()})"
        return params.ENABLE_SONAR == true || params.ENABLE_SONAR == 'true'
      }
      expression { 
        echo "SONAR_QUALITY_GATE: ${params.SONAR_QUALITY_GATE} (type: ${params.SONAR_QUALITY_GATE?.getClass()})"
        return params.SONAR_QUALITY_GATE == true || params.SONAR_QUALITY_GATE == 'true'
      }
    }
  }
  steps {
    script {
      echo "Waiting for SonarQube Quality Gate result..."
      echo "Webhook URL: http://host.minikube.internal:8080/sonarqube-webhook/"
      
      timeout(time: 10, unit: 'MINUTES') {
        def qg = waitForQualityGate()
        echo "Quality Gate result received: ${qg.status}"
        echo "Quality Gate details: ${qg}"
        
        if (qg.status != 'OK') {
          error "Pipeline aborted due to quality gate failure: ${qg.status}"
        }
        echo "Quality Gate passed successfully"
      }
    }
  }
}

5.2 Webhook 설정

image.png

  • SonarQube: 프로젝트 셋팅 → Webhooks → Create
  • Name: Jenkins-sonarqube-quality
  • URL 예시: http://jenkins:8080/sonarqube-webhook/

6. Quality Gates 설정

  • Coverage < 80%
  • Duplicated lines > 3%
  • Maintainability/Rel/Sec Rating ≤ A
  • ㅓ

→ Project Settings → Quality Gate → Custom Gate 선택


7. 연동 테스트

  1. Jenkins 빌드 실행 (ENABLE_SONAR=true)
  2. Jenkins 콘솔 로그에서 분석 결과 확인
  3. SonarQube 대시보드에서 프로젝트 상태 확인

8. 문제 해결

8.1 공통 이슈

  • Scanner 없음: Jenkins Global Tool 확인
  • 인증 실패: Token 만료 여부 확인
  • Webhook 타임아웃: SonarQube → Jenkins 접근 가능성 확인

8.2 디버깅

# Jenkins → SonarQube 연결 확인
curl -I http://sonarqube.127.0.0.1.nip.io

# SonarQube → Jenkins Webhook 테스트
curl -X POST http://jenkins:8080/sonarqube-webhook/ -d '{"test":"ok"}'

9. 베스트 프랙티스

  • 관리자 계정 강력 비밀번호
  • 토큰 주기적 로테이션
  • HTTPS 적용
  • Quality Gate 조건 점진적 강화

10. 유지보수

  • SonarQube/플러그인 정기 업데이트
  • 디스크 공간 및 DB 백업
  • Quality Profile 주기적 검토
  • 모니터링/알림 설정

👉 이제 매뉴얼은 섹션 번호와 목차가 일치하고, 소제목·코드 블록·리스트가 깔끔하게 정리되어 있습니다.

원하시면 제가 이 문서를 PDF 배포용 또는 사내 위키용 Markdown 버전으로도 만들어드릴 수 있어요. 어떤 형식이 필요하세요?

image.png

Comments

💬 Sign in with GitHub to leave a comment. Comments are public and stored in GitHub Discussions.