LabHub
배우기 러닝패스 코스

CGOA — GitOps Certified Associate

Building the Skeleton of a GitOps Repository

LabHub 에서 이어서 보기

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

목표

GitOps 설정 저장소의 표준 레이아웃을 직접 만들고, 같은 base 가 환경마다 다른 최종 매니페스트로 렌더되는 것을 눈으로 확인합니다. 마지막에는 그 저장소를 Argo CD 에 물리는 Application·AppProject·app-of-apps 루트까지 파일로 완성합니다.

왜 중요한가

GitOps 에서 저장소 구조는 취향 문제가 아니라 운영 비용을 결정하는 설계 입니다. base 와 오버레이가 제대로 갈려 있으면 stage 에서 prod 로 올리는 PR 의 diff 가 이미지 태그 한 줄이 되고, 리뷰어는 "설정은 그대로이고 버전만 올라간다"를 눈으로 확인할 수 있습니다. 반대로 환경별로 YAML 을 통째로 복사해 두면 승격 PR 마다 수십 줄이 바뀌고, 어느 줄이 의도된 차이인지 아무도 모르게 됩니다. 이 실습에서 만드는 Application 과 AppProject 는 실습 환경에 Argo CD CRD 가 없으므로 파일로만 작성하며, 채점은 그 파일을 읽어서 합니다. 실제 운영에서도 이 파일들은 Git 에 커밋되는 산출물이므로 형태를 정확히 익히는 것이 그대로 실무입니다.

단계

  1. /root/cgoa-repo/apps/checkout/base, /root/cgoa-repo/apps/checkout/overlays/dev, /root/cgoa-repo/apps/checkout/overlays/stage, /root/cgoa-repo/apps/checkout/overlays/prod, /root/cgoa-repo/bootstrap 디렉터리를 만드세요.
  2. base/deployment.yaml 에 Deployment checkout 을 작성하세요 — spec.replicas: 1, 셀렉터와 파드 라벨 모두 app: checkout, 컨테이너 이름 app, 이미지 ghcr.io/labhub/checkout:1.4.0, containerPort 8080. base/service.yaml 에 Service checkout 을 작성하세요 — spec.ports[0].port: 80, targetPort: 8080, 셀렉터 app: checkout. base/kustomization.yamlresources 에 두 파일을 나열하세요.
  3. overlays/dev/kustomization.yamlresources: [../../base], namespace: cgoa-dev, namePrefix: dev- 를 쓰세요. overlays/stage/kustomization.yaml 에는 resources: [../../base], namespace: cgoa-stage, namePrefix: stage-, 그리고 replicascheckout2 로 지정하세요.
  4. overlays/prod/kustomization.yamlresources: [../../base], namespace: cgoa-prod, namePrefix: prod-, replicascheckout3, imagesghcr.io/labhub/checkoutnewTag1.5.0 으로 지정하세요.
  5. kubectl kustomize /root/cgoa-repo/apps/checkout/overlays/prod 의 출력을 /root/cgoa-repo/render-prod.yaml 에 저장하세요.
  6. /root/cgoa-repo/bootstrap/app-checkout-prod.yaml 에 Argo CD Application 을 작성하세요 — apiVersion: argoproj.io/v1alpha1, kind: Application, metadata.name: checkout-prod, metadata.namespace: argocd, spec.project: checkout, spec.source.repoURL: http://10.0.0.200/labhub/gitops.git, spec.source.path: apps/checkout/overlays/prod, spec.source.targetRevision: main, spec.destination.server: https://kubernetes.default.svc, spec.destination.namespace: cgoa-prod, spec.syncPolicy.automated.prune: true, spec.syncPolicy.automated.selfHeal: true, spec.syncPolicy.syncOptions 첫 항목 CreateNamespace=true.
  7. /root/cgoa-repo/bootstrap/root-app.yaml 에 app-of-apps 루트 Application 을 작성하세요 — 이름 root, 네임스페이스 argocd, spec.project: checkout, spec.source.path: bootstrap, spec.source.directory.recurse: true, spec.destination.namespace: argocd, 자동 동기화(prune·selfHeal 모두 true).
  8. /root/cgoa-repo/bootstrap/project-checkout.yaml 에 AppProject checkout 을 작성하세요 — metadata.namespace: argocd, spec.sourceRepos 첫 항목 http://10.0.0.200/labhub/gitops.git, spec.destinations[0].server: https://kubernetes.default.svc, spec.destinations[0].namespace: cgoa-*, spec.clusterResourceWhitelist[0] 은 group "" 에 kind Namespace.

참고

저장소 디렉터리 뼈대

/root/cgoa-repo/apps/checkout/base, /root/cgoa-repo/apps/checkout/overlays/dev, /root/cgoa-repo/apps/checkout/overlays/stage, /root/cgoa-repo/apps/checkout/overlays/prod, /root/cgoa-repo/bootstrap 디렉터리를 만드세요.

베이스 하나에 환경 오버레이 셋, 그리고 Application 매니페스트를 모아 둘 bootstrap 디렉터리가 필요합니다. 상위 경로까지 한 번에 만드는 mkdir 옵션을 쓰세요.

base 매니페스트와 kustomization

base/deployment.yaml 에 Deployment checkout 을 작성하세요 — spec.replicas: 1, 셀렉터와 파드 라벨 모두 app: checkout, 컨테이너 이름 app, 이미지 ghcr.io/labhub/checkout:1.4.0, containerPort 8080. base/service.yaml 에 Service checkout 을 작성하세요 — spec.ports[0].port: 80, targetPort: 8080, 셀렉터 app: checkout. base/kustomization.yamlresources 에 두 파일을 나열하세요.

base 는 환경에 무관한 공통분모만 담습니다. 네임스페이스도 replicas 도 여기서 정하지 않는 편이 좋습니다. kustomization.yaml 의 resources 에 파일 이름을 나열하세요.

dev·stage 오버레이

overlays/dev/kustomization.yamlresources: [../../base], namespace: cgoa-dev, namePrefix: dev- 를 쓰세요. overlays/stage/kustomization.yaml 에는 resources: [../../base], namespace: cgoa-stage, namePrefix: stage-, 그리고 replicascheckout2 로 지정하세요.

오버레이의 resources 는 상대 경로로 base 를 가리킵니다. 이름 충돌을 막는 접두어 필드와 네임스페이스 필드를 kustomization.yaml 에서 지정할 수 있습니다.

prod 오버레이 — replicas 와 이미지 태그

overlays/prod/kustomization.yamlresources: [../../base], namespace: cgoa-prod, namePrefix: prod-, replicascheckout3, imagesghcr.io/labhub/checkoutnewTag1.5.0 으로 지정하세요.

kustomize 에는 replicas 를 이름으로 지정해 바꾸는 필드와, 이미지 이름을 찾아 태그만 바꾸는 필드가 따로 있습니다. 패치 파일 없이 kustomization.yaml 안에서 끝낼 수 있습니다.

kubectl kustomize 로 렌더 결과 저장

kubectl kustomize /root/cgoa-repo/apps/checkout/overlays/prod 의 출력을 /root/cgoa-repo/render-prod.yaml 에 저장하세요.

kubectl kustomize <디렉터리> 는 오버레이를 적용한 최종 매니페스트를 표준 출력으로 뱉습니다. 클러스터에 적용하지 않고도 원하는 상태를 눈으로 볼 수 있습니다.

Argo CD Application 매니페스트

/root/cgoa-repo/bootstrap/app-checkout-prod.yaml 에 Argo CD Application 을 작성하세요 — apiVersion: argoproj.io/v1alpha1, kind: Application, metadata.name: checkout-prod, metadata.namespace: argocd, spec.project: checkout, spec.source.repoURL: http://10.0.0.200/labhub/gitops.git, spec.source.path: apps/checkout/overlays/prod, spec.source.targetRevision: main, spec.destination.server: https://kubernetes.default.svc, spec.destination.namespace: cgoa-prod, spec.syncPolicy.automated.prune: true, spec.syncPolicy.automated.selfHeal: true, spec.syncPolicy.syncOptions 첫 항목 CreateNamespace=true.

Application 은 source(어디서), destination(어디로), syncPolicy(어떻게) 세 덩어리입니다. 자동 동기화와 자기 치유, 그리고 네임스페이스 자동 생성 옵션이 어디에 들어가는지 확인하세요.

app-of-apps 루트 Application

/root/cgoa-repo/bootstrap/root-app.yaml 에 app-of-apps 루트 Application 을 작성하세요 — 이름 root, 네임스페이스 argocd, spec.project: checkout, spec.source.path: bootstrap, spec.source.directory.recurse: true, spec.destination.namespace: argocd, 자동 동기화(prune·selfHeal 모두 true).

루트는 자식 Application 파일들이 든 디렉터리를 source.path 로 가리키고, 그 디렉터리를 재귀적으로 읽도록 설정합니다. destination 은 Argo CD 자신이 사는 네임스페이스입니다.

AppProject 로 경계 긋기

/root/cgoa-repo/bootstrap/project-checkout.yaml 에 AppProject checkout 을 작성하세요 — metadata.namespace: argocd, spec.sourceRepos 첫 항목 http://10.0.0.200/labhub/gitops.git, spec.destinations[0].server: https://kubernetes.default.svc, spec.destinations[0].namespace: cgoa-*, spec.clusterResourceWhitelist[0] 은 group "" 에 kind Namespace.

AppProject 는 이 프로젝트의 Application 이 어떤 저장소에서, 어느 클러스터·네임스페이스로, 어떤 클러스터 스코프 리소스를 만들 수 있는지 제한합니다. 6 단계에서 만든 Application 의 project 값과 이름이 맞아야 합니다.