# Step 02. Pipeline 작성
# Get Sample Application Source
Git 예제 프로젝트 설정
Open browser and go https://vup-git.cloudzcp.io/edu99/sam-zcp-lab.git
예제 프로젝트 Checkout
Clone or download > Copy click
Eclipse > Git Repository > Clone a Git repository 클릭
URI 입력 후 Next > Next > Finish
- Import Project
Working Tree 선택 후 팝업 메뉴에서 Import Projects 선택
Finish 클릭
Project Explorer 에서 확인
실행결과
# Create Pipeline
사용되는 정보
- User ID : edu01
- Namespace : edu01
- Application Project Name = sam-zcp-lab
- 사용자 Git URL : https://vup-git.cloudzcp.io/[edu01]/sam-zcp-lab
# Development pipeline
edu01 폴더 Click
왼쪽메뉴에서 New Item Click
Inputbox에 sam-zcp-edu-99(jenkins jobname) 입력
Pipeline 선택
Pipeline에 필요한 정보 입력: Pipeline section으로 이동(Scroll down)
- Definition 선택 : Pipeline script from SCM
- SCM 선택: Git
- Repositories
- Repository URL 입력: https://vup-git.cloudzcp.io/[edu01]/sam-zcp-lab.git
- Credentials 선택: edu01/...(GIT CREDENTIALS)
- Branch to build 입력 : */master
- Repository browser 선택 : gogs
- URL 입력: https://vup-git.cloudzcp.io/[edu01]/sam-zcp-lab ( '.git' 제거, browser url )
- Script Path 입력 : jenkins-pipeline/deploy-pipeline ( Git프로젝트 Root Path기준 상대 경로 )
- 저장
# Script 작성법
jenkins-pipeline/deploy-pipeline
k8s/deployment.yaml
# 구성
Block | 내용 |
---|---|
변수정의 | 내장 변수 및 Job에 필요한 기본 변수 선언 |
환경구성 | 내부에서 사용할 Resource에 필요한 pod 정의 |
Volume 선언 | 각각의 pod에서 사용할 저장소 설정 |
Job 선언 | Git Checkout, Source Build, Docker Image build, Deploy |
# k8s manifest
- k8s/deployment.yaml 파일 수정
배포 할 Docker image 주소 변경 후 Git Remote 로 Push
...
containers:
- name: spring-boot-cicd-demo
image: vup-registry.cloudzcp.io/edu01/spring-boot-cicd-demo:develop
ports:
- containerPort: 8080
name: tomcat
...
2
3
4
5
6
7
8
- k8s/ingress.yaml 작성
외부에 서비스 노출에 필요한 Domain 정보 설정
사용자 ID 기준으로 hosts 정보 변경
(테스트용) Local hosts 파일에 IP(169.56.171.70) 등록
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: spring-boot-cicd-demo
spec:
rules:
- host: edu01.cloudzcp.io
http:
paths:
- path: /
backend:
serviceName: spring-boot-cicd-demo
servicePort: 80
2
3
4
5
6
7
8
9
10
11
12
13
14
# 변수정의
jenkins-pipeline/deploy-pipeline 파일 수정
DOCKER_IMAGE, ZCP_USERID, K8S_NAMESPACE 변경 후 Git Remote 로 Push
- label: 내부에서 사용하는 UUID
- DOCKER_IMAGE: Pipeline에서 사용할 이름. [Registry URL]/[Repository Name]/[Image Name]. Tag명은 생략하고 정의 함. Tag는 변수로 입력 받거나, 자동할당됨
- ZCP_USERID : 배포 시 사용 할 ZCP 사용자 계정.
- K8S_NAMESPACE: 배포영역의 Namespace 이름
- VERSION: 개발 단계는 develop으로 고정처리함.
// Jenkins Shared Library 적용
@Library("retort-lib") _
// Jenkins slave pod에 uuid 생성
def label = "Jenkins-${UUID.randomUUID().toString()}"
def ZCP_USERID = 'edu01'
def DOCKER_IMAGE = 'edu01/spring-boot-cicd-demo' // Harbor Project Name : edu01
def K8S_NAMESPACE = 'edu01'
def VERSION = 'develop'
// Pod template 시작
podTemplate(label:label,
// Kubernetes cluste에 배포하기 위한 secret
serviceAccount: "zcp-system-sa-${ZCP_USERID}",
...){
......
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Volume 선언 (기본값 사용)
(생략)
# Job 선언
Job의 순서가 중요함
- Git checkout
- Source Build(Maven): Public Maven Repository 접근이 안되는 경우, Jenkins에 Private Nexus 서버 설정 필요함.
- Docker Image Build: ZCP 용 Private Registry 주소를 위한 ${HARBOR_REGISTRY}는 내장된 변수로서, Public Docker Hub를 사용할 경우 생략 또는 Registry 주소를 명시적으로 지정해야함
dockerCmd.build tag: "${HARBOR_REGISTRY}/${DOCKER_IMAGE}:${VERSION}"
- Deploy: 필요한 kubectl 명령어를 반복해서 적용
kubeCmd.apply file: 'k8s/service.yaml', namespace: K8S_NAMESPACE
Script Source
@Library('retort-lib') _
def label = "jenkins-${UUID.randomUUID().toString()}"
def ZCP_USERID = 'edu01'
def DOCKER_IMAGE = 'edu01/spring-boot-cicd-demo'
def K8S_NAMESPACE = 'edu01'
def VERSION = 'develop'
podTemplate(label:label,
serviceAccount: "zcp-system-sa-${ZCP_USERID}",
containers: [
containerTemplate(name: 'maven', image: 'maven:3.5.2-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
containerTemplate(name: 'docker', image: 'docker:17-dind', ttyEnabled: true, command: 'dockerd-entrypoint.sh', privileged: true),
containerTemplate(name: 'kubectl', image: 'lachlanevenson/k8s-kubectl:v1.13.6', ttyEnabled: true, command: 'cat')
],
volumes: [
persistentVolumeClaim(mountPath: '/root/.m2', claimName: 'zcp-jenkins-mvn-repo')
]) {
node(label) {
stage('SOURCE CHECKOUT') {
def repo = checkout scm
}
stage('BUILD MAVEN') {
container('maven') {
mavenBuild goal: 'clean package', systemProperties:['maven.repo.local':"/root/.m2/${ZCP_USERID}"]
}
}
stage('BUILD DOCKER IMAGE') {
container('docker') {
dockerCmd.build tag: "${HARBOR_REGISTRY}/${DOCKER_IMAGE}:${VERSION}"
dockerCmd.push registry: HARBOR_REGISTRY, imageName: DOCKER_IMAGE, imageVersion: VERSION, credentialsId: "HARBOR_CREDENTIALS"
}
}
stage('DEPLOY') {
container('kubectl') {
kubeCmd.apply file: 'k8s/service.yaml', namespace: K8S_NAMESPACE
kubeCmd.apply file: 'k8s/ingress.yaml', namespace: K8S_NAMESPACE
kubeCmd.apply file: 'k8s/deployment.yaml', namespace: K8S_NAMESPACE, wait: 300
}
}
}
}
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 배포실행 및 확인
Git : Staged > Commit > Push
실행 : Job Menu > Build Now Click
확인 : 콘솔출력
Open Browser : http://edu01.cloudzcp.io