1. 아키텍처
CI 과정
① Push codes to the repository
- 애플리케이션 코드 수정 후 dockerimage repository로 git commit 및 push 한다.
② Trigger Job - build image
- dockerimage repository로 push 되면 github webhook을 통해 build image Job이 Trigger 된다.
③ Build docker container image and save it in the ACR
- build image Job을 통해 Docker Container Image가 Build 되고 해당 이미지가 Azure Container Registry에 저장된다.
④ Trigger Job - update manifest
- build image Job이 완료되면 update manifest Job이 Trigger 된다.
⑤ Update image in deployment.yaml
- update manifest Job을 통해 kubernetesmanifest repository에 저장된 deployment.yaml 파일에서 컨테이너 이미지의 버전이 이전 단계에서 새로 생성된 컨테이너 이미지의 버전으로 변경된다.
CD 과정
⑥ Sync kubernetesmanifest repo
- 쿠버네티스 내에서 Pod 형태로 동작 중인 ArgoCD는 kubernetesmanifest repository를 주기적으로 sync 하며, 쿠버네티스의 현재 상태와 kubernetesmanifest repository에 선언되어 있는 상태를 비교한다.
⑦ Deploy deployment.yaml to AKS
- 현재 상태와 deployment.yaml 내용이 다름으로 업데이트된 deployment.yaml를 기반으로 쿠버네티스에 Deploy한다.
2. 사전 구성
1) Git Repository 2개
- dockerimage repository : Application Code, Dockerfile, Jenkinsfile
- kubernetesmanifest repository: Jenkinsfile, deployment.yaml
2) Jenkins 서버
- Ubuntu 20.04 버전의 VM에 Jenkins를 설치하여 사용하였다.
- 참고 사이트: https://lilylabs.tistory.com/28
3) Azure Container Registry
- Container Image 저장을 위한 Registry로 Azure의 서비스를 사용하였다.
4) Azure Kubernetes Service
- Azure에서 제공하는 관리형 쿠버네티스인 AKS를 사용하였다.
5) ArgoCD
- AKS 내부에 Pod 형태로 ArgoCD를 구성하였다.
- 참고 사이트: https://lilylabs.tistory.com/6
3. CI 과정
① Push codes to the repository
- 애플리케이션 코드 수정 후 dockerimage repository로 git commit 및 push 한다.
② Trigger Job - build image
1) Jenkins가 설치된 서버에 Docker Engine 설치
Docker Engine 이란?
- Docker Engine은 Docker Components와 서비스를 제공하는 컨테이너를 구축하고 실행하는 기본 핵심 소프트웨어다.
- Docker Engine은 애플리케이션을 구축하고 컨테이너화하기 위한 오픈 소스 컨테이너화 기술이다.
- Docker Engine이 설치되어 있기 때문에 Jenkinsfile에서 docker.build(), docker.push() 등의 구문을 사용할 수 있다.
- Docker Pipeline | Jenkins plugin
- https://docs.cloudbees.com/docs/cloudbees-ci/latest/pipelines/docker-workflow
2) docker.sock에 대한 권한 설정
- Jenkins Agent를 구동하는 계정이 root가 아닌 일반 사용자 계정이므로 권한 설정이 필요하다.
- docker.sock 권한 변경 또는 Docker 그룹을 만들어서 사용자를 추가한다.
chmod 666 /var/run/docker.sock
Docker socket 이란?
- Docker socket 파일은 /var/run/docker.sock 에 위치한다.
- Docker socket은 기본적으로 메인 도커 데몬(프로세스)와 통신하기 위해 사용된다.
- Docker socket은 Docker API의 진입점이다.
3) Jenkins에서 Plugin 및 Credential 설정
- 참고 사이트: https://lilylabs.tistory.com/31
4) buildimage Job 생성
- Dashboard → 새로운 Item 클릭
- Item name을 'buildimage'로 입력 → Pipeline 선택 → OK 선택
- Jenkinsfile은 코드를 저장소에서 가져오는 방식으로 SCM(소스 코드 관리)과 통합된다. 코드가 변경되면 Jenkins는 Jenkinsfile을 사용하여 파이프라인이 실행된다.
- 구성에서 Pipeline 선택 후 Github Repository 정보를 입력한다.
- Definition: Pipeline script from SCM
- SCM: Git
- Repository URL: dockerimage repo URL
- Credentials: 이전 단계에서 구성한 Github용 Credential 선택
- Branch Specifier (blank for 'any'): Repository의 brach 확인 후 입력
5) Dockerimage Repository의 필수 파일 목록
a. Application Code
b. Dockerfile
- 애플리케이션을 도커 컨테이너 이미지로 빌드하기 위한 텍스트 기반의 파일이다.
- 도커 엔진에 어떤 단계로 이미지를 구축해야 하는지를 지시하며, 컨테이너가 실행될 때 어떻게 동작해야 하는지를 정의한다.
# 베이스 이미지 선택
FROM python:3.8-slim
# dockerimage repo에 있는 애플리케이션 코드를 컨테이너 내부 /app 경로에 복사
COPY . /app
# 명령어 실행
RUN pip3 install flask
# 작업 디렉토리 설정
WORKDIR /app
# 컨테이너 실행 시 실행될 명령어 설정
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
c. Jenkinsfile
- buildimage job 파이프라인 구성을 위한 파일이다.
Jenkinsfile 이란?
- Jenkinsfile은 Jenkins 파이프라인을 정의하는 파일이다.
- Jenkinsfile은 코드를 저장소에서 가져오는 방식으로 SCM(소스 코드 관리)과 통합된다. 코드가 변경되면 Jenkins는 Jenkinsfile을 사용하여 파이프라인 실행된다.
- Jenkinsfile은 두 가지 주요 문법으로 작성된다.
- Scripted 문법
- Groovy 기반의 스크립팅을 사용하여 더 복잡하고 고급 기능을 포함한 파이프라인을 작성할 수 있다.
- 명령형 스크립팅 언어를 사용하기 때문에, 특정 단계의 세부 로직을 더 자세하게 제어할 수 있다.
- Declarative 문법
- 읽기 쉽고 간단한 구문을 갖추고 있어 CI/CD 파이프라인을 쉽게 정의할 수 있도록 설계되었다.
- YAML 형식으로 작성되며, 간단한 키-값 쌍을 사용하여 파이프라인을 정의한다.
- Scripted 문법
Jenkinsfile 작성 시 참고 사이트
- Jenkins 기본 제공 환경 변수: https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
- Docker Pipeline plugin 사용 시 활용 구문: Docker Pipeline plugin (cloudbees.com)
# Scripted 문법으로 작성
node {
# 변수 선언
def app
# SCM에서 소스 코드를 체크아웃 받음
# git repository를 '/var/lib/jenkins/workspace/{job name}' 위치로 clone
stage('Clone repository') {
checkout scm
}
# dockerfile을 이용해 'myacr.azurecr.io/test-web'라는 이름으로 이미지 빌드 ({ACR 이름}/{이미지 이름})
# Jenkinsfile에서 push 할 때 이미지 태그를 설정하므로 여기선 이미지 이름만 설정
stage('Build image') {
app = docker.build("myacr.azurecr.io/test-web")
}
# ACR 주소와 앞선 단계에서 Jenkins에서 생성한 ACR credential 지정
stage('Push image') {
docker.withRegistry('https://myacr.azurecr.io', 'acr-credentials') {
# env.BUILD_NUMBER는 Jenkins의 기본 환경변수로 현재 Jenkins의 빌드 번호를 의미
# push()안에 있는 번호로 이미지 태그가 지정되어 ACR로 Push
app.push("${env.BUILD_NUMBER}")
}
}
stage('Trigger ManifestUpdate') {
# Jenkins 작업 콘솔에 메시지 출력
echo "triggering updatemanifestjob"
# 새로운 Jenkins Job을 트리거하는 명령어
# 현재 job이 끝나면 'updatemanifest' job을 trigger하고, 'DOCKERTAG'라는 이름의 env.BUILD_NUMBER 파라미터 전달
build job: 'updatemanifest', parameters: [string(name: 'DOCKERTAG', value: env.BUILD_NUMBER)]
}
}
③ Build docker container image and save it in the ACR
- 파이프라인 구성 완료 후 Jenkins에서 build image job이 끝나면 ACR에 컨테이너 이미지가 저장된다.
- 이미지 태그는 자동으로 Jenkins 빌드 번호로 구성된다.
④ Trigger Job - update manifest
1) updatemanifest Job 생성
- Dashboard → 새로운 Item 클릭
- Item name을 'updatemanifest'로 입력 → Pipeline 선택 → OK 선택
- updatemanifest Job의 Jenkinsfile에서 사용할 파라미터를 지정한다.
- buildimage Job의 Jenkinsfile에 따라 buildimage Job에서 updatemanifest Job 으로 trigger 시 DOCKERTAG 파라미터를 전달한다.
- Git(SCM)에서 updatemanifest repo의 소스 코드를 가져온다.
- 구성에서 Pipeline 선택 후 Github Repository 정보를 입력한다.
- Definition: Pipeline script from SCM
- SCM: Git
- Repository URL: kubernetesmanifest repo URL
- Credentials: 이전 단계에서 구성한 Github용 Credential 선택
- Branch Specifier (blank for 'any'): Repository의 brach 확인 후 입력
2) Dockerimage Repository의 필수 파일 목록
a. Jenkinsfile
- updatemanifest job 파이프라인 구성을 위한 파일이다.
# Scripted 문법으로 작성
node {
def app
stage('Clone repository') {
checkout scm
}
stage('Update GIT') {
script {
# credentialsId는 앞선 단계에서 Jenkins에서 생성한 github credential 값으로 설정
# withCredentials는 Jenkins Pipeline에서 사용되는 구문으로, credentials을 안전하게 처리하기 위한 방법 중 하나
withCredentials([usernamePassword(credentialsId: 'github-credentials', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
# github email
sh "git config user.email demouser@gmail.com"
# github user name
sh "git config user.name demouser"
sh "cat deployment.yaml"
# sed 명령어를 이용하여 파일 내용 수정
# deployment.yaml에서 image에 해당하는 'myacr.azurecr.io/test-web'을 찾은 후 'myacr.azurecr.io/test-web:buildimage job의 빌드 넘버'로 변경
sh "sed -i 's+myacr.azurecr.io/test-web.*+myacr.azurecr.io/test-web:${DOCKERTAG}+g' deployment.yaml"
sh "cat deployment.yaml"
sh "git add ."
# 해당 변경 사항을 commit
sh "git commit -m 'Done by Jenkins Job changemanifest: ${env.BUILD_NUMBER}'"
# 해당 변경 사항을 kubernetesmanifest repo에 push
sh 'git push https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/${GIT_USERNAME}/kubernetesmanifest-main.git HEAD:main'
}
}
}
}
b. deployment.yaml
- Azure AKS에 배포될 deployment 및 svc가 선언된 manifest 파일이다.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test-web
name: test-web
spec:
replicas: 1
selector:
matchLabels:
app: test-web
template:
metadata:
labels:
app: test-web
spec:
containers:
- image: myacr.azurecr.io/test-web:latest
name: test-web
---
apiVersion: v1
kind: Service
metadata:
name: test-web-svc
labels:
app: test-web
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: test-web
3) Pipeline 테스트
- Pipeline 구성 테스트를 위해 buildimage Job에서 ‘지금 빌드’ 를 클릭한다.
- buildimage Job의 모든 Stage가 성공적으로 끝난 것을 확인한다.
- ACR에 이미지가 성공적으로 Push 되었는지 확인한다.
- buildimage Job의 빌드 번호가 11이므로, ACR에 Push 된 이미지의 태그도 11인 것을 확인할 수 있다.
- build image job의 Jenkinsfile에 정의된 'Trigger ManifestUpdate' stage를 통해 updatemanifest Job이 Trigger된다.
- updatemanifest Job의 모든 Stage가 성공적으로 끝난 것을 확인한다.
⑤ Update image in deployment.yaml
- updatemanifest Job에 의해 kubernetesmanifest repository의 deployment.yaml 파일이 업데이트 되었는지 확인한다.
다음글
- [Devops] Jenkins, ArgoCD를 통한 CI/CD 구성 - (2) ArgoCD 구성
[Devops] Jenkins, ArgoCD를 통한 CI/CD 구성 - (2) ArgoCD 구성
1. 테스트 사전 설명 이번 글에서는 ⑥ , ⑦ 번 CD 과정을 설정하는 과정을 설명하였습니다. 전체적인 테스트 구성 및 ① ~ ⑤ CI 과정은 이전 글을 참고하시길 바랍니다. [Devops] Jenkins, ArgoCD를 통한
lilylabs.tistory.com
참고
[Devops] Ubuntu에 Jenkins 설치
1. 사전 준비 Jenkins는 Java 개발 키트의 오픈 소스 버전 응용 프로그램 으로 Java Platform의 오픈 소스 구현인 OpenJDK 11 을 설치한다. sudo apt update sudo apt install openjdk-11-jdk OpenJDK 11 설치가 완료되면 Java
lilylabs.tistory.com
[Devops] Kubernetes에 ArgoCD 설치
1. ArgoCD란? ArgoCD는 GitOps로 관리되는 Kubernetes manifests의 변경사항을 Monitoring 하며 실제 Cluster에 배포된 형태를 이와 동일하게 계속 유지시키는 역할을 한다. 애플리케이션의 상태를 Git Repository에
lilylabs.tistory.com
[Devops] Jenkins에서 Plugin 및 Credential 설정
1. Jenkins에서 Docker pipeline 플러그인 설치 Docker를 사용하여 pipeline을 구축하기 위해서는 Docker pipeline 플러그인 설치가 필요하다. 1) Dashboard → Jenkins 관리 → Plugins → Available plugins → docker pipeline 검
lilylabs.tistory.com
'Container > Devops' 카테고리의 다른 글
[Devops] CI/CD 배포 전략 - Rolling, Blue/Green, Canary (0) | 2024.03.08 |
---|---|
[Devops] Jenkins, ArgoCD를 통한 CI/CD 구성 - (2) ArgoCD 구성 (1) | 2024.03.07 |
[Devops] Jenkins에서 Plugin 및 Credential 설정 (0) | 2024.03.04 |
[Devops] Ubuntu에 Jenkins 설치 (1) | 2024.02.20 |
[Devops] VM에 Gitlab 설치 (0) | 2024.02.05 |