인프라/Jenkins 2020. 3. 27. 17:34

 

오늘 다루어볼 포스팅은 Git과 Jenkins를 연동한 이후에 Jenkins Mulibranch pipeline으로 springboot web project를 docker image로 빌드 후 push하는 것까지 다루어볼 것이다. 이전까지는 오늘 다루어볼 포스팅의 연습 및 준비단계였고 본격적으로 CI/CD에 대해 다루어본다. 물론 오늘 다루어볼 포스팅 내용이 실무에서 그대로 활용하기 애매할 수는 있지만 포스팅을 이어나가면서 좀 더 보완해나갈 것이다.

 

1. Git & Jenkins 연동 후 Multibranch pipeline 작성

 

 

Jenkins - CentOS에 docker 환경으로 Jenkins 설치(Jenkins&GitHub CI)

오늘 다루어볼 내용은 CI의 핵심 젠킨스(Jenkins)를 다루어볼 것이다. 사실 이번 포스팅을 시작으로 젠킨스(Jenkins) 관련 몇개의 포스팅이 더 있을 듯하다. 오늘은 간단히 CentOS환경에 docker로 Jenkins를 설치..

coding-start.tistory.com

 

 

Jenkins - Jenkins&GitHub을 이용하여 아주 간단한 MultiBranch pipeline 만들어보기

이전 포스팅에 이어 Jenkins&GitHub을 이용한 CI 실습을 다루어볼 것이다. 이번 포스팅에서는 본격적으로 실습을 진행하기 전에 아주 간단한 echo를 찍어주는 pipeline 하나를 만들어 볼 것이다. 사실 이것을 설..

coding-start.tistory.com

 

위의 내용에 Git & Jenkins 및 간단한 Multibranch pipeline을 연동하는 내용이 있다. 위의 링크를 참조하고, 위에 없는 내용중 보완할 내용만 추가로 다룬다. 젠킨스와 깃의 연동은 크게 다르지 않다. 하지만 Multibranch pipeline 설정이 조금 보완되었다. 

 

1.1. Jenkins Multibranch pipeline 작성

 

General - Display Name과 Description을 작성해준다. (실행에 크게 영향 x)

 

*Branch Sources - 가장 핵심이 되는 configuration 영역이다. Github Credentials와 Repository HTTPS URL을 작성해준다. Credetials는 Jenkins Credentials에서 미리 만들어준다.(github의 인증정보 username/password로 작성하면 된다.) 그리고 깃헙의 https 주소를 넣어준다.

 

 

다음은 push & pull request event를 어떤 branch에 대해 인식시킬지에 대한 설정이다. 그리고 clean after checkout & clean before checkout을 넣어준다.

 

 

master & develop branch에 대해 push&pull request를 인식시키도록 하였다. 추후에는 일반 PR브랜치에 대해 인식시키면 feature branch등도 push&pull request 이벤트로 반응하도록 할 수 있을 것이다.

 

Clean after checkout & Clean before checkout은 .gitignore에 지정된 것을 포함하여 추적되지 않은 모든 파일과 디렉토리를 삭제하여 모든 체크 아웃 전후에 작업 공간을 정리하는 옵션이다.(테스트 결과 등의 파일정리) 또한 소스파일은 업데이트 된 경우 최신 변경사항을 가져오게 된다. Wipe out repository & force clone이라는 비슷한 옵션도 있지만, 이 옵션은 전체 프로젝트 작업 공간을 정리하고 빌드 전에 프로젝트를 다시 한번 클론하기 때문에 시간이 오래 걸린다.(프로젝트가 1기가라면 빌드 할 때마다 1기가를 pull받는다.)

 

 

마지막으로 push&pull request event가 발생시키면 젠킨스는 프로젝트 root에 있는 Jenkinsfile을 기준으로 pipeline을 기동시킨다는 설정이다.

 

2. Dockerfile & Jenkinsfile 작성

Jenkinsfile을 작성하기 전에 docker image build를 위해 우리는 Jenkins을 dood(docker out of docker)로 기동시켜야한다. 만약 준비가 되어 있지 않다면 아래 링크를 참조하자.

 

 

Jenkins - Jenkins dood(docker out of docker)로 실행시켜 agent docker 사용하기

아마 이번 포스팅부터 Jenkins(젠킨스)에서 정말 쓸모 있는 부분을 다룰 것 같다. 젠킨스 파이프라인을 다루기 전에 Jenkins 안에서 dood(docker out of docker)로 docker agent를 실행하는 방법에 대해 다루어..

coding-start.tistory.com

 

그리고 간단히 springboot web project를 생성해준다. 우리는 springboot web을 docker image로 빌드할 것이다.

 

2.1. Dockerfile 작성

간단히 우리가 만든 springboot web image를 빌드하기 위한 Dockerfile을 작성하자.

 

FROM adoptopenjdk/openjdk13:alpine-jre
MAINTAINER levi <1223yys@naver.com>

COPY ./build/libs/jenkins_sample-0.0.1-SNAPSHOT.jar /app/app.jar

EXPOSE 8080
CMD ["java", "-jar", "/app/app.jar"]

 

큰 내용은 없다. openjdk13을 base image로 하여 우리가 빌드한 springboot jar파일을 카피하여 실행시키는 image다.

 

2.2. Jenkinsfile 작성

 

pipeline {
    agent none

    environment {
        SLACK_CHANNEL = '#jenkins_notification'

        REGISTRY = '1223yys/spring-web-jenkins'
        REGISTRYCREDENTIAL = '1223yys'
    }

    stages {
        stage('Start') {
            agent any
            steps {
                slackSend (channel: SLACK_CHANNEL, color: '#FFFF00', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
            }
        }

        stage('Test') {
            agent {
                docker {
                    image 'adoptopenjdk/openjdk13:alpine'
                    alwaysPull true
                }
            }
            steps {
                sh './gradlew test --no-daemon'
            }
        }

        stage('Build') {
            agent {
                docker {
                    image 'adoptopenjdk/openjdk13:alpine'
                    alwaysPull true
                }
            }
            steps {
                sh './gradlew --no-daemon build -x test'
            }
            post {
                success {
                    stash includes: '**/build/**', name: 'build'
                }
            }
        }

        stage('Docker image build & push') {
            agent any
            steps {
                unstash 'build'
                //docker username/password credential
                sh 'docker login -u username -p password'
                sh 'docker build -t $REGISTRY:latest .'
            }
            post {
                success {
                    sh 'docker image ls | grep 1223yys'
                    sh 'docker push $REGISTRY:latest'
                }
            }
        }

        stage('Clean docker image') {
            agent any
            steps {
                sh 'docker rmi $REGISTRY'
            }
        }
    }

    post {
        success {
            slackSend (channel: SLACK_CHANNEL, color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        failure {
            slackSend (channel: SLACK_CHANNEL, color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
    }
}

 

파이프라인의 모든 문법을 다루어보지는 못하지만 위에 작성된 문법정도는 다루어볼 것이다. 우선 항상 pipeline {} 가 root에 작성되어야하고 항상 해당 블록내에 파이프라인 스크립트를 작성한다. 그리고 바로 밑에 agent none이 보이는데, pipeline 바로 밑에 agent가 있으면 이것은 글로벌한 agent가 되기 때문에 각 steps마다 다른 agent 사용이 필요할 때는 사용하기 애매하기 때문에 none으로 지정하였다.

 

두번째는 environment {} 이다. 해당 설정에는 사용자 정의 환경설정 작성이 가능하지만 jenkins container 내부에서 사용하는 환경변수가 될수도 있다. 해당 설정은 중요하게 사용될 수 있다. 실제로 필자는 내부망 서버에 젠킨스를 올려 외부 파일을 받는 것이 되지 않아 environment에 proxy설정을 환경변수로 넣어놓아서 외부 파일을 다운로드 받을 수 있게 세팅하였다.

 

세번째는 slack에 파이프라인의 시작을 알림보내는 스크립트이다. 슬랙 알림에 대한 것은 아래 링크를 참고하자. agent any는 현재 젠킨스 인스턴스 중에 하나를 사용하겠다라는 설정이다.

 

 

Jenkins - Jenkins pipeline Slack notification(젠킨스 빌드 슬랙 알림)

오늘 다루어볼 포스팅은 간단하게 젠킨스의 빌드 시작과 성공/실패에 대한 알림을 슬랙으로 받는 방법이다. 간단해서 아주 짧은 포스팅이 될 것 같다. 1. Slack Jenkins CI app install 예제는 이미 슬랙이 설치..

coding-start.tistory.com

 

네번째는 Test stage이다. git에서 checkout 받은 파일중 gradlew를 이용해 테스트 하기 위해서 agent를 openjdk13 base docker image에서 실행하겠다라는 스크립트이다. agent를 docker로 설정하고 사용할 이미지와 image pull 전략을 넣었다. 그리고 해당 docker image(openjdk13) 환경에서 실행할 스크립트를 "./gradlew test --no-daemon"를 작성했다. 참고로 docker agent로 실행시키기 때문에 이 환경은 특정 이미지 컨테이너의 환경이기 때문에 docker 명령이 먹지 않는다. 그 이유는 openjdk container에는 도커 엔진이 없기 때문에 ! 잘 유의하자.

 

 

다섯번째는 Build stage이다. 네번째 테스트 스테이지를 무사히 통과하였다면 이 단계로 넘어온다. 위 테스트 스테이지와 동일한 base 이미지로 build를 수행한다. 하지만 하나 추가된 설정이 있다.

 

post {
   success {
       stash includes: '**/build/**', name: 'build'
   }
}

 

우리는 openjdk13을 볼륨마운트하는 설정을 어디에도 하지 않았고, 해당 이미지는 실행이 끝나면 docker container를 제거시킨다. 그렇기때문에 build된 jar파일이 없어질 것이다. 그래서 위와 같이 특정 파일을 stash(임시 저장)하여 필요할때 꺼내쓰기 위한 설정을 넣어주었다.

 

 

여섯번째는 도커 이미지 build 및 push 스테이지이다. 눈에 띄는 설정이 unstash 'build'이다. 도커 이미지를 빌드하기 위해 jar 파일이 필요하기 때문에 임시저장한 빌드 결과물을 꺼내고 있다. 그리고 해당 파일을 바탕으로 Dockerfile을 사용해 이미지를 빌드한다. agent any로 넣어줬기때문에 우리는 jenkins container로 빌드 잡을 수행한다. 이렇기 때문에 우리는 docker 명령 사용이 가능하다.

 

stage('Docker image build & push') {
    agent any
    steps {
        unstash 'build'
        sh 'ls -al'
        sh 'docker login -u username -p password'
        sh 'docker build -t $REGISTRY:latest .'
    }
    post {
        success {
            sh 'docker image ls | grep 1223yys'
            sh 'docker push $REGISTRY:latest'
        }
    }
}

 

 

마지막 스테이지는 빌드한 이미지를 clean하는 스크립트이다. 이미지를 빌드하면 결국 로컬 디스크에 저장되므로 쌓이기 시작하면 어느샌가 디스크를 많이 먹고 있을 것이다. 그렇기 때문에 매 빌드마다 clean해준다.

 

stage('Clean docker image') {
    agent any
    steps {
        sh 'docker rmi $REGISTRY'
    }
}

 

 

slack에 빌드 성공 메시지가 갔는지 확인해보자.

 

 

마지막으로 dockerhub에 우리가 빌드한 이미지가 잘 올라갔는지 확인하자 !

 

 

오 ! 잘올라갔다 ㅎㅎ 여기까지 간단히 Jenkins Multibranch pipeline을 다루어보았다. 사실 필자는 내부망 장비를 할당받아서 실습했기 때문에 굉장히 삽질을 많이 했다.(외부에서 파일 다운로드 이슈 등) 아마 퍼플릭 존이라면 큰 이슈없이 실습이 가능할 것이다. 혹시나 내부망에서 실습을 진행하다 잘안되는 부분이 있다면 댓글을 남겨주길 바란다.

 

실습한 코드는 아래 깃헙링크를 참고하자.

 

 

yoonyeoseong/jenkins_sample

Contribute to yoonyeoseong/jenkins_sample development by creating an account on GitHub.

github.com

 

posted by 여성게
:
인프라/Jenkins 2020. 3. 26. 00:11

 

아마 이번 포스팅부터 Jenkins(젠킨스)에서 정말 쓸모 있는 부분을 다룰 것 같다. 젠킨스 파이프라인을 다루기 전에 Jenkins 안에서 dood(docker out of docker)로 docker agent를 실행하는 방법에 대해 다루어 볼 것이다. 실제로 많이 사용하는 유즈케이스이기도 하다. 그 이유는 필요한 라이브러리를 직접 설치하거나 하지 않고 Jenkins pipeline 스크립트 안에서 docker agent를 이용해 설치하면 별도로 의존성있는 라이브러리를 직접 설치하지 않아도 되고, 또한 Jenkins에서 Docker image를 빌드할때도 필요하다. 즉, 요즘 같이 도커가 대중화되있는 시대에는 거의 필수이지 않을까 싶다.(더 좋은 방법이 있다면 댓글로 알려주시면 감사하겠다.)

 

우리가 구성해볼 것은 docker 안에 docker를 띄우는 것이긴 하지만 "docker in docker" 방식처럼 독립적으로 띄우지는 않을 것이고, Host docker의 docker.sock을 공유해서 docker out of docker방식으로 띄워볼 것이다. docker in docker라는 것도 존재하지만 권장하는 방법이 아니기 때문에 우리는 docker out of docker로 실습을 진행해볼 것이다.

 

그렇다면 왜 docker in docker가 권장하지 않는 방법일까? 이유는 아래와 같다.

 

Docker in Docker(DinD)는 도커 안에 컨테이너 내부의 격리된 Docker 데몬을 실행하는 작업을 의미한다. 
즉, 도커데몬이 2개가 뜨는 것이다. CI 측면에서 접근하자면 Task를 수행하는 Agent가 Docker Client와
Docker Daemon 역할까지 하게되어 도커 명령을 수행하는데 문제가 없어진다. 하지만 아주 큰 단점이 존재한다.

호스트 도커 컨테이너가 privilieged mode로 실행되어야 한다.

> docker run --privileged --name dind -d docker:1.8-dind

privilieged 플래그를 사용한다면 호스트 컨테이너가 호스트 머신에서 할 수 있는 거의 모든 작업을 할 수 있게 된다.
이는 컨테이너를 실행하는데 큰 보안 위험을 초래할 수 있다.

출저 : https://aidanbae.github.io/code/docker/dinddood/

그렇다고, dood가 아예 단점이 없는 것은 아니다. 그 이유는 직접 띄워보면 알 수 있는 것이 jenkins container 내부에서 docker ps 명령을 날려보면 자기자신의 container가 떠있는 것이 목록에 보인다. 그 말은? 외부 호스트 도커에 떠있는 container에 접근이 가능하게 될 수도 있다는 것이다. 또한 docker.sock을 공유하기 위해 그만큼의 권한을 docker container 에게 제공해야한다. 조금씩 장단점이 있는 방법들인 것 같으니, 안전하게 사용하는 쪽이 좋은 방향인것 같다.

 

우선 우리는 이전 포스팅에서 도커 젠킨스 공식 이미지를 사용했었는데, 조금 변경할 필요가 생긴다. 그 이유는 공식 젠킨스 이미지 안에는 도커 엔진이 설치되어 있지 않기때문에 우리는 도커엔진이 깔려있는 젠킨스 이미지가 필요하기 때문에 커스텀하게 이미지를 다시 만들어 볼것이다.

 

1. jenkins-dood image 만들기

바로 실습에 들어간다. 우선 도커 엔진을 다운로드 받기 위한 스크립트를 파일로 작성하였다.

 

> docker_install.sh

#!/bin/sh
apt-get update && \
apt-get -y install apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     zip \
     unzip \
     software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable" && \
apt-get update && \
apt-get -y install docker-ce

 

그리고 다음으로는 도커 이미지를 빌드하기 위한 Dockerfile이다.

 

#공식 젠킨스 이미지를 베이스로 한다.
FROM jenkins/jenkins:lts

#root 계정으로 변경(for docker install)
USER root

#DIND(docker in docker)를 위해 docker 안에서 docker를 설치
COPY docker_install.sh /docker_install.sh
RUN chmod +x /docker_install.sh
RUN /docker_install.sh

RUN usermod -aG docker jenkins
USER jenkins

 

도커 이미지를 빌드할 준비가 되었다. 이제 도커 이미지를 빌드해보자. 

 

docker build -t 1223yys/jenkins-dind:latest .
docker push 1223yys/jenkins-dind

 

여기까지 크게 문제없이 따라왔다면 도커허브에 이미지가 push 되어 있을 것이다. 

 

 

그 다음은 Jenkins를 띄울 서버에 방금 만든 이미지로 Jenkins를 띄워보자.

 

docker run -d --name jenkins -p 8080:8080 -p 50000:50000 \
        -v /home/deploy/jenkins_v:/var/jenkins_home \
        -v /var/run/docker.sock:/var/run/docker.sock \
        1223yys/jenkins-dind:latest

 

중요한 것은 우리가 처음 이야기했던 것처럼 Host의 docker.sock을 공유해서 사용할 것임으로 볼륨마운트가 필요하다. 이제 젠킨스 컨테이너에 들어가서 도커엔진이 잘 떠있는지 확인하자.

 

> docker exec -it jenkins bash

jenkins@20ff53d54e94:/$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                              NAMES
20ff53d54e94        1223yys/jenkins-dind:latest   "/sbin/tini -- /usr/…"   35 minutes ago      Up 35 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jenkins

 

어? 나는 띄운 컨테이너가 없는데 떠있는 컨테이너가 하나 보인다 ! 그 이유는 앞에서도 간단히 이야기 한 것처럼 호스트 도커엔진과 공유하고 있기 때문이다 ! 우리가 실행 시킨 젠킨스 컨테이너가 보인다. 만약 "docker.sock 볼륨마운트"에 관해 permission denied가 발생한다면 아래와 같이 호스트 머신에서 docker.sock에 접근할 수 있도록 권한을 부여하자. 

 

> sudo chmod 666 /var/run/docker.sock

 

그리고 계속해서 docker 명령어를 sudo로 붙여서 사용하는 사람이 있다면 아래 명령어를 참고하자.

 

> sudo groupadd docker
> sudo usermod -aG docker deploy

 

이제 간단하게 젠킨스 파이프라인 스크립트(Jenkinsfile)를 작성해 도커엔진이 정말 잘 동작하는지 확인하자.

 

pipeline {
    agent none

    environment {
        SLACK_CHANNEL = '#jenkins_notification'
    }

    stages {
        stage('Start') {
            steps {
                slackSend (channel: SLACK_CHANNEL, color: '#FFFF00', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
            }
        }

        stage('Build & Test') {
            agent {
                docker {
                    image 'gradle:6.0-jdk13'
                    alwaysPull true
                }
            }
            steps {
                sh '''
                    gradle -version
                '''
            }
            post {
                always {
                    echo 'Test and Build post process !'
                }
            }
        }

        stage('Deploy') {
            steps {
                echo 'jenkins sample deploy ! '
            }
        }

    }
    post {
        success {
            slackSend (channel: SLACK_CHANNEL, color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        failure {
            slackSend (channel: SLACK_CHANNEL, color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
    }
}

 

해당 파이프라인은 도커로 gradle을 내려받아 젠킨스 내부에 떠있는 도커의 gradle 컨테이너를 이용하여 gradle -version을 체크하는 간단한 스크립트이다. 블루오션으로 파이프라인 결과를 확인해보자 !

 

 

성공했다 ! 여기까지 Jenkins 컨테이너 안에 도커엔진을 설치하여 파이프라인에 docker를 사용할 수 있도록 구성하고 실습해보았다. 오늘까지는 실무에서 쓸만한 파이프라인 스크립트를 다루어나 하지는 않았지만, 다음 포스팅부터는 정말로 쓸만한 파이프라인을 구성해서 실습해볼 것이다. 만약 위 코드가 필요하다면 아래 깃헙주소를 참고하자.

 

 

 

yoonyeoseong/jenkins_sample

Contribute to yoonyeoseong/jenkins_sample development by creating an account on GitHub.

github.com

 

posted by 여성게
:
인프라/Jenkins 2020. 3. 22. 21:15

 

오늘 다루어볼 포스팅은 간단하게 젠킨스의 빌드 시작과 성공/실패에 대한 알림을 슬랙으로 받는 방법이다. 간단해서 아주 짧은 포스팅이 될 것 같다.

 

1. Slack Jenkins CI app install

 

예제는 이미 슬랙이 설치되어있고 계정이 있다는 가정에서 진행한다. 채널을 하나 생성해준 후 밑의 Apps 버튼을 누른다.

 

젠킨스(Jenkins)로 검색하여 다운로드 한다.

 

 

알림받을 채널을 입력한다.

 

 

진행하다보면 슬랙의 Team Subdomain과 인증 token을 받을 수 있다. 이러한 데이터를 이용하여 Jenkins에서 Slack과의 연동 설정을 할것이다.

 

 

젠킨스 설정에서 이제 슬랙과 연동을 할 것이다.

 

 

플러그인 관리에서 Slack Notification plugin을 install 해준다.

 

 

이제 Jenkins 설정 > 시스템 설정 > Slack에서 방금 받은 토큰과 Team Subdomain등을 입력할 것이다.

 

 

Test Connection을 클릭 후 Success가 뜬다면 완료 ! 

 

우리는 Multibranch pipeline에서 slack notification을 받을 것이므로, Jenkinsfile에 noti관련 스크립트를 추가할 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pipeline {
    agent none
 
    environment {
        SLACK_CHANNEL = '#test_notification'
    }
 
    stages {
        stage('Start') {
            steps {
                slackSend (channel: SLACK_CHANNEL, color: '#FFFF00', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
            }
        }
 
        stage('example build') {
            steps {
                echo 'jenkins sample build ! '
            }
        }
    }
    post {
        success {
            slackSend (channel: SLACK_CHANNEL, color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        failure {
            slackSend (channel: SLACK_CHANNEL, color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
    }
}
cs

 

Start stage와 post step에 Slack noti script를 추가하였다. 한번 테스트해보자 !

 

 

와우 굿 ! 알림이 왔다. ㅎㅎ 이렇게 Jenkinsfile에 알림 스크립트를 추가하면 프로젝트마다 서로 다른 채널연결이 가능하고, 더 복잡한 조건에 대한 알림이 가능할 것이다 !

posted by 여성게
:
인프라/Jenkins 2020. 3. 21. 20:11

 

이전 포스팅에 이어 Jenkins&GitHub을 이용한 CI 실습을 다루어볼 것이다. 이번 포스팅에서는 본격적으로 실습을 진행하기 전에 아주 간단한 echo를 찍어주는 pipeline 하나를 만들어 볼 것이다. 사실 이것을 설명하는 이유는 멀티브랜치 파이프라인에 대해 조금 이해해보기 위함이다.

 

1. Multibranch Pipeline 생성

사실 우리가 개발할때, 버전관리 시스템에서 브랜치를 하나만 사용하여 개발하지 않는다. 각 회사마다의 브랜치 전략이 있겠지만 가장 대중적인 브랜치 전략은 아래와 같다.

 

  • Feature branch
  • Integration branch
  • Master branch(production branch)

이렇게 여러개의 브랜치를 가지고 개발을 진행하고 이러한 멀티 브랜치 전략에 대해 Jenkins를 이용하여 CI를 구현할때는 Multibranch Pipeline을 이용한다. 자세한 브랜치 전략은 구글링해서 참고하자 ㅎㅎ.

 

새로운 Item 메뉴를 클릭하면 다음과 같은 페이지가 보일 것이다.

 

 

item 이름을 넣고 Multibranch Pipeline을 생성해준다. 하나 설명하면 Multibranch Pipeline은 직접 스크립트를 Jenkins에서 작성하지 않고 소스코드가 있는 Github project root에 Jenkinsfile로 정의된다. Jenkinsfile은 쉽게 말하면 파이프라인 스크립트가 정의된 파일로 보면 된다.

 

Branch Sources 탭을 클릭하여 필요한 정보를 기입할 것이다. 지금은 자세한 설명보다는 파이프라인이 동작하는 것을 집중적으로 볼 것이기 때문에 정말 필요한 정보만 기입한다.

 

Repository HTTPS URL에 생성한 GitHub 레포지토리 주소를 기입한다. Discover branchesStrategyAll branches로 바꿔준다. Add 버튼을 클릭하고 Filter by name (with wildcards)를 추가한다. 그리고 Includemaster develop을 입력한다. 여기까지 작성하고 save해준다.

 

다음으로 간단하게 springboot project를 생성하고 해당 프로젝트 root에 Jenkinsfile을 생성해준다. 소스코드는 아래 깃헙 정보를 참고하자

 

 

yoonyeoseong/jenkins_sample

Contribute to yoonyeoseong/jenkins_sample development by creating an account on GitHub.

github.com

 

2. Jenkinsfile 작성

간단하게 Jenkinsfile을 작성해보자. 샘플은 위 깃헙에 있으니 내려받아도 무방하다.

 

pipeline {
    agent none

    stages {
        stage('example build') {
            steps {
                echo 'jenkins sample build ! ${AUTHOR}'
            }
        }
    }
    post {
        always {
            echo 'post process !'
        }
    }
}

 

여기까지 작성한 후 master branch를 기준으로 develop branch를 하나 딴 후에 간단히 수정 후 커밋&푸시 해보자 ! 우리는 이전 포스팅에서 "GitHub의 master와 develop 브랜치의 PR, push를 인식시킨다." 라는 설정을 넣었기 때문에 Jenkins pipeline이 돌기를 기대해야한다. 과연 파이프라인이 작동하였을까?

 

오?! 뭔가 돌았다?(필자는 테스트로 한번 더 돌려서 2개가 보인다.) #1을 클릭한 후에 정말 잘 돌았는지 Console Output을 보자 !

 

 

오호 우리가 정의한 파이프라인이 작동했다 ! 정말 신기방기하다. 정말 간단한 것이지만 여기까지 진행했다면 Jenkins&GitHub을 이용한 CI의 느낌을 어느정도 느꼈을 것이다. 그리고 조금더 감각있는 사람은 앞으로 어떠한 실습을 진행할지 예상도 될것이다. 여기까지 간단하게 멀티브랜치 파이프라인 실습을 마친다. 다음 포스팅부터는 본격적으로 실무적인 레벨의 실습을 다루어본다.

 

3. 지금까지 다룬것

 

  1. CentOS 환경에서 Docker로 Jenkins 설치
  2. Jenkins와 GitHub 연동
  3. develop branch로 수정한 후 커밋&푸시를 통해 간단한 멀티브랜치 파이프라인 동작확인
posted by 여성게
:
인프라/Jenkins 2020. 3. 21. 19:42

 

오늘 다루어볼 내용은 CI의 핵심 젠킨스(Jenkins)를 다루어볼 것이다. 사실 이번 포스팅을 시작으로 젠킨스(Jenkins) 관련 몇개의 포스팅이 더 있을 듯하다. 오늘은 간단히 CentOS환경에 docker로 Jenkins를 설치해볼 것이다. 바로 예제로 넘어간다.

 

필자는 미리 CentOS VM을 준비하였다.(사실 회사에서 장비를 맘껏 받아쓸 수 있어서 ㅎㅎ 실습용으로 생성했다.) 이번 포스팅은 CentOS가 준비되어 있다라는 가정이다.

 

1. CentOS에 Docker Engine 설치

첫번째로 Docker Engine을 설치해보자.

 

> sudo yum -y update
> sudo yum -y install docker docker-registry
> sudo systemctl start docker
> sudo docker ps
> sudo systemctl enable docker
> sudo systemctl status docker

 

위와 같은 순서로 도커엔진(docker engine)을 설치한다. 잘 설치가 되지 않거나, 혹은 다른 OS에서 실습을 진행중이라면 구글링해보자.

 

2. Docker Jenkins install

==========jenkins 공식이미지를 이용하여 jenkins 실행==========
> sudo docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -v /home/deploy/jenkins_v:/var/jenkins_home jenkins/jenkins:lts

==========jenkins 설치 후 초기 비밀번호 조회==========
> sudo docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword

 

도커를 이용하여 젠킨스를 띄웠고 초기 비밀번호까지 획득했다면 8080포트로 접속해보자.

 

 

위와 같이 초기 비밀번호를 입력하는 창이 나온다. 아까 받아놓은 초기 비밀번호를 입력한다.

 

 

아마 사내인프라인 경우 위와 같이 offline이라고 뜰것이다. 젠킨스는 다양한 플러그인 설치 때문에 꼭 외부와 통신할 필요가 있다. 사내에 존재하는 proxy server를 이용하여 proxy 설정을 하자 !

 

 

Install suggested plugins를 눌러 필요한 플러그인을 모두 설치해준다. 플러그인이 모두 설치되었다면 이제 접속을 위한 인증정보를 작성해야한다.

 

 

모든 정보를 기입한 후 로그인해서 젠킨스 대시보드에 접속해보자 !

 

 

필자가 미리 만들어 놓은 Job을 제외하고는 거의 비슷한 화면이 떴을 것이다. 여기까지 젠킨스 설치가 완료되었다. 도커의 위대함을 다시 한번 느끼게 되는 실습이다. 만약 도커가 아니었다면 젠킨스 설치에 더 복잡한 프로세스가 있었을 것이다. 

 

3. Jenkins&Github 연동

이 포스팅의 최대 목표는 Jenkins를 이용한 CI 구성이다. 대부분 버전관리시스템은 git을 많이 이용하기 때문에 Jenkins&Github 연동을 통해 Jenkins pipeline을 구성할 것이다. 여기서 주의할 점은 Github에서 webhook을 걸기 위해 꼭 Jenkins는 외부에서 접근가능한 형태의 Domain 혹은 IP를 가지고 있어야한다. 만약 여기까지 문제없다면 바로 다음 실습을 진행한다.

 

첫번째로 Github 계정 정보를 넣어준다.

 

Credintials > System > Global credentials (unrestricted) click > Add Credentials 까지 들어온다.

 

kind는 Username with password로 하고 Username, Password 등 정보를 Github 로그인정보와 동일하게 기입해준다. 다음으로 Jenkins 설정 > 시스템 설정 메뉴로 들어와서 Github tab으로 이동한다.

 

 

고급 탭을 누른다. 고급탭을 누르면 Additional actions 탭이 생겼을 것이고 Manage additional Github actions를 눌러 Convert login and password to token을 눌러 우리가 넣었던 Github 인증 정보를 선택한다.

 

 

그런 다음 Create token credentials를 눌러 토큰을 생성해준다.

 

 

이제 Github에 접속하여 Generate된 토큰을 확인하자.

 

Settings > Developer settings > Personal access tokens 메뉴로 들어가면 우리가 Jenkins에서 생성한 token 정보가 보일 것이다.

 

 

다시 Jenkins설정 > 시스템 설정 > GitHub 탭으로 돌아가서 GitHub Server 정보를 입력하자. Name은 편한이름을 넣으면 되고, API URLhttps://api.github.com을 입력하자. 여기서 주의할 것은 혹시나 사내에서 GitHub 엔터프라이즈 버전을 사용한다면 API URL을 자체적으로 가지고 있으니 그것을 입력한다. 마지막으로 Credentials는 방금 생성한 토큰정보로 입력해준다.

 

모든 입력이 끝났다면 Test connection 버튼을 눌러보자!

 

 

여기까지 완료되었다면 Jenkins&Github 연동이 완료되었다. 조금 긴 글이었기 때문에 여기서 한번 끊고 다음 포스팅에서 이어서 Jenkins와 Github을 이용한 CI 실습을 이어나가겠다.

posted by 여성게
: