Kubernetes 환경에서 Jenkins 파이프라인으로 CI를 수행하도록 구성한 Jenkinsfile 정리
Jenkins와 GitLab이 같은 K8S에 있는 환경인 가정하에 유효
Python, PHP처럼 애플리케이션 빌드 과정이 필요 없는 인터프리터 언어 기반인 경우에 유효
1. Kubernetes Pod 템플릿
Jenkins 에이전트를 파드 단위로 생성하는 파드 템플릿 정의
docker, dind 컨테이너로 구성
docker-daemon컨테이너는 Docker in Docker(DIND)를 사용해서 도커 데몬 실행
workspace-volume와docker-socket볼륨 공유hostNetwork: true설정으로 파드의 컨테이너가 호스트 노드(현재 워커 노드)의 네트워크 네임스페이스를 사용할 수 있도록 설정hostAliases설정으로 사설 IP로 GitLab 서버에 접근할 수 있도록 설정
1 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 46agent { kubernetes { yaml """ apiVersion: v1 kind: Pod spec: serviceAccountName: jenkins hostNetwork: true hostAliases: - ip: "<마스터 서버 사설 IP>" hostnames: - "registry.<도메인>" - "gitlab.<도메인>" containers: - name: docker image: docker command: - sleep args: - 99d tty: true volumeMounts: - name: workspace-volume mountPath: /home/jenkins/agent - name: docker-socket mountPath: /var/run - name: docker-daemon image: docker:dind securityContext: privileged: true env: - name: DOCKER_TLS_CERTDIR value: "" args: - --insecure-registry=registry.<도메인>:8080 volumeMounts: - name: docker-socket mountPath: /var/run volumes: - name: workspace-volume emptyDir: {} - name: docker-socket emptyDir: {} """ } }
2. Environment
Jenkinsfile에서 사용될 전역 환경 변수 정의
GITLAB_REGISTRY: GitLab Registry 주소GITLAB_TOKEN: Jenkins Credentials에 저장된 GitLab 토큰
1 2 3 4 5 6 7 8environment { APP_NAME = "<앱 이름>" RELEASE = "1.0.0" GITLAB_REGISTRY = "registry.<도메인>:8080" GITLAB_TOKEN = credentials('<credentials 이름>') IMAGE_NAME = "${GITLAB_REGISTRY}/root/${APP_NAME}" IMAGE_TAG = "${RELEASE}-${BUILD_NUMBER}" }
3. Stages
Stage 1
- SCM에서 소스코드 체크아웃
- SCM의 url은 K8S Service의 FQDN으로 사용
1 2 3 4 5 6 7 8 9 10 11 12stage("Checkout from SCM") { steps { script { sh 'pwd' sh 'ls -al' git credentialsId: '<credentials 이름>', url: 'http://gitlab-webservice-default.gitlab.svc.cluster.local:8181/root/<리포지토리명>.git', branch: 'main' sh 'ls -al' } } }Stage 2
- Docker 이미지 빌드
- DinD 컨테이너에서 이미지 빌드 및 태그 추가
1 2 3 4 5 6 7 8 9 10 11 12stage('Build Docker Image') { steps { container('docker') { script { sh 'pwd' sh 'ls -al' sh 'docker build --no-cache -t ${IMAGE_NAME}:${IMAGE_TAG} .' sh 'docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:latest' } } } }- Docker 이미지 빌드
Stage 3
- GitLab Registry 이미지 푸시
- GitLab Container Registry에 로그인 후 이미지 푸시
GITLAB_TOKEN환경변수에서 주입받은 credential로GITLAB_TOKEN_PSW,GITLAB_TOKEN_USR변수 사용 가능
1 2 3 4 5 6 7 8 9 10 11stage('Push to GitLab Registry') { steps { container('docker') { script { sh 'echo $GITLAB_TOKEN_PSW | docker login ${GITLAB_REGISTRY} -u $GITLAB_TOKEN_USR --password-stdin' sh 'docker push ${IMAGE_NAME}:${IMAGE_TAG}' // Docker 이미지 푸시 sh 'docker push ${IMAGE_NAME}:latest' // Docker 이미지 푸시(latest 태그) } } } }- GitLab Registry 이미지 푸시
4. 정리
파이프라인 종료 전 도커 리소스 정리 및 로그아웃
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17post { always { // 작업 완료 후 정리 container('docker') { script { sh 'docker logout ${GITLAB_REGISTRY} || true' sh 'docker system prune -f || true' } } } success { echo "Pipeline succeeded! Image ${IMAGE_NAME}:${IMAGE_TAG} pushed to GitLab Registry" } failure { echo "Pipeline failed!" } }
전체 Jenkinsfile
| |