GitOps 와 ArgoCD · Application 과 동기화 · 실습
Application 과 AppProject 직접 작성하기
목표
ArgoCD 의 Application 과 AppProject 를 직접 작성해 "무엇을 어디서 읽어 어디에 어떤 순서와 정책으로 적용할지"를 선언으로 표현할 수 있게 됩니다.
왜 중요한가
배포를 스크립트가 아니라 오브젝트로 만들면 세 가지가 따라옵니다. 클러스터에 "지금 무엇을 배포받고 있나"를 물어볼 수 있고, RBAC 과 감사 로그가 공짜로 붙고, 그 선언 자체를 다시 git 에 커밋할 수 있습니다. 이 실습에서 채우는 필드는 전부 실제 사고와 짝이 있습니다 — prune 은 저장소 경로 오타 한 번을 대량 삭제로 바꿀 수 있는 스위치이고, retry.backoff 가 없으면 실패한 동기화가 API 서버를 같은 간격으로 두드리는 부하 장치가 되며, ignoreDifferences 가 없으면 HPA 와 ArgoCD 가 서로 replicas 를 되돌리는 무한 루프가 생깁니다. 다만 이 환경에는 ArgoCD 컨트롤러가 실행되지 않습니다. CRD 를 등록하고 커스텀 리소스를 만들 수는 있지만 그것이 스스로 Synced/Healthy 로 바뀌지는 않습니다. 그래서 채점하는 것은 상태가 아니라 선언의 정확성이며, 그 선언이 실제 컨트롤러에게 무엇을 시키는지는 앞의 읽기 자료와 마지막 모듈에서 다룹니다.
단계
1. /opt/crds/ 아래 오프라인 CRD 번들에서 ArgoCD CRD 가 든 파일을 찾아(grep -l applications.argoproj.io /opt/crds/*.yaml) kubectl apply -f 로 적용하세요. applications.argoproj.io 와 appprojects.argoproj.io 두 CRD 가 생기고 Established 조건이 True 여야 하며, 네임스페이스 argocd 가 있어야 합니다. 등록된 타입 목록을 /root/gitops/app/out/crds.txt 에 저장하세요 (applications 라는 문자열이 들어가야 합니다).
2. argocd 네임스페이스에 kind: Application, metadata.name: web 인 오브젝트를 만드세요. spec.source.repoURL 은 file:///root/gitops/repo, spec.source.path 는 apps/web, spec.source.targetRevision 은 main, spec.destination.server 는 https://kubernetes.default.svc, spec.destination.namespace 는 gitops-lab, spec.project 는 platform 입니다.
3. web 의 spec.syncPolicy.automated 를 추가하고 prune: true, selfHeal: true 로 두세요. 그리고 /root/gitops/app/out/prune-note.txt 에 prune 을 켰을 때의 위험(경로를 잘못 가리킨 커밋 하나가 대량 삭제로 이어진다)을 한국어로 두세 줄 적으세요.
4. web 의 spec.syncPolicy.syncOptions 에 CreateNamespace=true 와 ServerSideApply=true 를 넣고, spec.syncPolicy.retry 에 limit: 3, backoff.duration: 10s, backoff.factor: 2, backoff.maxDuration: 5m 을 넣으세요.
5. 저장소 /root/gitops/repo 가 아직 없다면 먼저 만드세요 — /opt/lab/fixtures/gitops/seed/ 의 deployment.yaml 과 service.yaml 을 /root/gitops/repo/apps/web/ 로 복사하고 git init 후 커밋하면 됩니다. 그다음 저장소 /root/gitops/repo/apps/web/ 의 service.yaml 에 argocd.argoproj.io/sync-wave: "-1" 어노테이션을, deployment.yaml 에 argocd.argoproj.io/sync-wave: "0" 어노테이션을 추가하세요. 값은 반드시 큰따옴표로 감싼 문자열이어야 합니다. 그리고 /root/gitops/app/out/wave-note.txt 에 같은 웨이브 안에서는 리소스 종류(kind)별 기본 순서로 적용된다는 점을 적으세요.
6. /root/gitops/repo/apps/web/presync-job.yaml 에 kind: Job 인 훅 리소스를 만드세요. 어노테이션으로 argocd.argoproj.io/hook: PreSync 와 argocd.argoproj.io/hook-delete-policy: BeforeHookCreation 을 넣고, 컨테이너 이름은 migrate, spec.backoffLimit 은 1, 파드의 restartPolicy 는 Never 로 하세요. 이 디렉터리에서 훅 어노테이션이 붙은 파일은 이 하나뿐이어야 합니다.
7. argocd 네임스페이스에 kind: AppProject, metadata.name: platform 을 만드세요. spec.sourceRepos 에는 file:///root/gitops/repo 하나만(* 금지), spec.destinations[0] 에는 server https://kubernetes.default.svc 와 namespace gitops-lab(* 금지), spec.clusterResourceWhitelist 에는 group "" / kind Namespace, spec.namespaceResourceBlacklist 에는 group "" / kind ResourceQuota 와 group "" / kind LimitRange 를 넣으세요. Application web 의 spec.project 는 platform 이어야 합니다.
8. web 에 spec.ignoreDifferences 를 추가하세요 — group apps, kind Deployment, jsonPointers 에 /spec/replicas(HPA 가 소유하는 필드). 그리고 spec.revisionHistoryLimit 을 5 로 두세요. 마지막으로 /root/gitops/app/out/gitops-report.json 을 만드세요. applications 는 argocd 네임스페이스의 모든 Application 을 {"name": "..."} 형태로 담은 배열이고, project 는 "platform", self_heal 은 true 입니다.
참고
Application이 가리키는 저장소는 이 파드 안의 로컬 경로입니다. 앞 실습을 다른 파드에서 했다면/root/gitops/repo가 비어 있으므로 5번에서 픽스처(/opt/lab/fixtures/gitops/seed/)로 다시 만들어야 합니다. 선언이 가리키는 대상이 실제로 존재하는지 확인하는 것도 GitOps 의 일입니다.- 이 환경에는 원격 git 이 없어
repoURL이 로컬 경로(file://)입니다. 실무에서는https://나git@주소가 오고, 그 저장소 자격 증명은argocd네임스페이스의 Secret(argocd.argoproj.io/secret-type: repository라벨)으로 관리합니다. - 매니페스트는
kubectl apply -f 파일로 만들면 됩니다. CRD 가 먼저 등록돼 있어야Application타입을 인식합니다. - 8번의 보고서는 손으로 개수를 맞추지 말고 클러스터에 물어본 결과로 만드세요.
kubectl get application -n argocd -o json을jq로 가공하면 앱이 늘어나도 개수가 자동으로 맞습니다. - 흔한 실수 1: sync wave 값을
argocd.argoproj.io/sync-wave: -1처럼 따옴표 없이 쓰는 것. 어노테이션 값은 문자열이어야 하며 따옴표가 없으면 YAML 파서가 숫자로 읽어 적용 자체가 거부됩니다. - 흔한 실수 2: 훅 어노테이션 키를 하나로 착각하는 것.
argocd.argoproj.io/hook과argocd.argoproj.io/hook-delete-policy는 서로 다른 키이고 둘 다 필요합니다.
단계 8개
- ArgoCD API 타입 등록하기
- Application 의 소스와 대상 정의하기
- 자동 동기화·정리·자가치유 켜기
- 동기화 옵션과 재시도 백오프 넣기
- sync wave 로 배포 순서 만들기
- PreSync 훅 Job 작성하기
- AppProject 로 경계 긋기
- 무시할 필드 지정하고 구성 보고서 만들기