hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

build server 부터 배포까지 - 1. GCP + Docker + Jenkins + Gitlab + JUnit + SonarQube + GCR image push
DevOps/Tutorial

build server 부터 배포까지 - 1. GCP + Docker + Jenkins + Gitlab + JUnit + SonarQube + GCR image push

그럼 이제 GCP 위에 docker를 올리고, docker 위에 jenkins, sonarqube를 올리고 gitlab webhook으로 pull받아서 build 후 GCR push까지, 한 번에 다뤄보고자 한다. 자세한 모든 화면은 이전 포스팅들을 참고.

 

*** 지금 이 글대로 구성하면, ci server에서 jenkins data가 저장될 곳이 없어 재시작하면 전부 날아간다. 이를 고려해서, volume을 추가하는 것을 권장한다.

 

1. docker-compose로 GCR 위에 docker, docker 위에 jenkins, sonarqube 설치

/home/hyelie/compose/docker-compose.yml

version: "3"

services:
    jenkins:
        container_name: jenkins-compose
        image: jenkins/jenkins:lts
        user: root       
        ports:
         - "8081:8080" 
        volumes:
         - /var/run/docker.sock:/var/run/docker.sock
         - /usr/bin/docker:/usr/bin/docker
         - jenkins_data:/var/jenkins_home

    sonarqube:
        image: sonarqube:lts
        container_name: sonarqube
        ports:
         - "9000:9000"
        volumes:
         - sonarqube_conf:/opt/sonarqube/conf
         - sonarqube_data:/opt/sonarqube/data
         - sonarqube_extensions:/opt/sonarqube/extensions
         - sonarqube_logs:/opt/sonarqube/logs
        
volumes:
    jenkins_data:
    sonarqube_conf:
    sonarqube_data:
    sonarqube_extensions:
    sonarqube_logs:
​

 

제일 처음 썼던 게시글과는 다르게, 이제는 jenkins에서 docker 명령어를 바로 수행할 수 있기 때문에 volumes에 docker.sock, docker folder를 연결해 준다.(이 방식은 docker out of docker 방식이다.) 이후 아래 명령어가 잘 수행되는지 보자.

 

$ docker-compose up -d
Creating jenkins-compose ... done
Creating sonarqube       ... done

$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS        PORTS                                                  NAMES
42dd8d6f5d59   jenkins/jenkins:lts   "/sbin/tini -- /usr/…"   2 seconds ago   Up 1 second   50000/tcp, 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp   jenkins-compose
d4984f7a0841   sonarqube:lts         "bin/run.sh bin/sona…"   2 seconds ago   Up 1 second   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp              sonarqube


$ docker exec -it 42dd8d6f5d59 bash
droot@42dd8d6f5d59:/# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS         PORTS                                                  NAMES
42dd8d6f5d59   jenkins/jenkins:lts   "/sbin/tini -- /usr/…"   11 seconds ago   Up 9 seconds   50000/tcp, 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp   jenkins-compose
d4984f7a0841   sonarqube:lts         "bin/run.sh bin/sona…"   11 seconds ago   Up 9 seconds   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp              sonarqube

 

exec bash로 들어가서 docker ps 결과가 수행 잘 되면 잘 된 것이다.

 

docker logs 42dd8d6f5d59

 

를 입력해 jenkins 비밀번호를 알아내고, jenkins에 접속하자. 그리고 plugin은 다음의 것들을 설치한다.

 

- gitlab

- gitlab hook

- sonarqube scanner

- sonar quality gates

- docker pipeline

- google oauth credentials

- google container registry

 

 

 


 

 

 

2. jenkins-gitlab 연동

GCR에서

ssh-keygen

 

을 입력한다. ~/.ssh에 있는 id_rsa.pub 값을 복사해서 gitlab - repository - deploy key에 등록

 

gitlab에 public key 등록

 

~/.ssh에 있는 id_rsa 값을 복사해서 jenkins 관리 - credentials - global - add credentials - ssh username with private key - enter directly에 등록.

jenkins는 {GCP public ip}:8081로 접속 가능.

jenkins에 private key 등록

 

위 방법은 public repository만 적용 가능하다. private repository의 경우 아래 링크를 따른다.

https://stackoverflow.com/questions/49790666/how-to-configure-jenkins-to-access-gitlab-private-repository-without-gitlab-plug

 

gitlab - settings - repository - deploy token으로 token 발급 받고, jenkins id/pw에 넣어주면 된다.

 


 

 

 

3. pipeline project 생성

jenkins - new item - pipeline project - build trigger - build when a change is pushed to gitlab~~~에 있는 링크, 그리고 고급 - secret token generate 후 복사.

gitlab webhook link 복사
secret token 복사

 

이후 gitlab - settings - webhook에 위의 링크, token 복사

gitlab - settings - webhook - url, secret token 붙여넣기

 

이후 test - push event로 잘 가는지 보자.

 

jenkins pipeline definition 등록

pipeline - definition - pipeline script from scm을 클릭하고

scm - git, repository url 등록, credential은 2.에서 등록한 gitlab credential 등록.

 

 

 


 

 

 

4. sonarqube, gradle 버전 연동

{GCP public IP}:9000으로 sonarqube 접속, 초기 id/pw admin/admin.

 

sonarqube token 등록 및 복사해두기

add a project - manually - 프로젝트 이름 적당히 등록, token 적당히 등록 및 복사. continue - gradle - 안에 있는 내용 복사.

 

sonarqube webhook 등록

administration - configuration - webhooks - create.

name은 적당히, url은 http://{jenkins url}:{jenkins port}/sonarqube-webhook/으로 등록.

 

jenkins token 등록
token은 여기 있는 값으로.

jenkins 관리 - manage credentials - global - add credentials - secret text, token 등록.

 

jenkins에 sonarqube server 등록

jenkins 관리 - 시스템 설정 - sonarqube servers 등록, 이름은 sonar-server, url은 sonarqube url, credential은 바로 위에서 만든 credential. 이후 저장.

 

jenkins에 sonarqube scanner 등록.

jenkins 관리 - global tool configuration - sonarqube scanner 등록.

 

마지막으로 gradle도 하자.

 

jenkins 관리 - global tool configuration -

jenkins - gradle 등록

gradle - add gradle - 내가 쓰는 버전인 6.9 등록

 

 

 


 

 

 

5. 테스트

내 로컬에 등록한 git으로 remote 등록,

 

/local/build.gradle

plugins {
	id 'org.springframework.boot' version '2.4.8'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
	id "org.sonarqube" version "3.0"
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
	useJUnitPlatform()
}

pulgins에 id sonarqube 등록.

 

이후 dockerfile 생성.

 

/local/Dockerfile

FROM openjdk:8-jdk-alpine 
VOLUME /tmp 
ARG JAR_FILE=build/libs/demo-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar 
EXPOSE 8080 
ENTRYPOINT ["java","-jar","/app.jar"]

 

마지막으로 jenkinsfile 생성.

pipeline {
    agent any
    tools{
        gradle '6.9'
    }    // 내가 쓸 build gradle. '' 안에 들어갈 것은 gradle 이름이다.
    stages{
        stage('Ready'){
            steps{
                sh "echo 'Ready'"
            }
        }

        stage('Spring Boot Clean & Build'){
            steps{
                sh "chmod +x gradlew;"
                sh "./gradlew clean;"  
                sh "./gradlew build -x test;"  
            }
        }   // build 시 test 없이 진행하고, test는 추후에 거르기 위해 이렇게 이용함.
        
        stage('Gradle Junit Test') {
            steps {
                    sh "chmod +x gradlew; ./gradlew test"
            }
        }   // test를 이용해서 확인함.
        stage('JUnit Test Publish') {
            steps {
                junit '**/build/test-results/test/*.xml'
            }
        }   // Junit 테스트 결과를 젠킨스 프로젝트 첫 화면에서 볼 수 있게 결과물을 출력한다. 이렇게 해주면 알아서 결과물을 보여준다.

        stage('SonarQube Analysis'){
            steps{
                withSonarQubeEnv('sonar-server'){
                    sh './gradlew sonarqube -Dsonar.projectKey=ciserver -Dsonar.host.url=http://34.68.84.109:9000 -Dsonar.login=8ec502617dd7b039e3179fadb5ec83f0127544cc'
                }
            }
        }

        stage('SonarQube Quality Gate'){
            steps{
                timeout(time: 1, unit: 'MINUTES') {
                    script{
                        echo "Start~~~~"
                        def qg = waitForQualityGate()
                        echo "Status: ${qg.status}"
                        if(qg.status != 'OK') {
                            echo "NOT OK Status: ${qg.status}"
                            updateGitlabCommitStatus(name: "SonarQube Quality Gate", state: "failed")
                            error "Pipeline aborted due to quality gate failure: ${qg.status}"
                        } else{
                            echo "OK Status: ${qg.status}"
                            updateGitlabCommitStatus(name: "SonarQube Quality Gate", state: "success")
                        }
                        echo "End~~~~"
                    }
                }
            }
        }
        stage('Docker image build'){
            steps{
                script{
                    def app = docker.build("hyelie/firstspring:latest")
                }
            }
        }
        stage('Clean'){
            steps{
                sh "chmod +x gradlew;"
                sh "./gradlew clean;"  
            }
        }
    }
}

여기서 sonarqube analysis step에 있는 withSonarQubeEnv는 jenkins 관리 - 시스템 설정 - sonarqube servers에 등록한 이름이고 그 안에 있는 shell은 아래 사진에 있는 ./gradlew sonarqube \ ~~~에 있는 코드이다.

sonarqube token

 

build 결과
image 생성

 

build가 되고, docker image가 생성되었다.

 

 

 


 

 

 

6. GCR에 push해보기

https://cloud.google.com/container-registry/docs/quickstart

 

프로젝트 설정

먼저 위 링크로 들어가서 API 사용 설정 - 프로젝트 설정을 누른다. 그러면 gcr이 활성화된다.

 

API 및 서비스
사용자 인증 정보 - 사용자 인증 정보 만들기 - 서비스 계정
적당히 입력
역할 관리
역할 만들기 - 권한

역할 만들기 - 권한 - 권한 추가으로 들어가 아래 5개를 추가한다.

- storage.objects.create

- storage.objects.get

- storage.objects.list

- storage.buckets.create

- storage.buckets.get

 

권한 추가하기
추가된 권한 확인 및 만들기
만든 역할로 설정

역할은 원래는 storage admin & storage object viewer로 하고 싶었는데 그걸로 하니 안되어서 custom으로 만든 권한을 두었다.

 

생성한 계정 - key - 키 추가 - json

key를 추가하면 뭐 하나가 다운로드된다.

 

 

다음으로 jenkins로 넘어가자.

 

jenkins credential 추가

jenkins - manage credentials - global - add credentials - google service account from private key.

project 이름은 gcr-ci-project라고 두겠다. json key는 방금 다운받아진 파일을 선택한다.

 

/local/jenkinsfile

stage('docker build'){ steps{ sh 'docker build -t gcr.io/numeric-replica-320807/testspring .' } } stage('Docker push image'){ steps{ script{ docker.withRegistry('https://gcr.io', 'gcr:gcr-ci-project'){ sh 'docker push gcr.io/numeric-replica-320807/testspring' } } } } // gcr push

 

jenkinsfile에는 이렇게 적는다. 뜻만 대충 설명하자면, image id를 gcr에 넣고, project 이름을 같이 넣음으로써 push할 경로를 지정해 준다. docker hub에 push할 때 {repository name}/{project 이름}으로 적었던 것처럼.

이후에는 jenkins에 있는 registry를 이용해 gcr에다가 push하겠다는 말이다.

 

jenkins 결과
gcr 결과

GCR에도 잘 들어가 있다!

 

 

 

 


 

 

 

지금까지 GCP VM instance에 빌드 서버를 올렸다. 다음에는 GKE 클러스터를 만들고, 쿠버네티스 노드를 만들고, db를 배포할 것이다. DB를 먼저 배포하는 이유는, 저번에 게시판을 빌드할 때 DB가 없으면 hikaripool test 오류가 났기 때문에 그렇다.

이후에는 spring 게시판 예제를 kubernetes에 올려볼 것이다.

 

이렇게 하면, 개발자는 개발만 해서 git에 올리면 되고, project master가 git branch를 merge하면 jenkins에서 테스트/빌드가 완료되어 GCR로 올라간다. 이후에 project master가 kubenetes deploy를 진행하면 될 것이다!!

'DevOps > Tutorial' 카테고리의 다른 글

build server 부터 배포까지 - 3. GKE Spring MySQL 배포 - MySQL 배포 및 Mysql + Spring 배포  (0) 2022.10.05
build server 부터 배포까지 - 2. GKE Spring MySQL 배포 - GKE 클러스터 생성 및 spring 예제 배포  (0) 2022.10.05
EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 6. 수정사항, ECR push  (0) 2022.10.05
EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 5. jenkins pipeline - JUnit + SonarQube  (0) 2022.10.05
EC2 Docker Jenkins Spring Gitlab 자동 빌드 - 4. docker image push  (0) 2022.10.04
    hyelie
    hyelie

    티스토리툴바