** 시작 전에 젠킨스의 SSH Server의 IP가 정확하게 입력되어 있는지 확인하자.
대시보드 -> Jenkins 관리 -> System -> SSH Servers

Jenkins의 Pipeline 기능을 알아보기 전에 직전 포스팅에서 CI/CD 자동화 파이프라인을 구축한 적이 있다.
Jenkins를 이용한 CI/CD 자동화 파이프라인 구축하기
그때 기억을 상기 시켜 하나의 예제를 먼저 실행해보려고 한다.
DevOps 관련 포스팅을 계속 하면서 많은 JOB을 생성하였다.
예를 들어 첫 번째 만들었던 My-First-Project,My-Second-Project, My-Third-Project가 있다.
My-First-Project에서는 단순 Echo 메시지를 출력해 보는 작업을 했고, My-Second-Project에서는 Git에 있는 코드를 가져와 Maven 빌드를 하는 작업을 진행헤보았고, My-Third-Project Git에 있는 프로젝트를 가져와서 Maven 빌드가 끝난 다음에 패키징 되어 있는 결과 값을 Tomcat 웹 서버에 배포하는 작업의 예제였다.

My-First-Project의 설정에 들어가면 하단에 빌드 후 조치라는 항목이 있다.
Build other projects 빌드할 프로젝트 명에 My-Second-Project를 지정한다.

동일하게 My-Second-Project의 설정에 빌드 후 조치에서 Build other projects를 선택해 준 뒤 My-Third-Project를 지정해준다.
이때 빌드 후 발생할 수 있도록 둘 다 Trigger only if build is stable을 체크해줘야 한다.

.\bin\startup\bat
로컬에 있는 Tomcat 웹 서버에 배포하는 작업이 포함되어 있기 때문에 빌드 실행 전에 Tomcat 서버를 켜줘야 한다.
Tomcat 웹 서버 설치 및 설정사항과 실행은 아래 포스팅을 참고하면 된다.

My-First-Project에서 지금 빌드를 클릭하면 연쇄적으로 Secound와 Third가 빌드가 이루어진다.

localhost:8088
Tomcat 웹 서버에 들어가 Manager App에 들어가 설정했던 정보를 바탕으로 로그인을 한다.


/hello-world라고 되어 있는 어플리케이션이 잘 배포된 것을 확인할 수 있다.
작업했던 이 내용을 플러그인 Jenkins의 Pipeline을 추가하여 시각화 시켜보는 작업에 대해서 살펴보자.
먼저 플러그인이 설치되어야 한다.

대시보드 -> Jenkins 관리 -> Plugin -> Available plugins 로 들어가 Delivery PIpeline라고 검색을 한다.

사용할 수 있도록 설치를 진행한다.

설치가 끝났다면 대시보드 -> My Views 로 들어가면 All 옆에 + 버튼이 있는데 이를 클릭하면 새로운 뷰를 만들 수 있다.

이름은 My-First-Pipeline-View라고 적어주었고, 타입은 방금 설치한 Delivery Pipeline을 사용하기 위해 첫 번째 타입을 선택해주었다.


Create 버튼을 클릭하면 다음 설정 화면이 나오는데, 맨 하단으로 내려가면 Component를 추가하는 메뉴가 나온다.
컴포넌트 이름에 My-Pipeline 이라고 이름을 입력하였다.
다음에 초기 실행할 수 있는 JOB의 이름을 고를 수 있는데 여기에 My-First-Project를 선택하였다.

그렇게 생성해 주면 My-First-Pipeline-View라는 새로운 뷰를 확인할 수 있다.
해당 뷰에서는 My-First-Project에서부터 시작되어 있는 히스토리가 확인이 가능하다.

My-First-Project를 다시 실행해보자

My-First-Pipeline-View를 확인해보면 9번째 빌드가 실행되며 진행사항을 가시적으로 보여준다.

그 동안 아이템이라는 프로젝트 타입에다가 빌드하고자 하는 소스 코드를 가져오고, 빌드하는 방식을 선택하고, 빌드한 결과물을 배포하고자 하는 서버를 구성을 했었다.
이번에는 Pipeline이라는 프로젝트를 이용해서 다이내믹하게 원했던 형태로 스크립트를 만들어서 제공하는 방식에 대해서 살펴보자.
Jenkins의 Pipeline 프로젝트는 크게 두가지 형태로 작성하실 수가 있다.
첫 번째 방식은 Declarative, 두 번째 방식은 Scripted 이다.
Scripted 는 Groovy라는 언어를 기본적으로 사용하며 자체 스크립트 언어 타입인 DSL(Domain Specific Language) 사용하도록 되어 있다.
둘의 차이점은 다음과 같다.
처음에 시작했을 때 유효성을 검사하는지 여부
Declarative: 실행 도중 실패하면 다음 단계 진행 X
Scripted: 실행 도중 실패해도 다음 단계 계속 수행 O
pipeline {
agent any
//agent: Master와 Slave 중 어떤 서버에 Jenkins를 실행할지 지정
//any: 어떠한 서버도 상관없이 실행하겠다는 뜻
stages {
//stages: 구성하고자 하는 각각의 단계
stage('build') {
//
}
stage('test') {
//
}
stage('deploy') {
//
}
}
}
agent: Jenkins 서버를 기동을 할 때 마스터 서버와 슬레이브 서버로 구성이 가능하다.
멀티노드로 구성할 수 있는데, 어떤 서버에다가 Jenkins를 실행할 것인지 지정을 할 수 있다.
any라는 것은 Jenkins 서버 중에서 어떠한 서버도 상관없이 실행하겠다는 뜻이다.
stages : 구성하고자 하는 각각의 단계를 넣을 수 있다.
위 예제는 build 다음에 test, deploy 단계에 필요한 코드를 가지고 각각 순차적으로 진행될 수 있도록 파이프라인을 구성했다.

Declarative 방식을 가지고 간단하게 스크립트를 만들 것이다.

새로운 파이프라인 프로젝트를 생성해보자.
이름은 My-first-Pipeline이라고 적고, Pipeline 항목을 선택 후 OK를 눌러준다.

맨 밑으로 이동하면 Pipeline Script라는 항목이 있다.
이 밑에 스크립트 내용을 기술하면 된다.
pipeline {
agent any //현재 Jenkins 마스터 한대만 가지고 있으므로 any라고 적어준다.
stages { //4가지 stage 기술
//각각의 stage에 간단하게 echo 문장말 출력해보는 예제
stage('Compile') {
steps {
echo "Compiled successfully!";
}
}
stage('JUnit') {
steps {
echo "JUnit passed successfully!";
}
}
stage('Code Analysis') {
steps {
echo "Code Analysis completed successfully!";
}
}
stage('Deploy') {
steps {
echo "Deployed successfully!";
}
}
}
}
Apply 후 저장을 한 뒤에

지금 빌드를 눌러 빌드를 시작해준다.

빌드가 되면 각각의 스테이지가 항목이 시각화되서 표시가 된다.
각각의 단계마다 어느 정도 시간이 소요가 됐는지 표시가 된다.

컴파일이라고 되어있다 항목을 선택하면 상단에 Success라는 결과가 보이고 logs라는 버튼을 클릭하면 상단에 로그 메시지를 확인할 수 있다.

콘솔을 확인해보면 단계 별로 진행한 명령어와 결과 화면 등을 확인할 수 있다.

스크립트에 post라는 항목을 추가해보자
post는 성공적으로 빌드가 되었을 때 또는 실패가 되었을 때 어쨌든 빌드가 완료되었을 때 어떤 작업을 진행할 것인지 출력해주는 문장이다.
pipeline {
agent any
stages {
stage('Compile') {
steps {
echo "Compiled successfully!";
}
}
stage('JUnit') {
steps {
echo "JUnit passed successfully!";
}
}
stage('Code Analysis') {
steps {
echo "Code Analysis completed successfully!";
}
}
stage('Deploy') {
steps {
echo "Deployed successfully!";
}
}
}
post { //빌드가 완료되었을 때 어떤 작업을 진행할 것인지 출력
always { //항상 출력
echo "This will always run"
}
success { //성공 시
echo "This will run when the run finished successfully"
}
failure { //실패 시
echo "This will run if failed"
}
unstable { //부분 실패 시
echo "This will run when the run was marked as unstable"
}
changed { //변경 사항 발생 시
echo "This will run when the state of the pipeline has changed"
}
}
}
Apply 후 저장한 뒤

빌드를 실행해 준다.

다음에 제일 마지막에 보면 Declarative: Post Actions가 추가되었다.
로그를 봤을 때 첫 번째 언제나 출력된다는 문장 Always가 출력이 되고, 그 밑에 Success에 해당하는 문장이 출력된 것을 확인할 수 있다.

전체적인 문장을 콘솔에서 확인 가능하며 방금 언급한 Always와 Success 관련 문장도 함께 출력된다.

이번에 실행할 Pipeline 예제는 자체적으로 만들었던 Script 말고, 외부에 있는 Git의 코드를 가지고 와서 스크립트 에러를 실행해 볼 수 있는 예제로 생성해보자.
Shell Script를 실행할 때 필요한 Git을 가져오는 코드를 어떻게 작성해야 되는지 모른다고 했을 경우에, 위 오른쪽 그림처럼 Pipeline Syntax를 이용해서 Git에 접속을 해서 코드를 가져올 수 있는 파이프라인 스크립트를 자동으로 생성할 수 있다.

현재 도커에서 실행 중인 Jenkins 서버는 리눅스 환경에서 가동중이기에 실행하고자 하는 스크립트 파일은 sh 로 실행하면 된다.
최종 결과를 오른쪽 그림처럼 각각의 stage 별로 지정했던 echo 문장과 shell 스크립트 안에 포함되어 있는 명령어가 실행되는 걸 확인할 수 있다.
shell 스크립트 안에는 현재 날짜와 시간을 이렇게 출력하는 예제로 구성되어 있다.
사용할 Git주소
https://github.com/joneconsulting/jenkins_pipeline_script
위 Git 주소로 이동하면 위와 같은 파일들이 존재한다.
이 중에 sh 파일을 사용할 건데, sh 파일엔 위와 같이 echo 명령어를 현재 날짜을 출력할 수 있는 date 변수를 사용하고 있다.

새로운 Pipieline 프로젝트를 만들기 위해 대시보드 -> 새로운 Item을 클릭한다.
이름은 My-Secound-Pipeline, 그리고 Pipeline을 선택한 후 OK 버튼을 클릭해준다.

Pipeline script에선 Git에서 가져오는 코드를 스테이지에다가 지정을 해 주어야 한다.
그 코드를 문법적인 걸 다 알기가 어렵기 때문에 Pipeline Syntax를 클릭한다.

콤보박스에서 git:Git을 선택하고

어느 Repository에서 가져올지 Github 주소와 Branch는 master를 선택해준다.
작성이 끝났으면 Generate Pipeline Script를 클릭하면 git 명령어가 만들어진다.
해당 명령어를 복사하여

Script로 돌아와 stage 항목의 steps에 붙여넣는다.
pipeline {
agent any
stages {
stage('Git clone') {
steps {
git 'https://github.com/joneconsulting/jenkins_pipeline_script';
}
}
stage('Compile') {
steps {
echo "Compiled successfully!";
sh './build.sh'
}
}
stage('JUnit') {
steps {
echo "JUnit passed successfully!";
sh './unit.sh'
}
}
stage('Code Analysis') {
steps {
echo "Code Analysis completed successfully!";
sh './quality.sh'
}
}
stage('Deploy') {
steps {
echo "Deployed successfully!";
sh './deploy.sh'
}
}
}
post {
always {
echo "This will always run"
}
success {
echo "This will run when the run finished successfully"
}
failure {
echo "This will run if failed"
}
unstable {
echo "This will run when the run was marked as unstable"
}
changed {
echo "This will run when the state of the pipeline has changed"
}
}
}
완성되었다면 Apply 후 저장해준다.

빌드를 실행해주면 파이프라인이 자동으로 실행된다.

메시지도 정상 출력되는 것을 확인할 수 있다.

Maven build 를 enkins Pipeline에 추가시키기 위해 새로운 아이템을 추가해주자.
이름은 My-Third-Pipelin이고 Pipeline 항목을 클릭해준 뒤 OK를 누른다.

Pipline Script 부분을 내려가 Script를 작성해준다.
pipeline {
agent any //agent는 any
tools { //Tools 항목을 입력
maven 'Maven3.8.5' //Maven 버전 입력
}
stages { //stage는 2가지
stage('github clone') {
//첫 번째 stage는 Git에서 코드를 가져오는 부분
}
stage('build') {
//두 번째 stage는 Git에서 가져왔던 코드를 빌드하는 작업
}
}
}
여기서 중요한건 tools에 maven 버전을 입력해주었는데, 해당 버전을 사용하기 위해서는 젠킨스 관리에서 등록되어진 버전을 명시해줘야 한다.

대시보드 -> Jenkins 관리 -> Tools로 이동해 맨 하단으로 내려가면 Maven에 대한 설정을 확인할 수 있다.
여기에 스크립트에 적었던 버전과 똑같이 이름을 Maven3.8.5라고 적고, Version 또한 3.8.5을 선택해준다.

Git에서 가져올 수 있는 코드를 입력할 때 문법에 맞게 작성해야 함으로 Pipeline Syntax를 클릭하고


git Git를 박스에서 선택해주고, 사용할 Git 주소와 Branch는 Repository 상황에 맞게 main인지 master인지 등 선택해준다.
작성이 끝나면 Generate Pipline Script를 클릭하면 생성되는 코드를 복사한다.

복사한 코드를 github clone 스테이지의 스탭에 붙여넣어주고,
build 시 실행될 shell 스크립트를 작성해주었다.
pipeline {
agent any
tools {
maven 'Maven3.8.5'
}
stages {
stage('github clone') {
steps {
git branch: 'main', url: 'https://github.com/joneconsulting/cicd-web-project.git';
}
}
stage('build') {
steps {
sh '''
echo build start
mvn clean compile package -DskipTests=true
'''
}
}
}
}

Apply후 저장을 눌러준 뒤 빌드하면 정상 실행되는 것을 확인할 수 있다.


직전에 만든 My-Third-Pipeline 프로젝트에 Script를 추가 기입하여 Tomcat 서버에 배포하는 작업을 해보자.
My-Third-Pipeline 의 구성으로 들어가 Pipeline Script를 추가한다.
pipeline {
agent any
tools {
maven 'Maven 3.8.5'
}
stages {
stage('github clone'){
steps {
git branch: 'main', url: 'https://github.com/10000JI/cicd-web-project'
}
}
stage('build'){
steps {
sh '''
echo build start
mvn clean compile package -Dskiptests=true
'''
}
}
stage('deploy'){
steps{
}
}
}
}
steps에 Tomcat 서버에 배포하기 위한 스크립트를 적어줘야 하는데 문법적인 요소를 모를 수 있으니 Pipeline Syntax를 선택한다.

Sample Step 박스에 deploy: Deploy war/ear to a container 메뉴를 선택한다.
위 항목을 선택하면 어떤 파일을 어떤 서버에다가 배포할 것인지 선택할 수 있다.
첫 번째 WAR/EAR files 에 war란 파일을 쓸 것이기 때문에 **/*.war을 적는다.
이는 현재 가지고 있는 디렉토리에서 모든 디렉토리 중에서 war 확장자로 끝나는 파일이 대상이라는 뜻이다.
그 밑에 Container를 추가하도록 되어 있는데, 필자는 Tomcat 9.x버전을 선택해주었다.
그리고 Credentials 부분에 앞서 이전 포스팅에서 추가했던 deployer 계정이 있다.
deployer 계정을 선택해주고, Tomcat URL은 현재 사용하고 있는 톰켓 서버의 IP주소를 확인하고 적어주면 된다.
기입이 끝나면 Generate Pipeline Script을 클릭해 만들어진 코드를 복사한다.

그리고 step 자리에 그대로 붙여넣어주면 된다.
pipeline {
agent any
tools {
maven 'Maven 3.8.5'
}
stages {
stage('github clone'){
steps {
git branch: 'main', url: 'https://github.com/10000JI/cicd-web-project'
}
}
stage('build'){
steps {
sh '''
echo build start
mvn clean compile package -Dskiptests=true
'''
}
}
stage('deploy'){
steps{
deploy adapters: [tomcat9(credentialsId: 'deployer_user', path: '', url: 'http://172.30.1.52:8088')], contextPath: null, war: '**/*.war'
}
}
}
}

톰켓 서버를 열어 현재 존재하는 애플리케이션 목록을 확인하고

빌드를 정상적으로 진행되었다면

/hello-world라는 애플리케이션이 생성되는 것을 확인할 수 있다.

여기서도 만들었던 My-Third-Pipeline 프로젝트에 Script를 추가 기입하여 Docker 컨테이너 배포하는 작업을 해보자.
pipeline {
agent any
tools {
maven 'Maven 3.8.5'
}
stages {
stage('github clone'){
steps {
git branch: 'main', url: 'https://github.com/10000JI/cicd-web-project'
}
}
stage('build'){
steps {
sh '''
echo build start
mvn clean compile package -Dskiptests=true
'''
}
}
stage('deploy'){
steps{
deploy adapters: [tomcat9(credentialsId: 'deployer_user', path: '', url: 'http://172.30.1.52:8088')], contextPath: null, war: '**/*.war'
}
}
stage('ssh publisher'){
steps {
}
}
}
}
이번 stage는 ssh 명령을 이용해서 완성되어진 결과 파일을 도커 서버에다가 보내는 것이기 때문에 ssh publisher라고 stage 명을 입력하였다.
step에 코드를 작성하기 위해 Pipeline Syntax를 클릭한다.

Sample Step에 sshPublisher : Send build artifacts over SSH를 선택한다.
SSH Server는 docker-server를 선택해주었고, Source files엔 target/*.war, Remove prefix는 target, Remote directory는 .을 입력해주었다.
Exec command는 도커 빌드 명령어,docker build --tag 10000ji/devops_exam1 -f Dockerfile .을 입력해주었다.
참고로 필자는 본인 계정명으로 devops_exam1이라는 이름의 이미지를 만들겠다고 적었다.

입력이 끝나면 Generate Pipeline Script를 클릭해 코드를 복사한다.

pipeline {
agent any
tools {
maven 'Maven 3.8.5'
}
stages {
stage('github clone'){
steps {
git branch: 'main', url: 'https://github.com/10000JI/cicd-web-project'
}
}
stage('build'){
steps {
sh '''
echo build start
mvn clean compile package -Dskiptests=true
'''
}
}
stage('deploy'){
steps{
deploy adapters: [tomcat9(credentialsId: 'deployer_user', path: '', url: 'http://172.30.1.52:8088')], contextPath: null, war: '**/*.war'
}
}
stage('ssh publisher'){
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'docker-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'docker build --tag 10000ji/devops_exam1 -f Dockerfile .', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '.', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/*.war')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
복사한 코드를 steps에 붙여넣는다.
Apply하고 저장한 뒤에

지금 빌드를 눌러 실행해준다.

콘솔을 확인해보니 정상적으로 빌드가 완료되었고

docker-server에 이미지도 만들어진 것을 확인할 수 있다.