GitOps 와 ArgoCD · 헬름·Kustomize 연동 · 실습
베이스·오버레이로 환경 차이 만들기
목표
하나의 베이스에서 dev·prod 두 환경을 만들어 내고, 그 오버레이를 ArgoCD Application 의 소스로 연결할 수 있게 됩니다.
왜 중요한가
환경별 YAML 을 복사해서 관리하면 반드시 갈라집니다. 갈라진 뒤에는 어느 쪽이 정답인지 아무도 모르고, "dev 에서는 됐는데요"가 시작됩니다. 오버레이는 공통을 한 번만 쓰고 차이만 파일로 남기는 구조라 그 갈라짐을 구조적으로 막습니다. 이 실습에서 특히 눈여겨볼 것은 configMapGenerator 의 해시 접미어입니다 — 설정 내용이 바뀌면 ConfigMap 이름이 바뀌고, 그것을 참조하는 파드 템플릿이 바뀌어 롤아웃이 저절로 일어납니다. 해시가 없으면 ConfigMap 만 갱신되고 파드는 옛 설정을 들고 계속 도는, 원인 찾기 가장 어려운 부류의 사고가 납니다. 마지막으로 ArgoCD 가 Helm 을 다루는 방식도 짚습니다 — ArgoCD 는 helm install 을 하지 않고 repo-server 에서 helm template 로 렌더한 결과를 apply 합니다. 그래서 클러스터에서 helm list 를 해도 아무것도 안 보이고, 롤백은 Helm 리비전이 아니라 git 커밋으로 합니다.
단계
1. 베이스 지시서는 /root/gitops/kustomize/base/kustomization.yaml 입니다. /opt/lab/fixtures/gitops/seed/deployment.yaml 과 service.yaml 을 /root/gitops/kustomize/base/ 로 복사하고, 같은 디렉터리에 kustomization.yaml 을 만드세요. apiVersion: kustomize.config.k8s.io/v1beta1, kind: Kustomization, resources 에 두 파일 이름을 적습니다. 베이스의 spec.replicas 는 2 로 둡니다 (베이스가 1이면 실패 처리됩니다).
2. kustomize build /root/gitops/kustomize/base > /root/gitops/kustomize/out/base.yaml 로 결과를 저장하세요. 결과에 kind: Deployment 와 kind: Service 가 있어야 하고 kind: Kustomization 은 들어 있으면 안 됩니다.
3. 베이스 kustomization.yaml 에 namePrefix: labhub- 를 넣고, 공통 라벨 app.kubernetes.io/part-of: labhub-platform 을 추가하세요 (labels: 아래 - pairs: 형태 또는 commonLabels: 둘 다 인정됩니다). 다시 빌드해 out/base.yaml 을 갱신하면 Deployment 이름이 labhub-web 이 되고 Service 의 metadata.labels 에도 그 라벨이 붙어야 합니다.
4. /root/gitops/kustomize/overlays/dev/kustomization.yaml 을 만드세요. resources 의 첫 항목은 ../../base, namespace 는 gitops-dev, nameSuffix 는 -dev 입니다. kustomize build /root/gitops/kustomize/overlays/dev > /root/gitops/kustomize/out/dev.yaml 로 저장하세요.
5. dev 오버레이에 전략적 병합 패치 파일(예: patch-deployment.yaml)을 두고 kustomization.yaml 의 patches 에 그 경로를 적으세요. 패치는 Deployment 의 spec.replicas 를 1 로 낮추고, 컨테이너 web 에 환경변수 LOG_LEVEL=debug 를 추가해야 합니다. 패치 파일의 metadata.name 은 베이스에 적힌 원래 이름인 web 입니다. 베이스의 replicas 는 2 그대로여야 합니다. 다시 빌드해 out/dev.yaml 을 갱신하세요.
6. dev 오버레이의 kustomization.yaml 에 configMapGenerator 로 이름 app-config 인 ConfigMap 을 만드세요 (예: literals 에 LOG_FORMAT=json). 그리고 5번의 패치에서 컨테이너 web 이 envFrom 의 configMapRef.name: app-config 로 그것을 참조하게 하세요. 다시 빌드하면 ConfigMap 이름 끝에 내용 해시가 붙고 Deployment 의 참조 이름도 그 해시 이름으로 바뀌어 있어야 합니다. /root/gitops/kustomize/out/hash-note.txt 에 해시 접미어 덕분에 설정 변경이 파드 롤아웃으로 이어진다는 점을 한국어로 적으세요.
7. argocd 네임스페이스에 kind: Application, metadata.name: platform-helm 을 만드세요. spec.source.helm.valueFiles 에 values-prod.yaml 을, spec.source.helm.parameters 에 이름 image.tag 와 값(예: 1.27.3)을 넣고, spec.source.targetRevision 은 HEAD 가 아닌 고정 값(예: v1.4.0)으로 두세요.
8. /root/gitops/kustomize/overlays/prod/ 오버레이를 만드세요 — resources 는 ../../base, namespace 는 gitops-prod, 패치로 spec.replicas 를 3 이상으로, images 로 이미지 태그를 dev 와 다르게(예: name: nginx, newTag: 1.27.3) 바꿉니다. 빌드 결과를 /root/gitops/kustomize/out/prod.yaml 로 저장하세요. 그다음 argocd 네임스페이스에 kind: Application, metadata.name: web-dev 를 만드세요 — spec.source.path 에 overlays/dev 가 들어가야 하고, spec.source.kustomize.images 에 이미지 오버라이드를 최소 하나 넣습니다.
참고
- 7·8번의 Application 을 만들려면 ArgoCD CRD 가 먼저 등록돼 있어야 합니다. 앞 실습과 같이
/opt/crds/의 오프라인 번들에서 찾아 적용하세요 (grep -l applications.argoproj.io /opt/crds/*.yaml). kustomize build는 표준 출력으로 결과를 냅니다. 리다이렉트 전에 출력 디렉터리(/root/gitops/kustomize/out/)를 먼저 만들어 두세요.- 이름 접두어가 붙어 있어도 패치는 베이스에 적힌 원래 이름으로 대상을 찾습니다. 만약 대상을 찾지 못한다는 오류가 나면
patches대신 구형patchesStrategicMerge로 적어도 됩니다. - 흔한 실수 1: dev 의 replicas 를 1로 만들려고 베이스를 고치는 것. 그러면 prod 까지 1이 됩니다. 베이스는 공통분모, 환경 고유 값은 오버레이입니다.
- 흔한 실수 2: 오버레이를 고치고 다시 빌드하지 않는 것. 채점은
out/*.yaml파일을 읽으므로, 설정을 고칠 때마다 해당 빌드 결과를 새로 저장해야 합니다.
단계 8개
- kustomize 베이스 구성하기
- 베이스 빌드 결과 저장하기
- 이름 접두어와 공통 라벨 붙이기
- dev 오버레이 만들기
- 패치로 베이스 덮어쓰기
- 설정 생성기와 해시 접미어 연결하기
- Helm 소스를 쓰는 Application 작성하기
- 오버레이 기반 Application 과 prod 빌드