CNPA — 클라우드 네이티브 플랫폼 엔지니어링 어소시에이트 · 골든 패스와 개발자 경험 · 실습
골든 패스 한 세트 만들기
목표
새 서비스 하나가 태어날 때 항상 함께 붙어야 하는 것들 — 표준 라벨, 리소스 요청/제한, 오토스케일, 중단 예산, 네트워크 정책 — 을 한 세트로 묶고, 가드레일이 걸린 네임스페이스에 실제로 올립니다. 이어서 같은 서비스를 Helm 차트로 포장해 환경별 values 로 분기하고 렌더 결과를 배포합니다.
왜 중요한가
골든 패스의 가치는 '무엇을 넣었는가'보다 '개발자가 요청하지 않았는데 들어 있는가'에 있습니다. 스캐폴드가 리소스 제한과 네트워크 정책을 기본으로 달아 주면, 그 규칙을 지키는 데 드는 개발자의 노력이 0 이 됩니다. 반대로 위키에 '반드시 제한을 설정하세요'라고 적어 두면 절반은 잊습니다. 가드레일의 위치도 같은 맥락입니다 — ResourceQuota 와 LimitRange 는 생성 시점에 즉시 판정하므로, 사후 감사 리포트보다 훨씬 나은 개발자 경험을 만듭니다. 특히 이 둘의 조합은 시험에 자주 나옵니다. 쿼터가 CPU 를 제한하면 요청을 명시하지 않은 파드는 거절되는데, LimitRange 의 기본값이 그 구멍을 메워 줍니다. 뒤쪽 Helm 부분은 '같은 스캐폴드를 값으로 분기한다'는 골든 패스의 두 번째 얼굴입니다 — 템플릿 하나로 dev 와 prod 를 동시에 만족시키는 방법입니다.
단계
1. /root/cnpa-path/manifests/deployment.yaml 에 Deployment payments 를 작성하세요 — spec.replicas: 2, 셀렉터·파드 라벨에 app.kubernetes.io/name: payments, 메타데이터 라벨에 app.kubernetes.io/name: payments 와 app.kubernetes.io/part-of: cnpa-platform, 컨테이너 이름 app, 이미지 ghcr.io/labhub/payments:1.0.0, containerPort 8080, resources.requests 는 cpu 100m / memory 128Mi, resources.limits 는 cpu 300m / memory 256Mi. /root/cnpa-path/manifests/service.yaml 에 Service payments 를 작성하세요 — type ClusterIP, port 80, targetPort 8080, 셀렉터 app.kubernetes.io/name: payments.
2. /root/cnpa-path/manifests/hpa.yaml 에 HorizontalPodAutoscaler payments(apiVersion autoscaling/v2, scaleTargetRef 는 apps/v1 Deployment payments, minReplicas: 2, maxReplicas: 6, cpu Utilization 목표 70)를 작성하세요. /root/cnpa-path/manifests/pdb.yaml 에 PodDisruptionBudget payments(minAvailable: 1, 셀렉터 app.kubernetes.io/name: payments)를, /root/cnpa-path/manifests/netpol.yaml 에 NetworkPolicy payments(podSelector 는 app.kubernetes.io/name: payments, policyTypes 첫 항목 Ingress, ingress 는 app.kubernetes.io/part-of: cnpa-platform 라벨을 가진 파드에서 TCP 8080 만 허용)를 작성하세요.
3. 네임스페이스 cnpa-app 을 만들고, 그 안에 ResourceQuota cnpa-app-quota(requests.cpu: "1", requests.memory: 1Gi, limits.cpu: "2", limits.memory: 2Gi, pods: "8")와 LimitRange cnpa-app-limits(type Container, default cpu 200m / memory 256Mi, defaultRequest cpu 100m / memory 128Mi)를 만드세요.
4. /root/cnpa-path/manifests/ 의 다섯 매니페스트를 모두 cnpa-app 네임스페이스에 적용하세요.
5. helm create /root/cnpa-path/payments 로 차트를 만들고, values.yaml 을 고치세요 — replicaCount: 2, image.repository: ghcr.io/labhub/payments, image.tag: "1.0.0".
6. /root/cnpa-path/payments/values-dev.yaml(replicaCount: 1, image.tag: "1.0.0")와 /root/cnpa-path/payments/values-prod.yaml(replicaCount: 3, image.tag: "1.2.0", fullnameOverride: payments-v2)를 만드세요. 그다음 helm template payments-v2 /root/cnpa-path/payments -f /root/cnpa-path/payments/values-prod.yaml -n cnpa-app 결과를 /root/cnpa-path/render-prod.yaml 에 저장하세요.
7. /root/cnpa-path/render-prod.yaml 을 cnpa-app 네임스페이스에 적용하세요. 적용 후 payments-v2 Deployment 가 replicas 3, 이미지 ghcr.io/labhub/payments:1.2.0 으로 떠 있어야 하고, 3 단계의 쿼터는 그대로 남아 있어야 합니다.
참고
- 디렉터리 전체 적용은
kubectl apply -n cnpa-app -f /root/cnpa-path/manifests/입니다. helm template은 클러스터에 아무것도 만들지 않습니다. 렌더 결과만 표준 출력으로 나옵니다.fullnameOverride를 주면 helm 이 만드는 리소스 이름이 그 값으로 고정됩니다. 4 단계에서 올린payments와 이름이 겹치지 않게 하는 장치입니다.- 흔한 실수 1: HPA 의
scaleTargetRef.apiVersion을 빼먹는 것. Deployment 는apps/v1입니다. - 흔한 실수 2: NetworkPolicy 의
policyTypes를 생략하는 것. 생략하면 규칙이 있는 방향만 적용되어 의도와 달라질 수 있습니다.
단계 7개
- 서비스 스캐폴드 — Deployment 와 Service
- HPA · PDB · NetworkPolicy
- 가드레일이 있는 네임스페이스
- 스캐폴드를 클러스터에 적용
- helm create 로 로컬 차트
- 환경별 values 와 렌더 확인
- 렌더 결과를 가드레일 안에 배포