[쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 15. ArgoCD 빠르게 레벨업-1Tech/Kubernetes(K8s)2025. 6. 17. 16:44
Table of Contents
* 본 게시물은 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2 강의와 강의 자료를 바탕으로 작성되었습니다.
Argo CD 아키텍처

- Argo CD
- k8s 전용 배포 툴 (with Git) -> Release 파일 저장소로 반드시 Git을 사용해야 함
- Image Updater (Argo CD의 부가 기능) -> Container Image 변경을 감지
- Argo Rollouts
- 고급 배포 지원 (특정 배포 전략 선택)
- Argo Events
- 이벤트 버스 아키텍처 도구 (Kafka와 유사)
- Argo Workflow
- 워크플로우 매니지먼트 도구
- 어떤 작업을 할 지에 대한 순서도로 CD를 선택하면 배포를 수행한다는 의미
아래와 같은 순서로 동작하여 배포하게 됨

Argo CD 전체적인 흐름

Argo CD를 설치하면 K8s Cluster를 구성할 때처럼 여러 Components가 설치됨
- Server
- API Server, Dashboard 역할
- UI나 argocd(tool)를 설치하여 CLI로 사용할 수도 있음
- Repo Server
- Git에 연결하여 k8s에 배포할 매니패스트 생성
- Application Controller
- k8s 리소스 모니터링
- Git에서 받은 내용과 비교하여 다르면, 배포
- Kube API
- k8s로 Resource 생성 명령
- Notification
- Argo CD에서 발생하는 이벤트를 외부로 트리거 (Ex. Slack)
- Dex
- 외부 인증 관리
- 주로, IAM 솔루션을 이용해 SSO 로그인을 할 수 있도록 해줌
(한 번 로그인하면, 다른 종류의 Dashboard도 함께 자동 로그인됨)
- Redis (Memory DB)
- Kube API와 Git에서 요청을 줄이기 위한 Cache 역할
- ApplicationSet Controller (멀티 클러스터를 위한 App 패키징 관리)
- Cluster마다 Argo CD를 설치할 수 있지만, 하나만 설치해서 여러 Cluster로 배포해야 할 경우 사용
- 중복되는 구성이 생길 수 있어, 환결 별로 다른 구성을 사용할 수 있도록 Templates를 제공
(Helm와 Kustomize의 Overlay 방식과 유사)
Argo Apps 설치 및 배포
시작하기 전에,
- Github의 Repo는 크게 3가지로 분류하는 것이 접근 유저별 권한 관리와 불필요한 코드 다운로드 방지를 위해 좋음
- App 소스 코드 Repo
- Relase 전용 Repo (배포를 위한 YAML 파일이 담김 -> Helm, Kustomize 등 포함)
- Add-on 전용 Repo (Argo CD (Helm)Package 등)
1. Artifact Hub에서 Argo Apps를 설치하기 위한 Package를 가져옴
# helm이 설치돼 있는 서버에서 작업
# helm 레포지토리(argo-cd) 설정 및 다운로드
helm repo add argo https://argoproj.github.io/argo-helm
helm pull argo/argo-cd --version 5.52.1
helm pull argo/argocd-image-updater --version 0.9.2
helm pull argo/argo-rollouts --version 2.34.1
# 압축 해제
tar -xf argo-cd-5.52.1.tgz
tar -xf argocd-image-updater-0.9.2.tgz
tar -xf argo-rollouts-2.34.1.tgz
# 내용 확인
ls argo*
2. 가져온 Apps를 Github에 업로드
업로드 후, 개인적인 설정
(실습에서는 values-dev.yaml을 따로 만들어 nodePort 30002으로 연결시키고 나머지는 기본 설정을 사용)
# 아래 경로를 참고하여 업로드
# helm package를 Github로 업로드
https://github.com/k8s-1pro/install/tree/main/ground/cicd-server/argo/helm/argo-cd
https://github.com/k8s-1pro/install/tree/main/ground/cicd-server/argo/helm/argocd-image-updater
https://github.com/k8s-1pro/install/tree/main/ground/cicd-server/argo/helm/argocd-rollouts
3. CI/CD 서버에 Package를 다운로드하여 Argo Apps를 설치할 수 있는 Jenkins Job을 생성
Jenkins Job을 이용하여 argo가 설치될 namespace와 설치를 관리
Jenkins Dashboard > New Item > pipeline 생성
// Namespace 관리를 위한 Jenkinsfile 일부
stage('네임스페이스 관리') {
steps {
script{
if (params.DEPLOY_TYPE == "namespace_create") {
withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
sh "kubectl apply -f ./${INSTALL_PATH}/kubectl/namespace.yaml --kubeconfig " + '${KUBECONFIG}'
}
} else if (params.DEPLOY_TYPE == "namespace_delete") {
withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
sh "kubectl delete -f ./${INSTALL_PATH}/kubectl/namespace.yaml --kubeconfig " + '${KUBECONFIG}'
}
} else {
echo "skip namespace"
}
}
}
}
// Argo Apps 배포를 관리하기 위한 Jenkinsfile 일부
stage('헬름 배포 관리') {
steps {
script{
if (params.DEPLOY_TYPE == "helm_upgrade") {
withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
HELM_DEPLOY_COMMAND = "helm upgrade ${params.TARGET_ARGO} ./${INSTALL_PATH}/helm/${params.TARGET_ARGO} " +
" -f ./${INSTALL_PATH}/helm/${params.TARGET_ARGO}/values-dev.yaml" +
" -n argo --install --kubeconfig " + '${KUBECONFIG}' +
" --wait --timeout=10m " // 최대 10분으로 설정
// image-updater일 경우 도커허브 credentials 주입
if (params.TARGET_ARGO == "argocd-image-updater") {
// https://argocd-image-updater.readthedocs.io/en/stable/basics/update-methods/
withCredentials([usernamePassword(credentialsId: 'docker_password', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
HELM_DEPLOY_COMMAND += " --set config.registries[0].credentials=env:DOCKER_HUB_CREDS="+ '${USERNAME}' + ":" + '${PASSWORD}'
}
}
sh "eval ${HELM_DEPLOY_COMMAND}"
// sh "helm update argo-cd -n argo --kubeconfig " + '${KUBECONFIG}' + " --wait --timeout=10m "
}
} else if (params.DEPLOY_TYPE == "helm_uninstall") {
withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
sh "helm uninstall ${params.TARGET_ARGO} -n argo --kubeconfig " + '${KUBECONFIG}'
// CRD 삭제
if (params.TARGET_ARGO == "argo-cd") {
sh "kubectl delete crd applications.argoproj.io applicationsets.argoproj.io appprojects.argoproj.io --kubeconfig " + '${KUBECONFIG}'
}
if (params.TARGET_ARGO == "argo-rollouts") {
sh "kubectl delete crd analysisruns.argoproj.io analysistemplates.argoproj.io clusteranalysistemplates.argoproj.io --kubeconfig " + '${KUBECONFIG}'
sh "kubectl delete crd experiments.argoproj.io rollouts.argoproj.io --kubeconfig " + '${KUBECONFIG}'
}
}
} else {
echo "skip deploy"
}
}
}
}
4. Argo CD 초기 설정
# Argo CD 초기 Password 확인
kubectl get -n argo secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
- 출력된 텍스트를 암호로 Arco CD에 로그인 (아이디는 admin)
- Argo CD에 접속 후, User Info에서 비밀번호 변경 가능
5. App 배포
(Argo CD Applications > New App)
- General (배포 시, 기본 옵션)
- Application Name: api-tester-2231
- Project Name(포함될 그룹 이름): default
- SYNC POLICY(리소스에 대한 변경 감지 시, 수동/자동 배포를 선택): Manual
- SYNC OPTION(배포 상세 옵션): AUTO-CREATE NAMESPACE
- 추가적인 OPTION 기능
-
더보기▶ SYNC OPTIONS
SKIP SCHEMA VALIDATION : 매니패스트에 대한 yaml 스키마 유효성 검사를 건너뛰고 배포 (kubectl apply --validate=false)
PRUNE LAST : 동기화 작업이 끝난 이후에 Prune(git에 없는 리소스를 제거하는 작업)를 동작시킴
RESPECT IGNORE DIFFERENCES : 동기화 상태에서 특정 상태의 필드를 무시하도록 함
AUTO-CREATE NAMESPACE : 클러스터에 네임스페이스가 없을 시 argocd에 입력한 이름으로 자동 생성
APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포
SERVER-SIDE APPLY : 쿠버네티스 서버에서 제공하는 Server-side Apply API 기능 활성화 (레퍼런스 참조)
▶ PRUNE PROPAGATION POLICY(리소스 삭제 시, 정책)
foreground : 부모(소유자, ex. deployment) 자원을 먼저 삭제함
background : 자식(종속자, ex. pod) 자원을 먼저 삭제함
orphan : 고아(소유자는 삭제됐지만, 종속자가 삭제되지 않은 경우) 자원을 삭제함
- Source (연동할 Git의 정보)
- Repository URL: https://github.com/ONE0x393/kubernetes-anotherclass-sprint2.git
- Revision(배포할 Tag나 Branch 지정): main
- Path(배포할 디렉터리): 2231/deploy/k8s
- Destination
- Cluster URL: https://kubernetes.default.svc
(실습에서는 Argo CD가 배포할 Cluster 내부에 속해있기 때문에, 자신이 속한 Cluster의 kube-apiserver를 가리킴 - Namespace(App을 배포할 k8s의 namespace): anotherclass-223
- Cluster URL: https://kubernetes.default.svc
5-1. Kubectl을 이용한 배포
- Source에서 지정한 Path에 YAML 파일 밖에 없으면 Destination 하단에 Directory로 설정됨
- Source에서 지정한 Path 아래 YAML 파일들을 모두 배포 대상으로 간주한다는 의미
5-2. Helm을 이용한 배포
- Source에서 지정한 Path에 Helm 파일을 포함하고 있으면, Destination 하단에 Helm으로 설정됨
- 해당 배포에서 사용할 Values 파일들을 선택할 수 있음

4. Create
아래와 같이 Application이 생성되면 성공, 생성된 아이템을 클릭하면 상세 페이지
로 진입하게 되고 현황을 볼 수 있음

5. 배포하기
- REFRESH 버튼을 눌러 Git의 최신 내용을 가져오거나, 3분을 주기로 자동으로 최신 내용을 가져옴
- SYNC 버튼을 누르면, 미리 정의한 배포 방식들이 보이며 수정 가능함 -> 한 번 더, SYNCHRONIZE 버튼을 클릭하면 배포가 진행

배포가 완료되면, 초록색으로 변하여 시각적으로 확인 가능하며, 진행 중인 작업은 Indicator를 통해 확인할 수 있다.
또한, 그래프에 나타나있는 Resource를 클릭하는 것으로 상세정보를 확인할 수 있다.

- LIVE MANIFEST (현재 k8s의 YAML 파일 정보를 실시간으로 추적)
- k8s에서 수정한 내용이 반영되거나, 여기서 수정한 내용도 k8s에 반영된다.
- DESIRED MANIFEST (Git의 YAML 파일 정보를 추적하며, 3분마다 갱신 -> Refresh마다,)
- Git에서 주기적으로 내용을 가져오는 역할만 하고, 수정은 불가능
- DIFF (LIVe와 DESIRED의 YAML 파일 내용을 비교)
- SYNC로 배포되었을 때, DESIRED의 내용으로 LIVE의 내용이 수정될 수 있을 때, DIFF에서 비교하여 보여줌
- 만약, k8s에서 수정되면 Git에서는 해당 내용이 없으므로 DIFF에서 보여주지 않음
(때문에,k8s에서 바로 수정하는 방식은 지양됨 -> 바뀐 내용을 추적하기 힘들기 때문)
Troubleshooting
더보기
1. 갑자기, k8s-master node가 너무 느려지고 계속 죽어버림
원인: 이전 실습에서 사용된 Namespace를 지우지 않고 남겨둬, 그 수만큼 App이 동시에 기동되고 있었음
해결: 기존의 Namespace를 제거하여 증상을 해결
추가적인 의문? -> 전부 똑같은 App이었는데, 왜 port 충돌이 나지 않았을까?
알고보니 Service에서 nodePort가 전부 다르게 설정되어 있었음 -> 만약, 같았으면 충돌 나는 것이 맞음
'Tech > Kubernetes(K8s)' 카테고리의 다른 글
| [쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 15. ArgoCD 빠르게 레벨업-3 (0) | 2025.06.19 |
|---|---|
| [쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 15. ArgoCD 빠르게 레벨업-2 (0) | 2025.06.18 |
| [쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 14. Helm과 Kustomize 비교하며 사용-2 (0) | 2025.06.16 |
| [쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 13. Helm과 Kustomize 비교하며 사용-1 (0) | 2025.06.14 |
| [쿠버네티스 어나더 클래스 (지상편) - Sprint 2] 12. Jenkins Pipeline (기초부터 Blue/Green까지 (0) | 2025.06.12 |
@ONE_ :: 정호원
잘못된 정보가 있다면 말씀해주세요!