Jenkins 환경변수

Jenkins Global variable

  1. env
    : env 환경변수는 다음과 같은 형식 env.VARNAME으로 참조될 수 있다. 대표적인 env의 property는 아래와 같다.
property 이름 설명
BUILD_ID 현재 빌드의 ID이며 이는 v1.597 이상에서는 BUILD_NUMBER와 같은 값을 가진다
JOB_NAME 현재 빌드중인 프로젝트의 이름으로 foo 또는 foo/bar와 같은 형식이다.
BRANCH_NAME multibranch 프로젝트인 경우 사용할 수 있으며, 현재 빌드되고 있는 브랜치명을 알려준다
CHANGE_ID multibranch 프로젝트의 change request에 대한 change ID(PR number)를 나타낸다.
CHANGE_URL multibranch 프로젝트의 change request에 대한 change URL을 나타낸다.
CHANGE_TARGET multibranch 프로젝트의 change request에 대해 merge될 base branch를 나타낸다.
CHANGE_BRANCH multibranch 프로젝트의 change request에 대해 현재 HEAD가 가리키고 있는 브랜치 명을 알려준다. 이는 BRANCH_NAME과 같을 수 있다.
BUILD_NUMBER 현재 build number를 나타낸다.
JENKINS_URL http://server:port/jenkins/와 같은 jenkins의 URL을 알려준다.
BUILD_URL http://server:port/jenkins/job/foo/15/와 같은 현재 build의 URL을 알려준다.
JOB_URL http://server:port/jenkins/job/foo/와 같은 job의 URL을 알려준다
  1. currentBuild
    : currentBuild 환경변수는 현재 빌드되고 있는 정보를 담고있다. 보통 readonly 옵션인데 일부 writable한 옵션이 존재한다. 대표적인 currentBuild의 property는 아래와 같다.
property 이름 설명
number build number를 나타낸다.
result SUCCESS, UNSTABLE, FAILURE를 가질 수 있으며, 빌드 중에는 null이 될 수 있다. writable한 옵션이다.
currentResult SUCCESS, UNSTABLE, FAILURE를 가질 수 있으며 null이 될 수 없다.
duration 빌드에 소요되고 있는 시간을 ms단위로 나타낸다.
keepLog true이면 해당 빌드에 대한 로그 파일은 지워지지 않는다. writable한 옵션이다.
displayName 보통 #123과 같으나 writable한 옵션이다.
  1. docker
    : TBD

환경변수의 사용

이들의 사용 예는 아래와 같다.

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
            }
        }
    }
}

: Jenkins에서 환경변수를 설정할 수 있으며 이 예는 아래와 같다.

pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}
  • environment 지시어가 pipeline의 최 상단에 위치해 있으면, 이는 모든 step에 적용된다. 각 stage에 위치한 환경변수는 해당 stage에서만 적용된다.

pipeline-syntax/globals

Docker with GUI

: 도커를 사용하다 보면 GUI환경이 제공되지 않아 불편하거나 초기 GUI를 통해 무언가를 설정해야하는 경우가 있다. 이럴 때 유용한, 호스트의 GUI/sound를 공유하는 방법이다.

$ xhost +local:
$ docker run -it \\
    -v /tmp/.X11-unix:/tmp/.X11-unix \\ # mount the X11 socket
    -e DISPLAY=unix$DISPLAY \\ # pass the display
    --device /dev/snd \\ # sound
    --name jay \\
    ubuntu:16.04 /bin/bash
$ xhost -local:root

참고 링크

도커와 Host PC간 파일 전송

Host -> Container
docker cp /path/foo.txt myContainer:/path/foo.txt

Container -> Host
docker cp myContainer:/path/foo.txt /path/foo.txt

현재 OS 이미지를 Docker로 저장

: 현재 실행중인 부트 이미지를 Docker 이미지로 추출하는 방법이다.

  1. 현재 OS를 tar 파일로 묶음
    tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos6-base.tar(이름 지정) /
  2. docker 서버로 tar 파일을 복사 후 docker에 import
    cat centos6-base.tar | docker import - centos6-base(원하는 이미지 이름)
  3. import 정상 확인
    docker run -i -t centos6-base cat /etc/redhat-release

참고링크1참고링크2

docker error response from daemon no command specified 오류 발생 시

: 위와 같은 오류가 발생하는 경우는 보통 Docker 이미지의 실행 시 수행할 COMMAND가 지정되지 않아서이다. 따라서 다음과 같이 docker import --change 'CMD ["/bin/bash","-c","exec /sbin/init --log-target=journal 3>&1"]' tljh.tar myDockerName:tag CMD를 지정해주면된다.
: 위 방법으로 해결되지 않는 경우는, 발생원인이 위와는 다른 케이스이다. 나의 경우는 arm 아키텍쳐의 부팅 이미지를 Docker 컨테이너로 만들어 x86_64 아키텍쳐에서 실행하고자 하였을 때 위와 같은 오류를 접했다. 이는 Docker에 대한 이해가 부족했을 때 발생한 것이다. Docker는 어찌보면 컨테이너를 만들어 하나의 프로세스를 수행하는 것이지 가상화하는 것이 아니기때문에 다른 architecture의 부트 이미지를 돌릴수는 없다.
참고링크

'CICD > Docker' 카테고리의 다른 글

Docker - Docker 기본사항  (0) 2021.02.14

Docker 설치

: 도커의 설치는 아래 가이드를 수행하면 된다.

$ curl -fsSL <https://get.docker.com/> | sudo sh
$ sudo usermod -aG docker $USER # docker 실행 시 root 권한이 필요하므로 현재 user를 group에 추가해준다.
$ sudo service docker restart
$ sudo chmod 666 /var/run/docker.sock # /var/run/docker.sock 파일의 권한을 666으로 변경하여 그룹 내 다른 사용자도 접근 가능하게 변경

간단한 Docker 실행

  • 도커 실행은 다음 명령으로 할 수 있다. docker run --name jay ubuntu:16.04

위 명령을 실행한 후 실행중인 docker를 보면 아래와 같이 보인다.

$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS                     PORTS     NAMES
53c3dcd50980   ubuntu:16.04   "/bin/bash"               4 seconds ago    Exited (0) 3 seconds ago             jay

이렇게 Exited 상태가 된 것은 COMMAND인 /bin/bash를 수행하도록 설정되어있으므로 단순히 bash 쉘을 실행시키고 종료한다.
종료하지 않고 계속 실행중인 상태로 만들려면 docker run --name jay -it ubuntu:16.04 /bin/bash와 같이 옵션을 주면 된다.
-i는 interactively의 약어, -t는 attach to terminal 이라 생각하면 된다.

docker run 시 사용되는 옵션들은 다음과 같다.
: docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

옵션 설명
-d detached mode, 백그라운드 모드
-p 호스트와 컨테이너의 포트를 연결 (포워딩)
-v 호스트와 컨테이너의 디렉토리를 연결 (마운트)
-e 컨테이너 내에서 사용할 환경변수 설정
–name 컨테이너 이름 설정
–rm 프로세스 종료시 컨테이너 자동 제거
-it -i와 -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션
–link 컨테이너 연결 [컨테이너명:별칭]

Docker run에 대한 이해

: docker run 실행 시 docker: Error response from daemon: Conflict. The container name "/ubuntu_test" is already in use by container와 같은 에러를 발견하는 경우가 있다. 이는 docker run 명령이 "create" 와 "start" 명령을 한번에 실행시키는 명령이기 때문에 create 시 이미 동일한 이름의 컨테이너가 존재하기 때문에 발생한다. 따라서 docker rm <id or name>으로 삭제한 후 다시 실행하면 된다.
: detached 모드로 docker가 종료되지 않고 계속 실행되도록 하려면 docker run -d -it --name ubuntu_test ubuntu을 수행해주어야 한다.

도커를 처음 접할때 오는 멘붕 몇 가지

Docker Life-Cycle command

명령어 의미
run 배포 및 실행 docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=true --name mysql -v /my/own/datadir:/var/lib/mysql mysql:5.7
stop 실행 중인 Docker 컨테이너를 정지 docker stop ${CONTAINER_ID}
start 정지 중인 Docker 컨테이너를 실행  
rm 배포한 Docker 컨테이너를 삭제  
ps (-a) 실행 중인 (모든) 컨테이너를 표시  

Docker control command

명령어 의미
exec 실행 중인 컨테이너에 명령을 실행 docker exec -it mysql /bin/bash,,, docker exec nginx-vol ls -al
logs 컨테이너의 로그를 표시 docker logs ${CONTAINER_ID}
inpsect 컨테이너/이미지의 상세 정보를 표시  

Docker image-relative command

명령어 의미
images Docer 데몬에 있는 Docker 이미지 목록을 표시  
rmi Docer 데몬에 있는 Docker 이미지를 삭제 docker rmi ${IMAGE_ID}

Tips

|명령어|의미|
|---|---|
|docker rm -v $(docker ps -a -q -f status=exited)|종료 상태인 모든 Docker 컨테이너를 삭제||

Dockerfile

FROM ubuntu:latest
MAINTAINER jay <woghd8754@yonsei.ac.kr>
RUN apt-get -y update
RUN apt-get -y install valgrind
EXPOSE 80 443
CMD ["ls", "-al"]
# 1. ubuntu 설치 (패키지 업데이트 + 만든사람 표시)
FROM       ubuntu:16.04
MAINTAINER subicura@subicura.com
RUN        apt-get -y update

# 2. ruby 설치
RUN apt-get -y install ruby
RUN gem install bundler

# 3. 소스 복사
COPY . /usr/src/app

# 4. Gem 패키지 설치 (실행 디렉토리 설정)
WORKDIR /usr/src/app
RUN     bundle install

# 5. Sinatra 서버 실행 (Listen 포트 정의)
EXPOSE 4567
CMD    bundle exec ruby app.rb -o 0.0.0.0

docker build -t {tag_name} .

'CICD > Docker' 카테고리의 다른 글

Docker - GUI 설정 및 현재 부팅 이미지 이용  (0) 2021.02.14

GitHub CLI 설치 (Ubuntu)

: 다음의 절차를 차례로 수행한다. 참고링크

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key C99B11DEB97541F0
sudo apt-add-repository https://cli.github.com/packages
sudo apt update
sudo apt install gh

GitHub CLI 시작하기

GitHub 계정 연결

: gh auth login 을 입력하면 로그인할 수 있도록 Interactive CLI가 나타난다.
- Authentication token의 경우 [GitHub] - [Settings] - [Developer settings] - [Personal access token]에서 만들 수 있다.
- gh auth status 명령으로 로그인이 잘 되었는지 확인할 수 있다.



: 또는 위의 Personal access token을 이용하여 gh auth login --with-token < mytoken.txt 명령어를 통해 손쉽게 로그인 할 수 있다. Enterprise 계정의 경우 --hostname blah.blah.enterprise.GitHub.com 옵션을 사용하면 된다. 다시말해 다음의 gh auth login --hostname enterprise.internal --with-token < mytoken.txt 명령어를 사용하면 된다.

: 연결을 해제하고 싶다면 gh auth logout 명령어를 수행하면 된다.

PR 생성 및 comment 추가

: 현재 작업중인 branch에서 commit 생성 및 git push ~ 작업을 수행하였을 때, GitHub Web에서 PR을 생성할 수 있다. 하지만 GitHub CLI를 이용해 Web에서 하던 작업을 대신 해 보자.

  • gh pr create --title "Test for GitHub CLI" --base main 명령으로 PR을 생성할 수 있다.
  • gh pr list 명령을 통해 생성된 PR들의 리스트를 확인할 수 있다.
  • gh pr review --comment -b "Comment What you need" 명령으로 현재 branch에 대해 리뷰 코멘트를 남길 수 있다.
  • gh pr review 7 --comment -b "Hmm.. This is GitHub CLI" 명령으로 특정 PR Number에 comment를 남길 수 있다.




참고자료
GitHub CLI

Pipeline이란?

: Jenkins Pipeline은 CD(Continuous Delevery)를 지원하는 플러그인의 집합이다. 이 과정에서 소프트웨어를 빌드하고 여러 단계의 테스트, 배포를 진행한다. Pipeline은 Pipelie Domina Specific Language라는 문법을 통해 마치 코드를 작성하는 것과 같이 해당 기능을 제공한다. Pipeline을 사용하면 다음과 같은 이점이 있다.

  • 모든 Pull Request에 대해 Pipeline build process를 자동으로 제공한다.
  • Pipeline 선언을 코드로써 관리하여 프로젝트의 여러 구성원이 함께 보고 이해하며 편집할 수 있다.

이러한 Pipeline을 작성하는 데에는 크게 두 가지, Declarative 방식, Scripted 방식이 있으며, Declarative 방식은 Scripted방식보다 풍부한 구문 기능을 제공하며, 간편하게 작성할 수 있으며, 이해하기 쉬운 구조로 구성되어 있다.

Declarative Pipeline 기본 구조

기본 구조는 아래와 같다.

// Jenkinsfile

pipeline { // 최 상단 element로 정의되어 있어야 한다.
    agent any // pipeline 블록 내 최 상단에 정의되어야 하며, 말 그대로 실행할 Agent가 할당된다. 여기서 'any'는 사용가능한 어떠한 agent로도 실행해도 된다는 걸 나타낸다. 이는 pipeline 아래 위치해도 되고 각 stage 블록에 위치해도 된다.
    options {
        skipStagesAfterUnstable()
    }
    stages {
        stage('Build') { // stage는 Pipeline의 단계를 나타낸다.
            steps { // 해당 stage에서 실행할 명령을 기술하는 부분이다.
                sh 'make' // 주어진 shell 명령을 수행한다.
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml' // junit 플러그인을 통해 제공하는 기능으로, 테스트 보고서를 집계한다.
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
}

여기서 agent에 들어올 수 있는 parameter에 대해 자세히 알아보자.

agent type 설명
any 사용가능한 어떠한 agent를 써도 좋다 agent any
none pipeline 블록에 선언된 경우, 전체 파이프라인을 실행하는 동안 어떠한 global agent도 할당되지 않는다.
이 때, 각 stage 블록에 agent가 선언되어야 한다.
agent none
label 제공된 label을 이용해 파이프라인을 실행한다. agent { label 'my-defined-label' }
agent { label 'my-label1 && my-label2' }
agent { label 'my-label1 || my-label2' }
node agent { node { label 'labelName' } }agent { label 'labelName' }와 동일한 의미를 가진다.
하지만 customWorkspace와 같은 추가적인 옵션을 가질 수 있다.
agent { node { label 'labelName' } }
docker 도커 기반 파이프라인을 제공한다. docker는 아래에서 자세히 다루어 보자. -

docker

: 제공된 컨테이너를 이용해 도커 기반의 파이프라인 실행을 제공한다. 이는 args 파라미터를 이용하여 docker run 호출 시 제공할 파라미터를 줄 수 있다. 또한 alwaysPull 옵션은 이미지가 이미 존재하더라도 docker pull을 강제로 수행하도록 한다.

  • agent { docker 'maven:3-alpine' }
agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}

: docker는 추가적으로 registryUrl, registryCredentialsId 옵션을 통해 Docker Registry와 이에 필요한 Credential을 명시할 수 있도록 지원한다. registryCredentialsId 는 도커허브의 private repository를 위한 기능이다.

agent {
    docker {
        image 'myregistry.com/node'
        label 'my-defined-label'
        registryUrl '<https://myregistry.com/>'
        registryCredentialsId 'myPredefinedCredentialsInJenkins'
    }
}

dockerfile

: source repository(GitHub?)에 존재하는 Dockerfile을 이용해 pipeline을 실행한다. 이를 위해서는 JenkinsfileMultibranch pipeline 또는 Pipeline from SCM을 이용해 로딩되어야 한다. Dockerfile의 최 상단에는 agent { dockerfile true }이 정의되어 있어야 한다. dir 옵션을 통해 Dockerfile의 경로를 지정할 수 있다. filename을 통해 Dockerfile의 이름(Dockerfile이 아닌 경우)을 지정할 수 있다. additionalBuildArgs 옵션을 통해 docker build 명령에 들어가는 추가적인 인자를 지정할 수 있다.

agent {
    // Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
    dockerfile {
        filename 'Dockerfile.build'
        dir 'build'
        label 'my-defined-label'
        additionalBuildArgs  '--build-arg version=1.0.2'
        args '-v /tmp:/tmp'
    }
}

dockerfile 또한 docker와 마찬가지로 registryUrl, registryCredentialsId 옵션을 사용할 수 있다.

agent {
    dockerfile {
        filename 'Dockerfile.build'
        dir 'build'
        label 'my-defined-label'
        registryUrl '<https://myregistry.com/>'
        registryCredentialsId 'myPredefinedCredentialsInJenkins'
    }
}

Jenkinsfile 사용하기

: Jenkinsfile을 편집할 때 groovy 문법을 지원하는 에디터를 사용하면 편집에 편리하다. 그냥 파일명에 Jenkinsfile.groovy를 사용해도 무방하다. Jenkinsfile은 Make, CMake, Gradle, Maven과 같은 빌드도구가 아닌 빌드 및 테스팅을 간편하게 도와주는 중간 layer라고 이해하면 된다. 아래에서 sh 명령어는 Unix/Linux 기반 시스템에서, bat 명령어는 Window기반 시스템에서 사용하면 명령어 호출 예약어이다.
: 다음은 간단한 Jenkinsfile 의 예제이다.

// Declarative Jenkinsfile

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'make' 
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
            }
        }
        stage('Test') {
            steps {
                /* `make check` returns non-zero on test failures,
                * using `true` to allow the Pipeline to continue nonetheless
                */
                sh 'make check || true' 
                junit '**/target/*.xml' 
            }
        }
        stage('Deploy') {
            when {
              expression {
                currentBuild.result == null || currentBuild.result == 'SUCCESS' 
              }
            }
            steps {
                sh 'make publish'
            }
        }
    }
}
  • archiveArtifacts는 이후에 기술된 */target/*.jar과 패턴 매칭되는 파일들을 찾아 이들을 나중에 찾아볼 수 있도록 Jenkins controller 에 저장한다.
  • currentBuild.result 변수는 파이프 라인이 테스트 실패했는지 성공했는지를 알 수 있다. fail 시의 값은 UNSTABLE이다.

Jenkins 환경 변수

: TBD
https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables

참고 링크
Jenkins pipeline
Jenkinsfile
Jenkins pipeline syntax

Jenkins pipeline 이용하기

: 이번에는 GitHub 프로젝트에 Jenkinsfile을 생성하고, 여기에 기술된 작업 절차들을 Jenkins에서 수행하도록 하는 방법으로 pipeline을 사용할 수 있습니다. 이전에 Web에서 Job들을 일일이 적용하는 작업들은 매우 번거로울 뿐 아니라, Job이 추가/변경되는 경우 Website의 해당 Item에 들어가 일일이 수정해야하므로 여간 번거로운 일이 아닐 수 없습니다. 이를 Jenkinsfile에 기술해 놓으면 수정 또한 commit을 통해 할 수 있으므로 개발자 친화적인? 작업이라 할 수 있습니다. 그럼 적용하는 방법을 살펴보겠습니다.

저는 이전의 Jenkins 시작하기에서와 같이 https://github.com/JaehongParkYS/calculator_CICD 이 프로젝트를 사용하였습니다.


Manage Plugin에 들어가 위 그림처럼 Pipeline: Declarative Agent API을 설치해 줍니다.
저는 declarative 문법을 사용할 것이므로 해당 플러그인을 설치하였습니다.


New item을 선택해 줍니다.


Pipeline을 선택해 주고 이름은 아무 이름이나 설정해 줍니다.



위 그림처럼 프로젝트 주소와 Git 주소를 설정해 주고 Credential은 이전에 만든 것을 동일하게 사용해 줍니다.
그리고 Script Path에 GitHub 프로젝트에 추가해 준 Jenkinsfile의 이름(저는 Jenkinsfile로 했습니다.)을 적어 줍니다.
Build할 branch는 모든 브랜치를 대상으로 할 것이므로 /으로 하였습니다.


Item을 정의하고 난 후 Build Now를 선택하면 위 그림과 같이 Pipeline 형태의 기술된 작업들이 수행되는 것을 볼 수 있습니다.


세부 항목을 선택해 해당 로그를 보면, Test 작업에서 수행한 작업들의 결과(저는 Gtest를 이용해 테스트를 수행해 보았습니다.)를 볼 수 있습니다.

제가 작성한 Jenkinsfile은

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh '''
                echo "Start Build"
                g++ -o main main.cpp calculator.cpp -lgtest -lpthread
                '''
            }
        }
        stage('Test') {
            steps {
                sh '''
                echo "Start Test"
                ./main
                '''
            }
        }
        stage('Archive') {
            steps {
                sh '''
                echo "Start Archiving"
                mv ./main ./artifact/
                '''
                archiveArtifacts artifacts: 'artifact/*', fingerprint: true 
            }
        }
    }
}

입니다.
위 기술된 항목들에 대한 설명은 다음 페이지에서 이어나가겠습니다.

'CICD > Jenkins' 카테고리의 다른 글

Jenkins - 환경변수 사용  (0) 2021.02.24
Jenkins pipeline - Declarative pipeline 기술  (1) 2020.11.17
Jenkins - GitHub 연결(2)  (0) 2020.11.12
Jenkins - 젠킨스 설정(1)  (0) 2020.11.12

Github 프로젝트와 Jenkins 연동

해당 프로젝트를 진행하기 위하여 저는 다음의 주소에 있는 프로젝트를 사용하였습니다.

https://github.com/JaehongParkYS/calculator_CICD

 

  1. Global Tool Configuration

    : 여기서는 자신이 빌드할 프로젝트에서 필요한 환경(Maven, JDK, Gradle, Git, etc.)을 구성합니다. 저는 C/C++ 이므로 Git만 설정하면 되는데 이미 설정이 되어있어 Pass 합니다.

 

  1. Plugin 설정

    : 필요한 Plugin들을 설치합니다. Git, Github관련 Plugin들은 Install suggested plugins에 포함되어있어 추가적으로 설치할 필요는 없습니다.

저는 Docker Plugin을 설치해 주었습니다.

설치된 플러그인들은 다음의 페이지에서 확인할 수 있습니다.
http://localhost:8754/updateCenter/

 

  1. Github 설정

위 설명대로 들어온 후 해당 git에 접속할 수 있는 token을 발급해 줍니다.

본인의 의도에 맞게 token에 access 권한을 부여해 줍니다.

스크롤을 내려 GitHub 란에서 Add 버튼을 선택해 줍니다.

위 사진과 같이 설정해 주고, Secret 란에는 GitHub에서 발급한 token을 넣어줍니다.

위 사진과 같이 생성한 Credential을 선택해 주고 Connection test를 해 봅니다.

 

  1. Github 연결

위 사진과 같이 [New Item] - [Freestyle project]를 선택해 주고 아무 이름이나 넣어 줍니다.

다음 그림과 같이 GitHub project란에 프로젝트 명(https://github.com/JaehongParkYS/calculator_CICD)을%EC%9D%84) 넣어주고, Source Code Management란에 git 주소(https://github.com/JaehongParkYS/calculator_CICD.git)를%EB%A5%BC) 넣어줍니다. 그리고 Credential 란에는

ssh-keygen -t rsa -f 파일명 명령으로 ssh 키를 만들어, .pub 확장자가 없는 파일(private 키)의 내용을 넣어 줍니다.

그 후, 다음과 같이 Build 절차와 Post-build action을 정의해 줍니다.
저는 C/C++ 프로젝트이어서 간단하게 작성하였습니다. 저장을 눌러주면 다음과 같이 Item이 생성되었습니다.

다시 GitHub의 프로젝트로 넘어와서,

위에서 ssh-keygen -t rsa -f 파일명 명령으로 만든 public key를 위 사진과 같이 GitHub 계정에 등록시켜 줍니다. 이를 통해 Jenkins와 GitHub이 사전에 정의된 키를 이용해 통신을 가능하게 합니다.

GitHub 프로젝트의 [Settings] - [Webhooks]로 넘어가 [Add webhook]을 선택한 뒤 위와 같이${Jenkins의 주소}/github-webhook/을 넣어줍니다. 저는 public 주소가 없으므로 추후 ngrok을 이용해 수정해 줄 것입니다.

 

  1. Host(Windows10)와 Guest(Ubuntu-VirtualBox)를 포트포워딩 시키기

    제 PC는 Windows10이 설치되어있어, 개발 편의를 위해 VirtualBox에 Ubuntu20.04를 설치하였고, 이 Ubuntu에 모든 개발환경(Jenkins 포함)을 설정하였습니다.

    따라서 Jenkins 특성상 외부에서 제가 설정한 Jenkins 서버에 접속하여야 하므로, Host(Windows10)와 Guest(Ubuntu)의 특정 포트(8754)를 포트포워딩 시켰습니다.

다음 그림과 같이 HostPC의 loopback 주소(127.0.0.1)의 8754 포트를 GuestPC의 IP주소:8754 포트에 포트 포워딩 시켰습니다.


Ubuntu에서 IP 주소를 확인하기 위해서는 ifconfig 명령을 사용하면 되는데요, VirtualBox에서 설치하였다면 10.0.2.15로 고정되어 있습니다.

 

  1. ngrok을 이용해 Host PC의 특정 포트를 외부에서 접근가능하도록 public 주소 만들기

    ngrok은 다음의 주소에서 설치할 수 있습니다.

ngrok.com/download

 

ngrok - download

Running this command will add your authtoken to your ngrok.yml file. Connecting an account will list your open tunnels in the dashboard, give you longer tunnel timeouts, and more. Visit the dashboard to get your auth token.

ngrok.com

설치가 끝난 후, 저는 8754 포트를 Jenkins 접속 포트로 사용하고 있기 때문에 다음과 같이 ngrok에 명령어를 실행시켜주면


외부에서 접근할 수 있는 주소가 나타납니다.
한번 접속해 볼까요?


네, Jenkins로 포트포워딩 되어 접속이 잘 되네요.

 

그렇다면 위 GitHub 프로젝트의 [Settings] - [Webhooks]로 넘어가 [Add webhook] 다시 올바른 주소를 설정해 주도록 합시다. 그리고 나서 PR을 발생시켜보면,

위 그림과 같이 Jenkins의 Job이 생기고, PR에도 Jenkins 관련 내용이 보입니다. ^^

 

7. Build 결과물(artifact) 확인

Build 결과물은 jenkins 설치 경로에 따라서 다르므로 설치경로를 확인하는게 좋습니다.

default 경로는 /var/lib/jenkins/ 이므로 참고하시고, 해당 경로로 들어가보면 다음과 같이 빌드 결과물과, 해당 artifact를 실행해 볼 수 있습니다.

 

Jenkins 설치 (Ubuntu 20.04)

  1. JDK 설치

    apt-get update
    sudo apt-get install openjdk-8-jdk
  2. Jenkins 저장소 key 다운로드 후 sources.list에 다운로드 경로 추가 & Jenkins 다운로드

    wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
    
    echo deb http://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
    
    sudo apt-get update
    
    sudo apt-get install jenkins
  3. Jenkins 서비스 시작

    sudo service jenkins restart

이 후 Jenkins의 HTTP PORT로 설정되어있는 포트(기본 8080)에 웹 브라우저를 이용해 접속합니다.

  • http://localhost:8080
    Jenkins의 HTTP PORT는 다음의 파일을 수정하여 바꿀수 있습니다.
  • /etc/default/jenkinsHTTP_PORT=8080

페이지에 접속 후 비밀번호를 입력하는 페이지가 나오는데 비밀번호는 아래의 명령어로 확인할 수 있습니다.

  • sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Install suggested plugins 을 선택하여 플러그인을 설치합니다

관리자 계정을 생성합니다.

Jenkins 접속 URL을 설정합니다.

설정을 성공적으로 끝마치면 다음과 같은 페이지를 볼 수 있습니다.

+ Recent posts