LabHub
배우기 러닝패스 코스

CGOA — GitOps Certified Associate

Create Drift, See It, and Undo It

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

드리프트를 직접 만들고, 그 차이를 계산해 파일로 남기고, 선언 상태로 되돌리는 한 바퀴를 손으로 돕니다. 이어서 sync wave 와 PreSync 훅 매니페스트를 작성하고, 클러스터를 뒤져 prune 대상을 판별합니다.

왜 중요한가

Argo CD 의 조정 루프는 마법이 아니라 이 실습에서 하는 일을 기본 180 초마다 반복하는 것입니다. 다시 렌더하고, live 를 읽고, 비교하고, 정책이 허락하면 적용합니다. 이 루프를 손으로 한 번 돌려 보면 refreshsync 가 왜 다른 동작인지, selfHeal 을 켠다는 것이 운영에 어떤 규율을 요구하는지가 몸으로 이해됩니다. prune 판별도 마찬가지입니다 — 에이전트는 클러스터의 모든 리소스를 지우는 게 아니라 자기가 만들었다고 표시해 둔 것 중 Git 에서 사라진 것만 지웁니다. 이 경계를 모르면 "왜 저건 안 지워지지" 와 "왜 저게 지워졌지" 를 둘 다 설명할 수 없습니다. Argo CD CRD 는 이 환경에 없으므로 웨이브와 훅은 파일로 작성하고 채점도 파일을 읽어서 합니다.

단계

  1. /root/cgoa-drift/desired/orders.yaml 에 Deployment orders 를 작성하세요 — 네임스페이스 cgoa-drift, spec.replicas: 2, 셀렉터·파드 라벨 app: orders, 컨테이너 이름 app, 이미지 nginx:1.27-alpine. 네임스페이스 cgoa-drift 를 만들고 이 파일을 kubectl apply -f 로 적용하세요.
  2. 파일은 그대로 둔 채 클러스터의 orders replicas 만 5 로 바꿔 드리프트를 만드세요. 그리고 바뀐 live 값을 kubectl get ... -o jsonpath 로 읽어 /root/cgoa-drift/live-replicas.txt 에 저장하세요 (뒤에서 되돌린 뒤에도 증거로 남깁니다).
  3. kubectl diff -f /root/cgoa-drift/desired/orders.yaml 의 출력을 /root/cgoa-drift/drift.txt 에 저장하세요. 파일에는 replicas 차이가 보여야 합니다.
  4. 원본 매니페스트를 다시 적용해 replicas 를 2 로 되돌리세요.
  5. /root/cgoa-drift/wave/ 에 세 파일을 만드세요. namespace.yaml — Namespace cgoa-wave, 주석 argocd.argoproj.io/sync-wave: "-2". config.yaml — ConfigMap orders-wave-config(네임스페이스 cgoa-wave, data 아무 키 하나), 주석 argocd.argoproj.io/sync-wave: "-1". app.yaml — Deployment orders-wave(네임스페이스 cgoa-wave), 주석 argocd.argoproj.io/sync-wave: "1".
  6. /root/cgoa-drift/hooks/db-migrate.yaml 에 Job db-migrate 를 작성하세요 — 네임스페이스 cgoa-drift, 주석 argocd.argoproj.io/hook: PreSync, argocd.argoproj.io/hook-delete-policy: BeforeHookCreation, argocd.argoproj.io/sync-wave: "-1", spec.backoffLimit: 1, 파드의 restartPolicy: Never, 컨테이너 이름 migrate.
  7. prune 대상을 판별하세요. 먼저 /root/cgoa-drift/desired/config.yaml 에 ConfigMap orders-config(네임스페이스 cgoa-drift, data 아무 키 하나)를 선언하고 적용하세요. 그다음 legacy-config 라는 ConfigMap 을 cgoa-drift 네임스페이스에 파일 없이 명령형으로 만드세요. 마지막으로 /root/cgoa-drift/prune-candidates.txtcgoa-drift 네임스페이스의 ConfigMap 중 desired/ 디렉터리 어디에도 선언되지 않은 것의 이름을 한 줄에 하나씩 적으세요. (쿠버네티스가 자동으로 만드는 kube-root-ca.crt 는 관리 대상이 아니므로 제외합니다.)

참고

원하는 상태를 선언하고 적용

/root/cgoa-drift/desired/orders.yaml 에 Deployment orders 를 작성하세요 — 네임스페이스 cgoa-drift, spec.replicas: 2, 셀렉터·파드 라벨 app: orders, 컨테이너 이름 app, 이미지 nginx:1.27-alpine. 네임스페이스 cgoa-drift 를 만들고 이 파일을 kubectl apply -f 로 적용하세요.

선언형으로 적용하면 오브젝트에 마지막으로 적용한 설정이 주석으로 남습니다. 명령형으로 만들면 그 주석이 없습니다 — 채점이 그 차이를 봅니다.

손으로 고쳐 드리프트 만들기

파일은 그대로 둔 채 클러스터의 orders replicas 만 5 로 바꿔 드리프트를 만드세요. 그리고 바뀐 live 값을 kubectl get ... -o jsonpath 로 읽어 /root/cgoa-drift/live-replicas.txt 에 저장하세요 (뒤에서 되돌린 뒤에도 증거로 남깁니다).

파일은 그대로 두고 클러스터만 바꿔야 합니다. 스케일을 바꾸는 명령형 서브커맨드가 있습니다. 바뀐 live 값은 jsonpath 로 뽑아 파일에 남겨 두세요 — 되돌린 뒤에도 증거가 됩니다.

차이를 계산해 파일로 남기기

kubectl diff -f /root/cgoa-drift/desired/orders.yaml 의 출력을 /root/cgoa-drift/drift.txt 에 저장하세요. 파일에는 replicas 차이가 보여야 합니다.

kubectl diff -f <파일> 은 서버에 드라이런을 던져 실제 차이를 보여 줍니다. 차이가 있으면 종료 코드가 1 이므로 리다이렉트할 때 중단되지 않게 하세요.

선언 상태로 되돌리기

원본 매니페스트를 다시 적용해 replicas 를 2 로 되돌리세요.

에이전트의 selfHeal 이 하는 일을 손으로 합니다. 원본 파일을 그대로 다시 적용하면 됩니다.

sync wave 주석 세 개

/root/cgoa-drift/wave/ 에 세 파일을 만드세요. namespace.yaml — Namespace cgoa-wave, 주석 argocd.argoproj.io/sync-wave: "-2". config.yaml — ConfigMap orders-wave-config(네임스페이스 cgoa-wave, data 아무 키 하나), 주석 argocd.argoproj.io/sync-wave: "-1". app.yaml — Deployment orders-wave(네임스페이스 cgoa-wave), 주석 argocd.argoproj.io/sync-wave: "1".

웨이브 번호는 문자열로 씁니다. 인프라가 먼저, 설정이 그다음, 워크로드가 마지막이 되도록 번호를 정하세요.

PreSync 훅 Job

/root/cgoa-drift/hooks/db-migrate.yaml 에 Job db-migrate 를 작성하세요 — 네임스페이스 cgoa-drift, 주석 argocd.argoproj.io/hook: PreSync, argocd.argoproj.io/hook-delete-policy: BeforeHookCreation, argocd.argoproj.io/sync-wave: "-1", spec.backoffLimit: 1, 파드의 restartPolicy: Never, 컨테이너 이름 migrate.

훅 종류와 삭제 정책은 서로 다른 주석 키입니다. 삭제 정책은 기본값을 명시적으로 적어 두는 편이 리뷰에 좋습니다.

prune 대상 판별

prune 대상을 판별하세요. 먼저 /root/cgoa-drift/desired/config.yaml 에 ConfigMap orders-config(네임스페이스 cgoa-drift, data 아무 키 하나)를 선언하고 적용하세요. 그다음 legacy-config 라는 ConfigMap 을 cgoa-drift 네임스페이스에 파일 없이 명령형으로 만드세요. 마지막으로 /root/cgoa-drift/prune-candidates.txtcgoa-drift 네임스페이스의 ConfigMap 중 desired/ 디렉터리 어디에도 선언되지 않은 것의 이름을 한 줄에 하나씩 적으세요. (쿠버네티스가 자동으로 만드는 kube-root-ca.crt 는 관리 대상이 아니므로 제외합니다.)

prune 대상은 '클러스터에 있는데 선언 디렉터리에는 없는' 리소스입니다. 클러스터가 자동으로 만드는 오브젝트는 대상이 아니라는 점을 기억하세요.