checkout : source control (사이트?)에서 부터 코드를 다운로드 받는다. 주로 scm을 사용한다. (checkout scm)
archiveArtifacts : 앞서 빌드된 파일들을 저장해 놓는 역할을 한다. (archiveArtifacts artifacts: '*/arget/tar', fingerprint: true)
withEnv : global 또는 특정 영역에 variable을 define하는 행동을 한다. 아래 처럼 사용 가능하다.
properties : 해당 파이프라인에서 사용 사능한 일시적 properties를 설정한다. 해당 내용은 jenkins 파이프 라인 "설정" 화면에서 "General" 탭의 "이 빌드는 매개 변수가 있습니다. (Build with Parameters)"를 사용하면 되는데, 해당 설정을 하고 나면 파이프라인 실행 이름이 기존 "Build"에서 "Build with Parameters"로 변경되고 해당 value 값을 사용자가 빌드 요청시마다 수정 할 수 있게 된다.
properties([parameters([string(defaultValue:'Hello', description:'How should I greetthe world?', name:'Greeting3'),string(defaultValue:'Hello2', description:'How should I greetthe world22?', name:'Greeting2')])])
TEST는 빌드가 완료 된 이후 junit등과 같이 테스트 후 리포트를 내놓는 부분을 말한다
테스트 된 결과를 Visualization 하게 보여 주거나 test에 대한 reportingm redording 하는 많은 플러그인을 제공 하고 있다.
https://plugins.jenkins.io/?labels=report
sh 'make check || true' 0 exit code가 항상 나오게 하는 코드로써, 특별한 행위를 하지는 않는다. 전체 적으로 환경에 대한 clear를 하는 역할로 보인다.(linux kernel 개발할때 중간 중간 넣어 주는 용도로 넣는 다는 이야기가 있다.)
junit '*/target/.xml' target 이하 떨어진 xml 파일들을 캡쳐 하는 역할이다.
currentBuild.result가 null 이란 의미는 앞서 아무런 이상 결과 값이 없다는 뜻이다.
Multibranch Pipeline
scm(여기서는 git)에서 여러개의 파이프라인을 처리하는 방법이다.
New Item > Multibranch Pipeline > Branch Source > Project Repository > Url 입력
해당 git url 에서 Jenkins 파일이 있는 branch 대상으로 자동으로 파이프라인이 생성된다.
Scan Multibranch Pipeline Triggers Periodically if not otherwise run : 일정 기간별로 scan 처리 한다.
global variable 이 추가 된다.
BRANCH_NAME : 특정 branch name 등
CHANGE_ID : full request number 등 수정 id
Docker
jenkins 파이프라인 2.5 이상은 docker를 사용 가능하다.
상위에서 소개한 ebook은 최신화 되어 있지 않다. 다음 url을 참고 하는게 좋을거 같다.
https://jenkins.io/doc/book/pipeline/docker/
Docker test
node { /* Requires the Docker Pipeline plugin to be installed */ docker.image('node:7-alpine').inside { stage('Test') { sh 'node --version' } } }
jenkins user 설정을 root로 안하는 이상 permission denied 가 날 확률이 높다.
docker user group을 만들고 해당 docker group에 사용자를 add 하여 처리 하는 것이 좋다
sudo groupadd docker
sudo usermod -aG docker $USER
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
처리 후 log out, log in을 하면 처리 완료 된다고 하지만, 나는 서버 재기동 시키고 나서야 적용 되었다.
Started by user devops Running in Durability level: MAX_SURVIVABILITY [Pipeline] Start of Pipeline (hide) [Pipeline] node Running on Jenkins in /var/lib/jenkins/workspace/example [Pipeline] { [Pipeline] sh + docker inspect -f . node:7-alpine
앞서 다운로드한 라이브러리등 캐쉬를 재 활용 하기 위해서 다음과 같이 volume을 mount 할 수 있다.
// Script // node { /* Requires the Docker Pipeline plugin to be installed */ docker.image('maven:3-alpine').inside('-v $HOME/.m2:/root/.m2') { stage('Build') { sh 'mvn -B' } } }
다중 container 처리
node { /* Requires the Docker Pipeline plugin to be installed */ stage('Back-end') { docker.image('maven:3-alpine').inside { sh 'mvn --version' } } stage('Front-end') { docker.image('node:7-alpine').inside { sh 'node --version' } } }
sidecar 처리
특정 서비스 환경을 테스트 하기 위하여 주변 환경을 우선 만들고, 해당 서비스를 테스트 하기 위한 행위를 sidecar 패턴이라고 한다.
docker에서는 다음과 같이 side car를 docker에 반영 할 수 있다.
mysql run
node { /* * In order to communicate with the MySQL server, this Pipeline explicitly * maps the port (`3306`) to a known port on the host machine. */ docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw" -p 3306:3306') { c -> docker.image('mysql:5').inside("--link ${c.id}:db") { /* Wait until mysql service is up */ sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done' sh 'ehco $USER' } } }
상위 프로세스가 진행 하는 동안은 아래와 같이 mysql container가 2개 동시에 실행 되는 것을 확인 할 수있다. 하나는 사용할 mysql 서버 이고, 다른 하나는 mysqladmin이 정상적으로 작동 하는지 확인 하는 용도의 컨테이터라고 생각하면 된다.
[devops@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfbe21f96c9a mysql:5 "docker-entrypoint..." 23 seconds ago Up 21 seconds 3306/tcp, 33060/tcp hopeful_goldwasser 541d07bced67 mysql:5 "docker-entrypoint..." 29 seconds ago
만약에 jenkins가 동작하고 있는 서버에 mysqladmin이 사용 가능하다면 상위처럼 mysqladmin 테스트용 도커를 따로 만들 필요는 없다.
상위 script를 보다보면 설명이 없는 부분이 있는데,
c ->
이 부분에 대한 설명이 없다.
groovy의 closure를 사용한 부분으로 http://groovy-lang.org/closures.html 이 url 내용을 확인 하면 된다.
결론적으로는 https://github.com/jenkinsci/docker-workflow-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/docker/workflow/Docker.groovy 이 파일의 Container 객체를 인스턴스한 객체를 뜻하는 것으로, 테스트 해본 바로는 c.id를 제외하고는 다른 정보를 얻어 올 수 없는 것으로 보인다.
> public <V> V inside(String args = '', Closure<V> body){ > docker.node { > def toRun = imageName() > if (toRun != id && docker.script.sh(script: "docker inspect -f . ${id}", returnStatus: true) == 0) { > // Can run it without registry prefix, because it was locally built. > toRun = id > } else { > if (docker.script.sh(script: "docker inspect -f . ${toRun}", returnStatus: true) != 0) { > // Not yet present locally. > // withDockerContainer requires the image to be available locally, since its start phase is not a durable task. > pull() > } > } > docker.script.withDockerContainer(image: toRun, args: args, toolName: docker.script.env.DOCKER_TOOL_NAME) { > body() > } > } > } >
>
내용을 보자면 args는 "--link ${c.id}:db" 과 대응 되며 body 이후는
{
/* Wait until mysql service is up */
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
sh 'ehco $USER'
}
이 영역으로 치환 되게 된다. 즉 body, 또는 클로저라고 불리는 영역은 해당 container 내부에서 실행 되는 영역으로 생각 하면 된다.
Dockerfile을 이용한 빌드
github에서 dockerfile을 pull 한 이후 해당 파일을 바탕으로 image를 만들고 실행을 시켜 보는 코드이다.
node {
git credentialsId: 'theyoung', url: 'https://github.com/theyoung/nginx.git' def customImage = docker.build("nodejs") /* * In order to communicate with the MySQL server, this Pipeline explicitly * maps the port (`3306`) to a known port on the host machine. */ customImage.withRun() { c -> stage('containerTest'){ sh "echo ${c.id}" } } }
결과는 다음과 같다.
Started by user devops Running in Durability level: MAX_SURVIVABILITY [Pipeline] Start of Pipeline [Pipeline] node Running on Jenkins in /var/lib/jenkins/workspace/example [Pipeline] { [Pipeline] git using credential theyoung > git rev-parse --is-inside-work-tree # timeout=10 Fetching changes from the remote Git repository > git config remote.origin.url https://github.com/theyoung/nginx.git # timeout=10 Fetching upstream changes from https://github.com/theyoung/nginx.git > git --version # timeout=10 using GIT_ASKPASS to set credentials github > git fetch --tags --progress https://github.com/theyoung/nginx.git +refs/heads/*:refs/remotes/origin/* > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10 Checking out Revision d3d0ab61b78fcf93a63fd3fe37ec07eef2b1df5d (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f d3d0ab61b78fcf93a63fd3fe37ec07eef2b1df5d > git branch -a -v --no-abbrev # timeout=10 > git branch -D master # timeout=10 > git checkout -b master d3d0ab61b78fcf93a63fd3fe37ec07eef2b1df5d Commit message: "Update Dockerfile" > git rev-list --no-walk 0faa7924ddcc35bc2e83ca15d454e2240824d33b # timeout=10 [Pipeline] sh + docker build -t nodejs . Sending build context to Docker daemon 192.5 kB
우상단 profile > settings > Access Token> Personal Access Token 발행
gitlab token jenkins 등록
Dashboard > Credentials > System > Global Credentials > Add Credentials
kind : gitlab api token (안보이면 플러그인을 재설치)
Token : gitlab access token
그외 : 아무거나
Dashboard > jenkins 관리 > 시스템 설정 > gitlab tab (없으면 플러그인 확인)
Connection name : 아무거나
Gitlab host url : http:// 부터 .com <-여기까지 (예, http://gitlab.test.com)
Credential : 상위 만든 gitlab token 선택
Test Connection 시 Success 나면 됨.
Jenkins 등록
Dashboard > Credentials > System > Global Credentials > Add Credentials
gitlab 접근용도 (아래 두개중 사용 가능한것 하나)
kind : Username with password
id&pw 입력
그외 : 아무거나
ssh-keygen을 사용해야 하는 부분인데 테스트를 안해봐서 일단 pass
kind : SSH Username with private key
jenkins 프로젝트
프리스타일 선택
General : Gitlab Connection 선택 (token이 정상적으로 등록 된경우 선택 가능)
소스코드관리 : Git 선택 > Credential > username 등록한 credential 선택
빌드유발 : Build when a change is pushed to GitLab. GitLab webhook URL: http://jenkins.test.com/project/projectname
Secret token : Build when a change is pushed to GitLab. 이 설정에 속한 우하단 고급을 선택 하면, 숨겨있는 옵션을 선택 할 수있는데, 그 중에서 Secret token 을 생성하고 저장해 놓는다. (gitlab webhook에 사용된다.)
그외 : 아무거나 (gitlab web hook 만 작동 하는지 테스트 할 예정임으로 build 처리만 되면 된다.)
Gitlab 설정
gitlab > webhook 처리할 프로젝트로 이동 > setting > intergration >
Url : 상위 빌드 유발 url 입력 (http://jenkins.test.com/project/projectname)
Secret Token : jenkins에서 얻어온 Secret Token 을 넣어준다.
Enable SSL verification : 위에서 사용을 안했음으로 uncheck
add webhook : click
해당 페이지의 중간 쯤에 Webhooks (1) 라는 내용이 생기고, test 버튼을 확인 할 수있다. 이 버튼을 click 하면 jenkins가 실행 되어야 한다.
jenkins와 gitlab이 동일 서버(localhost) 라고 하면서 오류가 나면, 다음과 같이 설정을 수정해 줘야한다.