ApplicationとAppProjectを自分で書く
한국어 원문으로 표시합니다.
목표
ArgoCD 의 Application 과 AppProject 를 직접 작성해 "무엇을 어디서 읽어 어디에 어떤 순서와 정책으로 적용할지"를 선언으로 표현할 수 있게 됩니다.
왜 중요한가
배포를 스크립트가 아니라 오브젝트로 만들면 세 가지가 따라옵니다. 클러스터에 "지금 무엇을 배포받고 있나"를 물어볼 수 있고, RBAC 과 감사 로그가 공짜로 붙고, 그 선언 자체를 다시 git 에 커밋할 수 있습니다. 이 실습에서 채우는 필드는 전부 실제 사고와 짝이 있습니다 — prune 은 저장소 경로 오타 한 번을 대량 삭제로 바꿀 수 있는 스위치이고, retry.backoff 가 없으면 실패한 동기화가 API 서버를 같은 간격으로 두드리는 부하 장치가 되며, ignoreDifferences 가 없으면 HPA 와 ArgoCD 가 서로 replicas 를 되돌리는 무한 루프가 생깁니다. 다만 이 환경에는 ArgoCD 컨트롤러가 실행되지 않습니다. CRD 를 등록하고 커스텀 리소스를 만들 수는 있지만 그것이 스스로 Synced/Healthy 로 바뀌지는 않습니다. 그래서 채점하는 것은 상태가 아니라 선언의 정확성이며, 그 선언이 실제 컨트롤러에게 무엇을 시키는지는 앞의 읽기 자료와 마지막 모듈에서 다룹니다.
단계
/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라는 문자열이 들어가야 합니다).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입니다.web의spec.syncPolicy.automated를 추가하고prune: true,selfHeal: true로 두세요. 그리고/root/gitops/app/out/prune-note.txt에 prune 을 켰을 때의 위험(경로를 잘못 가리킨 커밋 하나가 대량 삭제로 이어진다)을 한국어로 두세 줄 적으세요.web의spec.syncPolicy.syncOptions에CreateNamespace=true와ServerSideApply=true를 넣고,spec.syncPolicy.retry에limit: 3,backoff.duration: 10s,backoff.factor: 2,backoff.maxDuration: 5m을 넣으세요.- 저장소
/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)별 기본 순서로 적용된다는 점을 적으세요. /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로 하세요. 이 디렉터리에서 훅 어노테이션이 붙은 파일은 이 하나뿐이어야 합니다.argocd네임스페이스에kind: AppProject,metadata.name: platform을 만드세요.spec.sourceRepos에는file:///root/gitops/repo하나만(*금지),spec.destinations[0]에는 serverhttps://kubernetes.default.svc와 namespacegitops-lab(*금지),spec.clusterResourceWhitelist에는 group""/ kindNamespace,spec.namespaceResourceBlacklist에는 group""/ kindResourceQuota와 group""/ kindLimitRange를 넣으세요. Applicationweb의spec.project는platform이어야 합니다.web에spec.ignoreDifferences를 추가하세요 — groupapps, kindDeployment,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는 서로 다른 키이고 둘 다 필요합니다.
ArgoCD API 타입 등록하기
/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 라는 문자열이 들어가야 합니다).
인터넷이 없으니 오프라인 CRD 번들을 씁니다. 파일 이름을 외우는 대신 내용으로 찾으세요 — 어떤 파일에 applications.argoproj.io 가 들어 있는지 grep 으로 찾을 수 있습니다.
Application 의 소스와 대상 정의하기
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 입니다.
Application 오브젝트 자신이 사는 곳과 배포 대상 네임스페이스는 서로 다릅니다. source 에는 어디서·어디를·어느 리비전을 읽을지 세 가지가 모두 필요합니다.
자동 동기화·정리·자가치유 켜기
web 의 spec.syncPolicy.automated 를 추가하고 prune: true, selfHeal: true 로 두세요. 그리고 /root/gitops/app/out/prune-note.txt 에 prune 을 켰을 때의 위험(경로를 잘못 가리킨 커밋 하나가 대량 삭제로 이어진다)을 한국어로 두세 줄 적으세요.
automated 아래 스위치 두 개가 서로 다른 일을 합니다. 하나는 저장소에서 지운 것을 처리하고 하나는 클러스터에서 바뀐 것을 처리합니다. 위험한 쪽이 무엇인지도 적어야 합니다.
동기화 옵션과 재시도 백오프 넣기
web 의 spec.syncPolicy.syncOptions 에 CreateNamespace=true 와 ServerSideApply=true 를 넣고, spec.syncPolicy.retry 에 limit: 3, backoff.duration: 10s, backoff.factor: 2, backoff.maxDuration: 5m 을 넣으세요.
syncOptions 는 키=값 문자열의 배열입니다. 재시도는 횟수만으로는 부족하고, 간격이 점점 벌어지게 만드는 값 세 개가 필요합니다.
sync wave 로 배포 순서 만들기
저장소 /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)별 기본 순서로 적용된다는 점을 적으세요.
웨이브 값은 어노테이션이고 숫자가 아니라 큰따옴표로 감싼 문자열로 씁니다. 먼저 만들어야 할 것에 더 작은 값을, 필요하면 음수를 줍니다. 순서를 만들려면 파일이 둘 이상이어야 합니다.
PreSync 훅 Job 작성하기
/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 로 하세요. 이 디렉터리에서 훅 어노테이션이 붙은 파일은 이 하나뿐이어야 합니다.
훅은 보통 Job 입니다. 어노테이션 두 개가 필요한데 하나는 어느 단계인지, 하나는 언제 치울지를 정합니다. 정리 정책을 빼면 훅 리소스가 계속 쌓입니다.
AppProject 로 경계 긋기
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 이어야 합니다.
화이트리스트는 '적힌 것만 허용', 블랙리스트는 '적힌 것만 금지'입니다. 저장소와 네임스페이스에 * 를 쓰면 프로젝트를 나눈 의미가 없어집니다. 앱을 그 프로젝트에 소속시키는 것도 잊지 마세요.
무시할 필드 지정하고 구성 보고서 만들기
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 입니다.
다른 컨트롤러가 소유한 필드까지 되돌리면 무한 동기화가 됩니다. 보고서의 앱 개수는 손으로 세지 말고 클러스터에 물어본 결과로 만드세요 — 그래야 항상 실제와 일치합니다.