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을 실행한다. 이를 위해서는 Jenkinsfile
이 Multibranch 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