4.7. ArgoCD 로 배포 (GitOps)
어떨 때 읽는 장인가
- 배포 이력을 Git 에 남겨 누가 언제 무엇을 바꿨는지 추적해야 할 때
- 클러스터 상태가 정해 둔 설정에서 벗어나지 않게 하고 싶을 때
- 여러 환경(개발·검증·운영)에 같은 애플리케이션을 배포할 때
- 배포 권한을 Git 승인 절차로 통제하고 싶을 때
GitOps 란
GitOps 는 클러스터에 무엇이 떠 있어야 하는지를 Git 저장소에 적어 두고, 도구가 그대로 맞추게 하는 방식입니다.
지금까지의 방식은 사람이나 CI 도구가 클러스터에 "이 이미지로 바꿔라" 라고 명령을 보냅니다. GitOps 는 반대입니다. Git 에 원하는 상태를 적어 두면, 클러스터 안의 도구가 그것을 읽어 스스로 맞춥니다.
이 차이에서 세 가지가 따라옵니다.
| 성질 | 설명 |
|---|---|
| 이력이 남는다 | Git 커밋이 곧 배포 기록입니다. 누가 언제 무엇을 바꿨는지 남습니다 |
| 되돌리기가 쉽다 | 이전 커밋으로 되돌리면 클러스터도 그 상태로 돌아갑니다 |
| 벗어나면 되돌아온다 | 누군가 클러스터를 직접 고쳐도 Git 에 적힌 상태로 되돌립니다 |
ArgoCD 란
ArgoCD 는 GitOps 를 실제로 수행하는 프로그램입니다. 클러스터 안에서 동작하며 다음을 반복합니다.
- 지정한 Git 저장소를 주기적으로 읽습니다.
- 거기 적힌 상태와 클러스터의 현재 상태를 견줍니다.
- 다르면 Git 쪽에 맞춥니다(설정에 따라 자동으로, 또는 사람이 누를 때).
COP 는 ArgoCD 를 클러스터 구성요소로 함께 설치합니다. 별도로 준비할 것이 없습니다.
지금까지의 배포와 무엇이 다른가
| 지금까지 (4.2~4.6 장) | ArgoCD (이 장) | |
|---|---|---|
| 배포를 일으키는 것 | 사람이 버튼을 누르거나 CI 도구가 명령 | Git 저장소의 변경 |
| 클러스터를 고치는 주체 | 밖에서 kubectl 로 밀어 넣음 | 클러스터 안의 ArgoCD 가 스스로 당겨 옴 |
| 클러스터 접속 권한 | CI 도구가 가져야 함 | CI 도구는 필요 없음 (Git 쓰기 권한만) |
| 배포 이력 | Deployment 의 리비전 | Git 커밋 이력 |
| 직접 고친 설정 | 그대로 남음 | 되돌아옴 (설정에 따라) |
클러스터 접속 정보를 CI 도구에 주지 않아도 되는 점이 큽니다. CI 도구는 Git 에 쓰기만 하고, 클러스터 권한은 ArgoCD 만 갖습니다.
저장소 두 개를 쓴다
GitOps 는 소스 저장소 와 설정 저장소 를 나눕니다.
| 저장소 | 담는 것 | 누가 고치는가 |
|---|---|---|
소스 저장소 (egov) | 애플리케이션 소스 코드 | 개발자 |
설정 저장소 (egov-argocd) | Deployment·Service 등 배포 설정 YAML | 배포 도구, 또는 운영 담당자 |
나누는 이유 는 둘의 변경 주기와 승인 절차가 다르기 때문입니다. 소스는 하루에도 여러 번 바뀌지만 배포 설정은 드물게 바뀝니다. 나눠 두면 "운영에 무엇이 배포되어 있는지" 를 설정 저장소 하나만 보면 알 수 있고, 배포 승인을 그 저장소의 병합 요청으로 통제할 수 있습니다.
전체 흐름
앞 절반은 지금까지와 같습니다. 빌드해서 레지스트리에 올리는 데까지는 4.5 장의
스크립트를 그대로 씁니다. 달라지는 것은 그 뒤입니다 — build-deploy.sh 로 클러스터를 직접
고치는 대신, 설정 저장소의 이미지 태그를 고쳐 밀어 넣습니다.
COP 는 이 일을 하는 스크립트를 함께 넣어 둡니다. 소스 저장소에서 이미지 태그를 만들고, 설정
저장소의 deployment.yaml 에서 이미지 값을 바꾸고, 커밋해 푸시하는 것까지 한 번에 합니다.
스크립트를 내 프로젝트에 가져다 쓰기
ArgoCD 관련 스크립트는 샘플 애플리케이션에만 만들어집니다. 설치할 때 아래 경로에 생기며, 다른 애플리케이션에는 만들어지지 않습니다.
기본 설치 경 로가 /data 이면 /data/workspaces/apps/egov/egov/ 입니다.
Jenkins 신규 프로젝트 생성은 이 스크립트를 만들지 않습니다
Jenkins 의 신규 프로젝트 생성 작업은 빌드·배포 스크립트 묶음만 풉니다. 그 묶음에 들어 있는 것은 다음 일곱 개이고 ArgoCD 스크립트는 포함되지 않습니다.
| 신규 프로젝트가 만들어 주는 것 | 만들어 주지 않는 것 |
|---|---|
env.sh · build-app.sh · build-push.sh · build-deploy.sh · build-history.sh · build-rollback.sh · values.yaml | create-*-argocd.sh · deploy-*-argocd.sh · sync-*-argocd.sh · glab_git_push-argocd.sh · git-argocd/ |
신규 프로젝트 작업은 env.sh 의 네임스페이스·Deployment 이름·Git 주소만 입력값으로 바꿔
줍니다. ArgoCD 를 쓰려면 샘플의 스크립트를 복사해 직접 고쳐야 합니다.
Jenkins 의 ArgoCD 배포 작업(70-egov-argocd-deploy)도 샘플 전용입니다. 다른 프로젝트에
쓰려면 그 작업을 복제해 경로와 스크립트 이름을 바꿉니다.
복사해서 쓰는 순서
my-app 이라는 애플리케이션을 my-ns 네임스페이스에 배포한다고 하겠습니다.
1. 스크립트를 복사합니다.
SRC=<설치 경로>/workspaces/apps/egov/egov
DST=<설치 경로>/workspaces/apps/my-ns/my-app
cp $SRC/create-egov-argocd.sh $DST/create-my-app-argocd.sh
cp $SRC/deploy-egov-argocd.sh $DST/deploy-my-app-argocd.sh
cp $SRC/sync-egov-argocd.sh $DST/sync-my-app-argocd.sh
cp $SRC/glab_git_push-argocd.sh $DST/glab_git_push-argocd.sh
cp -r $SRC/git-argocd $DST/git-argocd
chmod +x $DST/*.sh
2. 스크립트 안의 이름을 바꿉니다. 샘플 이름이 여러 곳에 박혀 있습니다.
| 파일 | 바꿀 것 |
|---|---|
create-my-app-argocd.sh | ArgoCD 애플리케이션 이름, 설정 저장소 주소, 배포할 네임스페이스 |
deploy-my-app-argocd.sh | 소스 저장소 경로, 설정 저장소 경로, 컨테이너 이름, 이미지 주소 |
sync-my-app-argocd.sh | ArgoCD 애플리케이션 이름 |
glab_git_push-argocd.sh | 설정 저장소 경로와 원격 주소 |
deploy-*.sh 의 컨테이너 이름을 꼭 확인하십시오. 이 스크립트는 deployment.yaml 에서
이름이 일치하는 컨테이너의 이미지 값을 바꿉니다. 샘플은 컨테이너 이름이 egov 이므로
그대로 두면 my-app 의 이미지가 바뀌지 않는데, 오류 없이 조용히 넘어갑니다.
3. 설정 저장소의 YAML 을 고칩니다. git-argocd/ 안의 deployment.yaml·service.yaml·
ingress.yaml 에서 이름·네임스페이스·포트·주소를 내 애플리케이션에 맞춥니다.
4. 설정 저장소를 만들어 올립니다.
cd $DST
./glab_git_push-argocd.sh
5. ArgoCD 에 등록합니다. 저장소와 애플리케이션을 등록하는 최초 1회 작업입니다.
./create-my-app-argocd.sh
여기까지가 준비입니다. 이후 배포는 다음 두 줄로 끝납니다.
./deploy-my-app-argocd.sh # 설정 저장소에 새 이미지 태그를 반영
./sync-my-app-argocd.sh # 즉시 반영하고 싶을 때만 (자동 동기화면 생략 가능)
CI 도구에 넣기
이 스크립트도 셸 스크립트라 어느 CI 도구에서든 부를 수 있습니다(4.6 장). 빌드 뒤에 배포 단계만 바꿔 넣으면 됩니다.
# 기존 (클러스터를 직접 고침)
- cd $APP_DIR && ./build-deploy.sh
# ArgoCD (설정 저장소를 고침)
- cd $APP_DIR && ./deploy-my-app-argocd.sh
build-deploy.sh 와 deploy-*-argocd.sh 를 함께 두지 마십시오. 앞의 것은 클러스터를
직접 고치고 뒤의 것은 Git 을 고칩니다. 둘 다 돌면 자기 치유가 켜진 상태에서 배포가
오르내립니다.
이 방식이 번거로우면
스크립트를 복사해 고치는 대신 설정 저장소의 이미지 태그만 바꿔 커밋하는 것 이 본질입니다. 사내 표준 CI 도구가 있다면 그 도구의 Git 연동 기능으로 같은 일을 해도 됩니다. 스크립트는 "이렇게 하면 된다" 를 보여 주는 출발점입니다.
배포하는 세 가지 방법
방법 1 — ArgoCD 화면에서 누르기
- ArgoCD 화면에 접속합니다. 주소와 계정은 운영 담당자에게 확인하십시오.
- 애플리케이션 을 고릅니다.
- SYNC 를 누릅니다.
Git 에 적힌 상태를 클러스터에 반영합니다. 무엇이 바뀌는지 미리 볼 수 있어 처음 쓸 때 적합합니다.
방법 2 — CI 도구에서 실행
COP 가 기본으로 넣어 주는 Jenkins 작업 중 ArgoCD 배포 작업이 있습니다. 내용은 설정 저장소의 이미지 태그를 고쳐 푸시하는 스크립트 한 줄입니다. 다른 CI 도구를 쓴다면 같은 스크립트를 부르면 됩니다(4.6 장).
방법 3 — 명령줄에서 실행
Bastion 에 argocd 명령이 준비되어 있습니다. 동기화 스크립트를 실행하면 화면에서 SYNC 를
누른 것과 같습니다.
argocd app sync <애플리케이션 이름> # 동기화
argocd app wait <애플리케이션 이름> # 끝날 때까지 기다림
argocd app get <애플리케이션 이름> # 상태 확인
자동 동기화 세 가지 설정
COP 가 만드는 애플리케이션에는 자동 동기화가 켜져 있습니다. 세 가지가 함께 설정됩니다.
| 설정 | 하는 일 | 켜면 달라지는 것 |
|---|---|---|
| 자동 동기화 | Git 이 바뀌면 사람이 누르지 않아도 반영합니다 | 푸시가 곧 배포가 됩니다 |
| 자동 정리 | Git 에서 지운 자원을 클러스터에서도 지웁니다 | YAML 을 지우면 실제 자원도 사라집니다 |
| 자기 치유 | 클러스터를 직접 고쳐도 Git 상태로 되돌립니다 | kubectl 로 고친 것이 잠시 뒤 사라집니다 |
자기 치유가 켜져 있으면 클러스터를 직접 고쳐도 소용없습니다. 예를 들어 복제본 수를 Console 에서 늘려도 몇 분 뒤 Git 에 적힌 값으로 돌아갑니다. 바꾸려면 설정 저장소를 고쳐야 합니다.
자동 확장(HPA)을 함께 쓸 때 주의하십시오. HPA 가 복제본 수를 바꾸는데 ArgoCD 가 그것을 "벗어남" 으로 보고 되돌리면 둘이 서로 다툽니다. 이때는 설정 저장소의 YAML 에서 복제본 수 항목을 아예 빼야 합니다(3.5 장).
상태 읽는 법
ArgoCD 는 두 가지 상태를 따로 보여 줍니다. 둘을 구분해야 합니다.
| 상태 | 뜻 |
|---|---|
| Synced | 클러스터가 Git 과 같습니다 |
| OutOfSync | Git 과 다릅니다. 아직 반영되지 않았거나 누군가 직접 고쳤습니다 |
| 상태 | 뜻 |
|---|---|
| Healthy | 배포된 자원이 정상 동작합니다 |
| Progressing | 배포가 진행 중입니다 |
| Degraded | 배포는 되었으나 정상이 아닙니다 |
| Missing | Git 에는 있는데 클러스터에 없습니다 |
Synced 인데 Degraded 인 경우가 헷갈립니다. Git 에 적힌 대로 반영은 했지만 그 내용
자체에 문제가 있다는 뜻입니다. 이미지 이름이 틀렸거나, 필요한 설정 데이터가 없거나, 자원이
모자란 경우입니다. 이때는 파드 로그와 이벤트를 봐야 합니다(3.1 장).
Console 에서 확인하기
ArgoCD 로 배포해도 결과를 보는 곳은 지금까지와 같습니다.
| 확인할 것 | 어디에서 |
|---|---|
| 새 이미지가 반영되었는가 | Deployment 상세의 이미지 태그(3.2 장) |
| 파드가 정상으로 떴는가 | 파드 목록과 상태 뱃지(3.1 장) |
| 무엇이 배포되었는지 한눈에 | 토폴로지(2.2 장) |
| 실패 원인 | 파드 로그와 이벤트(3.1 장) |
ArgoCD 자체가 만드는 자원(애플리케이션 정의)은 커스텀 리소스라 Console 의 커스텀 리소스 화면에서도 볼 수 있습니다(8.2 장).
되돌리기
GitOps 에서 되돌리기는 Git 을 되돌리는 것입니다.
| 상황 | 방법 |
|---|---|
| 방금 배포가 잘못됐다 | 설정 저장소에서 직전 커밋으로 되돌려 푸시합니다 |
| 여러 단계 앞으로 가야 한다 | 그 시점 커밋의 YAML 로 되돌려 푸시합니다 |
| 지금 당장 멈춰야 한다 | ArgoCD 화면에서 자동 동기화를 끄고 이전 리비전으로 롤백합니다 |
Console 의 배포 히스토리에서 되돌리면 안 됩니다. 되돌아가긴 하지만 Git 은 그대로여서 자기 치유가 켜져 있으면 몇 분 뒤 다시 되돌아옵니다. 겉보기에는 "롤백했는데 원래대로 돌아왔다" 로 보여 원인을 찾기 어렵습니다.
잘 안 될 때
| 증상 | 원인 | 확인할 것 |
|---|---|---|
OutOfSync 로 멈춰 있음 | 자동 동기화가 꺼져 있습니다 | ArgoCD 화면에서 SYNC 를 누릅니다 |
| Git 에 올렸는데 안 바뀜 | ArgoCD 가 아직 읽지 않았습니다 | 잠시 기다리거나 새로 고침을 누릅니다 |
| 저장소를 못 읽음 | 저장소 접근 정보가 잘못됐습니다 | 운영 담당자에게 저장소 등록 확인 요청 |
Synced 인데 Degraded | Git 내용 자체에 문제가 있습니다 | 파드 로그·이벤트, 이미지 이름과 태그 |
| 고쳤는데 되돌아옴 | 자기 치유가 켜져 있습니다 | 클러스터가 아니라 설정 저장소를 고칩니다 |
| 자원이 갑자기 사라짐 | 자동 정리가 켜진 상태에서 YAML 을 지웠습니다 | 설정 저장소의 최근 커밋 |
어느 방식을 고를 것인가
| 상황 | 권하는 방식 |
|---|---|
| 처음 써 보거나 개발 중 | Console 빌드(4.2 장) 또는 Bastion(4.5 장) |
| 팀이 정해진 절차로 배포 | CI 도구(4.4 장, 4.6 장) |
| 이력·승인·복구가 중요한 운영 환경 | ArgoCD (이 장) |
| 여러 환경에 같은 것을 배포 | ArgoCD (이 장) |
한 애플리케이션에 두 방식을 함께 쓰지 마십시오. ArgoCD 로 관리하는 자원을 kubectl 이나
Console 로 고치면 자기 치유가 되돌립니다. 옮기는 중이라면 자동 동기화를 잠시 끄고 진행한 뒤
다시 켜십시오.