LabHub
배우기 러닝패스 코스

GitOps and Argo CD

Environment Differences With Bases and Overlays

LabHub 에서 이어서 보기

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

목표

하나의 베이스에서 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.yamlservice.yaml/root/gitops/kustomize/base/ 로 복사하고, 같은 디렉터리에 kustomization.yaml 을 만드세요. apiVersion: kustomize.config.k8s.io/v1beta1, kind: Kustomization, resources 에 두 파일 이름을 적습니다. 베이스의 spec.replicas2 로 둡니다 (베이스가 1이면 실패 처리됩니다).
  2. kustomize build /root/gitops/kustomize/base > /root/gitops/kustomize/out/base.yaml 로 결과를 저장하세요. 결과에 kind: Deploymentkind: Service 가 있어야 하고 kind: Kustomization 은 들어 있으면 안 됩니다.
  3. 베이스 kustomization.yamlnamePrefix: 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, namespacegitops-dev, nameSuffix-dev 입니다. kustomize build /root/gitops/kustomize/overlays/dev > /root/gitops/kustomize/out/dev.yaml 로 저장하세요.
  5. dev 오버레이에 전략적 병합 패치 파일(예: patch-deployment.yaml)을 두고 kustomization.yamlpatches 에 그 경로를 적으세요. 패치는 Deployment 의 spec.replicas1 로 낮추고, 컨테이너 web 에 환경변수 LOG_LEVEL=debug 를 추가해야 합니다. 패치 파일의 metadata.name베이스에 적힌 원래 이름인 web 입니다. 베이스의 replicas 는 2 그대로여야 합니다. 다시 빌드해 out/dev.yaml 을 갱신하세요.
  6. dev 오버레이의 kustomization.yamlconfigMapGenerator 로 이름 app-config 인 ConfigMap 을 만드세요 (예: literalsLOG_FORMAT=json). 그리고 5번의 패치에서 컨테이너 webenvFromconfigMapRef.name: app-config 로 그것을 참조하게 하세요. 다시 빌드하면 ConfigMap 이름 끝에 내용 해시가 붙고 Deployment 의 참조 이름도 그 해시 이름으로 바뀌어 있어야 합니다. /root/gitops/kustomize/out/hash-note.txt 에 해시 접미어 덕분에 설정 변경이 파드 롤아웃으로 이어진다는 점을 한국어로 적으세요.
  7. argocd 네임스페이스에 kind: Application, metadata.name: platform-helm 을 만드세요. spec.source.helm.valueFilesvalues-prod.yaml 을, spec.source.helm.parameters 에 이름 image.tag 와 값(예: 1.27.3)을 넣고, spec.source.targetRevisionHEAD 가 아닌 고정 값(예: v1.4.0)으로 두세요.
  8. /root/gitops/kustomize/overlays/prod/ 오버레이를 만드세요 — resources../../base, namespacegitops-prod, 패치로 spec.replicas3 이상으로, images 로 이미지 태그를 dev 와 다르게(예: name: nginx, newTag: 1.27.3) 바꿉니다. 빌드 결과를 /root/gitops/kustomize/out/prod.yaml 로 저장하세요. 그다음 argocd 네임스페이스에 kind: Application, metadata.name: web-dev 를 만드세요 — spec.source.pathoverlays/dev 가 들어가야 하고, spec.source.kustomize.images 에 이미지 오버라이드를 최소 하나 넣습니다.

참고

kustomize 베이스 구성하기

베이스 지시서는 /root/gitops/kustomize/base/kustomization.yaml 입니다. /opt/lab/fixtures/gitops/seed/deployment.yamlservice.yaml/root/gitops/kustomize/base/ 로 복사하고, 같은 디렉터리에 kustomization.yaml 을 만드세요. apiVersion: kustomize.config.k8s.io/v1beta1, kind: Kustomization, resources 에 두 파일 이름을 적습니다. 베이스의 spec.replicas2 로 둡니다 (베이스가 1이면 실패 처리됩니다).

kustomization.yaml 은 매니페스트가 아니라 지시서입니다. resources 에 적은 이름은 같은 디렉터리에 실제로 있어야 합니다.

베이스 빌드 결과 저장하기

kustomize build /root/gitops/kustomize/base > /root/gitops/kustomize/out/base.yaml 로 결과를 저장하세요. 결과에 kind: Deploymentkind: Service 가 있어야 하고 kind: Kustomization 은 들어 있으면 안 됩니다.

kustomize build 디렉터리 의 표준 출력을 파일로 받습니다. 결과에 지시서 자신이 섞여 나오면 안 됩니다 — 그건 결과물이 아니니까요.

이름 접두어와 공통 라벨 붙이기

베이스 kustomization.yamlnamePrefix: labhub- 를 넣고, 공통 라벨 app.kubernetes.io/part-of: labhub-platform 을 추가하세요 (labels: 아래 - pairs: 형태 또는 commonLabels: 둘 다 인정됩니다). 다시 빌드해 out/base.yaml 을 갱신하면 Deployment 이름이 labhub-web 이 되고 Service 의 metadata.labels 에도 그 라벨이 붙어야 합니다.

이름 변형과 라벨 부착은 모두 베이스의 kustomization 에서 선언합니다. 라벨은 신형 labelspairs 나 구형 commonLabels 둘 다 됩니다. 고쳤으면 다시 빌드해야 결과 파일이 바뀝니다.

dev 오버레이 만들기

/root/gitops/kustomize/overlays/dev/kustomization.yaml 을 만드세요. resources 의 첫 항목은 ../../base, namespacegitops-dev, nameSuffix-dev 입니다. kustomize build /root/gitops/kustomize/overlays/dev > /root/gitops/kustomize/out/dev.yaml 로 저장하세요.

오버레이는 베이스를 상대 경로로 resources 에 넣습니다. 네임스페이스와 이름 접미어는 오버레이가 정하고, 빌드 결과는 dev 전용 파일로 따로 저장하세요.

패치로 베이스 덮어쓰기

dev 오버레이에 전략적 병합 패치 파일(예: patch-deployment.yaml)을 두고 kustomization.yamlpatches 에 그 경로를 적으세요. 패치는 Deployment 의 spec.replicas1 로 낮추고, 컨테이너 web 에 환경변수 LOG_LEVEL=debug 를 추가해야 합니다. 패치 파일의 metadata.name베이스에 적힌 원래 이름인 web 입니다. 베이스의 replicas 는 2 그대로여야 합니다. 다시 빌드해 out/dev.yaml 을 갱신하세요.

베이스는 건드리지 않습니다. 패치 파일에는 베이스에 적힌 원래 이름을 쓰고, 컨테이너 이름이 맞아야 병합이 됩니다.

설정 생성기와 해시 접미어 연결하기

dev 오버레이의 kustomization.yamlconfigMapGenerator 로 이름 app-config 인 ConfigMap 을 만드세요 (예: literalsLOG_FORMAT=json). 그리고 5번의 패치에서 컨테이너 webenvFromconfigMapRef.name: app-config 로 그것을 참조하게 하세요. 다시 빌드하면 ConfigMap 이름 끝에 내용 해시가 붙고 Deployment 의 참조 이름도 그 해시 이름으로 바뀌어 있어야 합니다. /root/gitops/kustomize/out/hash-note.txt 에 해시 접미어 덕분에 설정 변경이 파드 롤아웃으로 이어진다는 점을 한국어로 적으세요.

생성기가 만든 이름 끝에는 내용 해시가 붙습니다. 워크로드가 그 ConfigMap 을 참조하고 있으면 참조 이름도 함께 갱신됩니다 — 이게 왜 유용한지가 이 단계의 핵심입니다.

Helm 소스를 쓰는 Application 작성하기

argocd 네임스페이스에 kind: Application, metadata.name: platform-helm 을 만드세요. spec.source.helm.valueFilesvalues-prod.yaml 을, spec.source.helm.parameters 에 이름 image.tag 와 값(예: 1.27.3)을 넣고, spec.source.targetRevisionHEAD 가 아닌 고정 값(예: v1.4.0)으로 두세요.

환경별 값 파일과 배포마다 바뀌는 개별 파라미터는 서로 다른 자리에 들어갑니다. 리비전을 브랜치 최신으로 두면 같은 선언이 시점마다 다른 것을 배포합니다.

오버레이 기반 Application 과 prod 빌드

/root/gitops/kustomize/overlays/prod/ 오버레이를 만드세요 — resources../../base, namespacegitops-prod, 패치로 spec.replicas3 이상으로, images 로 이미지 태그를 dev 와 다르게(예: name: nginx, newTag: 1.27.3) 바꿉니다. 빌드 결과를 /root/gitops/kustomize/out/prod.yaml 로 저장하세요. 그다음 argocd 네임스페이스에 kind: Application, metadata.name: web-dev 를 만드세요 — spec.source.pathoverlays/dev 가 들어가야 하고, spec.source.kustomize.images 에 이미지 오버라이드를 최소 하나 넣습니다.

prod 오버레이는 dev 와 같은 베이스를 쓰되 네임스페이스·복제 수·이미지 태그가 달라야 합니다. Application 쪽에서도 이미지 태그를 갈아 끼우는 자리가 따로 있습니다.