- Published on
Cl/CD 배포해보기
- Authors
- Name
- zkrp
이번에는 CI/CD를 통해서 배포해보려합니다!!
이 전에 CI/CD에 대해서 글을 썻는데 CI/CD에 대해서 자세히 알고싶은 분들은 밑에 있는 링크를 참고해주세요!
CI/CD를 배포하기 전에 사전에 준비해야될게 있습니다.
1. 실습 환경 세팅
- 필수 가입/설치
- GitHub, Docker Hub, Argo CD CLI
- 쿠버네티스 클러스터 준비
- Argo CD 설치 & 초기 로그인
- GIthub Repository
- 기존에 가지고있던 서비스 , 블로그 레포등
- Dockerfile
저는 이 툴을 가지고 CI/CD를 배포할 예정입니다.
GithubAction과 ArgoCD를 사용하는 이유에 대해서 설명하겠습니다.
2. 사용한 이유
1. Github Actions
Github Actions은 GitHub에서 공식적으로 제공하는 CI/CD(지속적 통합/지속적 배포) 자동화 도구입니다.
Github Actions을 사용하는 이유를 설명하겠습니다.
- 소스코드와 파이프라인의 자연스러운 통합
- Github 저장소에 직접 워크플로우 파일을 두고, Push/Pull Request 등 Git 이벤트와 연동하여 손쉽게 자동화가 가능합니다.
- 별도의 CI 서버 없이 Github 환경 내에서 바로 구축할 수 있습니다.
- 무료
- 오픈 소스 프로젝트와 소규모 프로젝트는 충분한 무료 러너(MAC, Linux, Windows)를 제공합니다.
- 자동화 파이프라인의 유연성
- 코드 빌드, 테스트, 배포까지 하나의 Workflow로 관리할 수 있습니다.
- 여러 잡(Job) 과 단계(Step)으로 복잡한 과정도 유연하게 분리할 수 있습니다.
- 보안, 시크릿 관리의 장점
- Github Repository 수준의 Secrets 관리를 통해 민감정보를 안전하게 다룰 수 있습니다.
저는 소규모 프로젝트를 운영하고 무료라는 이유로 CI는 GithubActions을 선택하게 되었습니다.
다음은 ArgoCD에 대해서 설명하겠습니다.
2. ArgoCD
ArgoCD 는 Git 을 배포의 원천으로 사용하는 GitOps 도구 입니다.
ArgoCD를 사용하는 이유에대해서 설명하겠습니다.
Git과 Kubernetes 상태의 효율적 동기화
- Git 저장소의 선언적 배포 설정(Helm/YAML)을 Kubernetes 클러스터와 항상 일치시켜줍니다.
- Git에 변경만 푸시하면 Argo CD가 이를 감지하여 원하는 상태로 자동 반영하므로, 배포의 일관성과 신뢰성이 크게 올라갑니다.
간편적이고 직관적인 설치 및 운영
- 쿠버네티스 클러스터에 간결하게 설치할 수 있으며, 웹 UI/CLI를 통하여 간편하게 운영할수 있습니다.
- 리소스나 설정 변경의 이력 및 현재 상태를 한 눈에 볼 수 있습니다.
빠른 롤백과 빠른 배포
- 애플리케이션의 빌드 없이, 설정/리소스만 변경해서 빠르게 배포 및 롤백이 가능합니다.
- 배포 오류시 빠르게 복구할 수 있어서, 운영 리스크가 줄어듭니다.
현재 쿠버네티스 클러스터 운영 경험을 바탕으로, GitOps 방식의 자동화와 선언적 배포 관리가 중요한 상황이므로, 최적화된 도구라고 판단해서 사용하게 되었습니다.
자 이제 세팅을 시작해보겠습니다.
3. CI Setting
저는 CI 세팅하기 위해 Github Actions으로 파이프라인를 구축했습니다.
name: Build & Deploy
on:
push:
branches: [ main ]
permissions:
contents: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 1) 소스 체크아웃
- uses: actions/checkout@v4
# 2) Docker Hub 로그인
- uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 3) Docker 이미지 빌드 & 푸시
- name: Build & Push Docker Image
run: |
TAG=${{ github.sha }}
IMAGE=${{ vars.DOCKERHUB_USERNAME }}/blog:${TAG}
docker build -t $IMAGE .
docker push $IMAGE
echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV
# 4) deployment.yaml 이미지 태그 변경
- name: Update Deployment Tag
run: |
pip install yq -q
yq -i -y '.spec.template.spec.containers[0].image = "wngud1/blog:${{ env.IMAGE_TAG }}"' cd/deployment.yaml
git config user.name "gha-bot"
git config user.email "[email protected]"
git commit -am "chore: bump image to ${{ env.IMAGE_TAG }}"
git push
전체적인 워크플로우입니다.
- main 브랜치에 푸시 발생 시 자동 시작
- Github Actions 러너에서 소스코드 검사, 도커 이미지 빌드 및 Docker Hub 푸시
- Kubernetes 배포용 YAML의 이미지 태그 업데이트 & GitHub 저장소에 커밋/푸시
전체적인 워크플로우는 위와 같고 다음은 단계별로 설명하겠습니다.
- 소스 코드 체크아웃
- actions/checkout@v4
- 현재 워크플로우가 실행되는 실행 환경(Github Actions 러너)에서 코드를 가져옵니다.
- 이후 빌드/설치 작업에서 코드가 필요하므로 필수 단계입니다.
- Docker Hub 로그인
- docker/login-action@v3
- Docker 이미지를 빌드한 뒤 Docker Hub에 push를 하는 과정입니다.
- 로그인 정보는 워크플로우 변수(DOCKERHUB_USERNAME)와 시크릿(DOCKERHUB_TOKEN)으로 지정한 뒤에 사용합니다.
시크릿 설정 방법에 대해 설명하겠습니다.
- 깃허브 Repo → Settings → Secrets and variables → Actions
- Repository secrets 쪽에서
- DOCKERHUB_TOKEN 값 추가
- INFRA_REPO_TOKEN 값 추가
- Repository variables 쪽에서
- DOCKERHUB_USERNAME 값 추가
이렇게 하면 워크플로 YAML 어디서든
secrets.DOCKERHUB_TOKEN, secrets.INFRA_REPO_TOKEN, vars.DOCKERHUB_USERNAME 로 바로 쓸 수있습니다.
- Docker 이미지 빌드 및 푸시
- Build & Push Docker Image
- docker build로 현재 디렉토리의 Dockerfile 기반 이미지를 빌드합니다.
- 이후 이미지를 Docker Hub로 push 합니다.
- docker build로 현재 디렉토리의 Dockerfile 기반 이미지를 빌드합니다.
- deployment.yaml 이미지 태그 업데이트 및 커밋
- Update Deployment Tag
- pip install yq를 통해 배포 manifest(YAML) 파일을 쉽게 수정할 수 있게 도와주는 도구를 설치합니다.
- yq를 사용해 cd/deployment.yaml 파일에서 컨테이너 이미지 부분을 방금 빌드한 이미지로 교체합니다
- 변경된 내용을 새로운 커밋으로 남기고 ,github 저장소에 푸시합니다.
- pip install yq를 통해 배포 manifest(YAML) 파일을 쉽게 수정할 수 있게 도와주는 도구를 설치합니다.
위와 같은 워크플로우로 CI 파이프라인이 정상적으로 작동하면 ArgoCD가 변경된 deployment.yaml 의 이미지 태그를 감지하고, 최신 이미지를 가동으로 배포합니다.
다음은 CD(Continuous Delivery) 설정에 대해 설명하겠습니다.
4. CD Setting
- 배포 manifest(YAML) 작성
저는 CD 배포를 위해 manifest(YAML)파일을 작성했습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog-web
namespace: blog
spec:
replicas: 1
selector:
matchLabels:
app: blog-web
template:
metadata:
labels:
app: blog-web
spec:
containers:
- name: blog-web
image: wngud1/blog:0.1.9
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
ArgoCD는 이 YAML파일을 감시하여 변경되면 자동으로 배포 합니다.
- ArgoCD 초기 세팅
ArgoCD 설치 과정은 이 주제와 무관하므로 생략하겠습니다.
ArgoCD UI에 접속해서 로그인을 한뒤 New APP을 누르시면 아래와 같은 화면이 나타납니다.

아래 표는 ArgoCD에서 새 Application을 생성할 때 입력해야 하는 주요 항목과, 각각의 선택 이유를 정리한 것입니다.
실습 시에는 아래 내용을 참고하여 입력하시면 됩니다.
섹션 | 필드 | 넣을 값 / 선택 이유 |
---|---|---|
GENERAL | Application Name | blog-dev |
Project | default (추후 팀별 프로젝트 분리 가능) | |
Sync Policy | Automated 선택 + • prune ☑ • selfHeal ☑→ CD 레포에 커밋만 생기면 자동 롤링 업데이트 | |
Set Deletion Finalizer | 기본 유지 (앱 삭제 시 리소스 정리) | |
Sync Options | • Auto-Create Namespace (아직 blog NS 없으면 자동 생성)나머지는 기본 (공란) | |
Retry | 기본(Disabled) 그대로 두면 됨 | |
SOURCE | Repository URL | |
Revision | dev 또는 main (CD 레포에서 태그를 커밋하는 브랜치) | |
Path | github Deployment YAML 있는 폴더 | |
DESTINATION | Cluster | 현재 클러스터 |
Namespace | blog |
설정하면을 다하시면 다음과 같은 화면이 나타납니다.

이제 모든 준비과정이 끝났습니다. 이제 CI/CD를 배포를 시작해보겠습니다.
5. CI/CD 배포
이제 Github에서 Actions 에 들어가 Build를 시작해보겠습니다.
아래는 Github Actions에서 Build(빌드)가 정상적으로 완료된 모습입니다.

다음과 같이 빌드가 성공하면 자동으로 Deployment.yaml파일에 있는 docker Image 버전이 바뀔것입니다.

빌드와 함께 Deployment.yaml 파일 내 Docker 이미지 태그가 자동으로 갱신된 것을 확인할 수 있습니다
- 이 과정은 워크플로우에서 yq 명령어를 사용해 자동으로 이루어지기 때문에, 수동으로 YAML 파일을 일일이 수정하지 않아도 됩니다.
ArgoCD UI를 들어가 다음과 같은 화면을 볼수있습니다.

ArgoCD UI에서도 변경된 이미지 태그를 감지하여, Kubernetes 클러스터로의 자동 배포가 이루어진 모습입니다.
Sync(동기화) 상태가 정상(Synced/Healthy)이라면 CI/CD 배포 파이프라인이 원활하게 동작하고 있다는 뜻입니다.
위와 같이 Github Actions의 Build가 성공하면,
배포용 deployment.yaml 파일의 Docker 이미지 태그가 자동으로 변경된 것을 확인할 수 있습니다.
그리고 ArgoCD UI에서도 배포가 정상적으로 반영(동기화)되어 CI/CD 전체 파이프라인이 성공적으로 완료된 것을 볼 수 있습니다.
그런데 실제 운영 과정에서는 위처럼 정상적으로 배포가 완료되는 경우도 있지만, 다음과 같은 오류가 발생할수도 있습니다.

저 역시 이번 실습에서 아래와 같이 문제가 발생했는데요.
이러한 CI/CD 과정의 트러블슈팅 및 해결 방법들은 다음 게시글에서 더 자세히 다루도록 하겠습니다.