본문으로 건너뛰기

워크로드 가드레일

이 페이지는 Lumie의 애플리케이션 계층 워크로드 가드레일에 대한 reference 문서입니다. Helm values 파일과 실제 실행 중인 워크로드 사이에 놓인 체크인된 안전 장치, 즉 PodDisruptionBudget, 네임스페이스 수준 NetworkPolicy, audit 모드 Kyverno 정책, 매니페스트에 아직 남아 있는 Goldilocks 인접 라벨을 다룹니다.

소스 경로

경로역할
lumie-infra/charts/common/values.yaml리소스 형태, 보안 컨텍스트, 롤아웃 전략, 선택적 PDB 설정을 포함한 공통 워크로드 기본값
lumie-infra/charts/common/templates/pdb.yaml공통 PDB 렌더링 계약
lumie-infra/applications/lumie/backend/common-values.yaml백엔드의 PDB, 리소스 요청, 보안 컨텍스트 opt-in
lumie-infra/applications/lumie/frontend/common-values.yaml프론트엔드의 PDB, 리소스 요청, 보안 컨텍스트 opt-in
lumie-infra/applications/lumie/worker/grading-svc/common-values.yaml워커의 PDB, 리소스 요청, 보안 컨텍스트 opt-in
lumie-infra/applications/lumie/{backend,frontend,worker/grading-svc,develop}/manifests/network-policy.yamldefault-deny와 명시적 allow를 조합한 NetworkPolicy 집합
lumie-infra/security/kyverno/argocd.yamlKyverno controller와 로컬 정책 집합을 위한 ArgoCD 애플리케이션
lumie-infra/security/kyverno/manifests/policies/*.yaml체크인된 validation 및 mutate 정책
lumie-infra/security/kyverno/manifests/policy-exceptions.yamlbootstrap, Falco, Tekton DinD, CNPG에 대한 명시적 예외
lumie-infra/observability/goldilocks/argocd.yaml저장소에 남아 있는 Goldilocks 애플리케이션 정의
lumie-infra/observability/kustomization.yaml현재 Goldilocks를 비활성화한 활성 observability 루트

가드레일 계층

계층위치오늘 수행하는 역할
공통 chart 기본값charts/common/values.yaml리소스, 보안 컨텍스트, 롤아웃 전략, affinity, 선택적 PDB의 기본 형태를 정의
애플리케이션별 opt-inapplications/lumie/**/common-values.yaml개별 워크로드마다 가드레일을 켜거나 조정
네임스페이스 NetworkPolicyapplications/lumie/**/manifests/network-policy.yamldefault-deny와 명시적 의존성 허용을 강제
admission 정책security/kyverno/manifests/**이미지 registry, 보안 컨텍스트, 리소스 정책을 감사하고 admission 시 CPU limit를 제거
권고 라벨ArgoCD 매니페스트의 goldilocks.fairwinds.com/enabled 라벨매니페스트에는 남아 있지만 Goldilocks 자체는 활성 observability 루트에 없음

PodDisruptionBudget 계약

공통 PDB 템플릿은 의도적으로 maxUnavailable 기반입니다.

대표 발췌:

spec:
maxUnavailable: {{ $comp.podDisruptionBudget.maxUnavailable | default 1 }}

템플릿 주석은 그 이유를 설명합니다. KEDA가 관리하는 워크로드가 복제본 1개로 줄어든 상태에서 minAvailable: 1을 쓰면 노드 드레인이 교착 상태에 빠질 수 있습니다.

현재 opt-in은 좁고 명시적입니다.

워크로드PDB 상태소스
lumie-backend활성, maxUnavailable: 1applications/lumie/backend/common-values.yaml
lumie-frontend활성, maxUnavailable: 1applications/lumie/frontend/common-values.yaml
grading-svc활성, maxUnavailable: 1applications/lumie/worker/grading-svc/common-values.yaml

모든 워크로드가 PDB를 상속받는다고 가정하면 안 됩니다. 공통 chart는 애플리케이션 values가 opt-in할 때만 PDB를 렌더링합니다.

NetworkPolicy 계약

Lumie는 네임스페이스 수준 default-deny 정책과 명시적 allow 목록을 사용합니다.

현재 체크인된 적용 범위:

  • lumie-dev: 공용 dev 네임스페이스 가드레일
  • lumie-backend: default-deny에 더해 Postgres, RabbitMQ, Redis, MinIO, Vault, 워커, DNS, HTTPS, Traefik, cert-manager, 프론트엔드에 대한 명시적 ingress 및 egress 허용
  • lumie-frontend: default-deny에 더해 backend, Vault, DNS, HTTPS, Traefik, cert-manager 허용
  • lumie-worker: grading-svc에 고정된 네임스페이스 전역 워커 가드레일이며, podSelector: {}를 사용해 lumie-worker의 모든 워커 pod에 적용

현재 상태에서 중요한 세부사항:

  • 운영 Traefik은 전용 traefik 네임스페이스가 아니라 kube-system에 있는 것이 전제입니다
  • 워커 정책은 의도적으로 모든 워커 의존성을 합친 union입니다
  • HTTPS egress는 체크인된 정책 모델에 FQDN 인지 egress가 없기 때문에 여전히 0.0.0.0/0을 사용합니다

마지막 항목은 누락이 아니라 설계입니다. 이를 문서에서 숨겨진 allow-list처럼 다시 쓰면 안 됩니다.

Kyverno 계약

Kyverno는 워크로드 가드레일의 일부이지만, 오늘 기준으로는 주된 차단 계층이 아닙니다.

현재 활성 체크인 정책:

정책현재 모드효과
require-zot-registryAuditzot.lumie-infra.com 밖의 container 또는 init-container 이미지를 표시
require-security-contextAuditrunAsNonRoot 누락, privileged container, 권한 상승 허용을 표시
require-resource-limitsAuditmemory request 또는 limit 누락, CPU request 누락, CPU limit 존재를 표시
remove-cpu-limitsadmission 시 mutate만 수행승인된 pod의 CPU limit를 제거

정책 예외도 체크인되어 있으며 운영상 의미가 있을 만큼 넓습니다.

  • argocd, cert-manager, external-secrets, vault, zot 같은 bootstrap 네임스페이스
  • Falco pod
  • Tekton DinD springboot-test task pod
  • CNPG cluster와 pooler pod

Goldilocks 인접 상태

매니페스트 라벨은 여전히 많은 ArgoCD 관리 네임스페이스와 애플리케이션에 goldilocks.fairwinds.com/enabled: 'true'를 붙이고 있지만, 활성 observability 루트는 다음을 주석 처리한 상태입니다.

  • goldilocks/argocd.yaml
  • vpa/argocd.yaml
  • blackbox-exporter/argocd.yaml

따라서 이 라벨은 오늘 기준으로 비활성 메타데이터일 뿐, 클러스터에서 권고나 VPA 가드레일이 실제로 동작한다는 증거가 아닙니다.

운영 실패 모드

실패 모드보통 어긋나는 지점
드레인 시 너무 많이 또는 너무 적게 축출됨애플리케이션 values가 공통 PDB 템플릿에 opt-in하지 않았거나, 롤아웃 전략 변경이 기대한 maxUnavailable 동작과 충돌
워크로드는 ArgoCD에서 Healthy지만 의존성에 도달하지 못함pod spec 자체는 유효하지만 네임스페이스의 NetworkPolicy allow 목록이 불완전
admission 로그에는 위반이 보이는데 배포는 성공함정책이 의도적으로 Audit이며 생성 자체를 막지 않음
라벨은 autosizing 권고가 있다고 보이는데 추천 결과가 없음Goldilocks가 활성 observability 루트에서 비활성화되어 있음
CPU limit가 계속 사라짐임의의 chart 드리프트가 아니라 remove-cpu-limits의 기대된 mutate 동작

검증

cd /Users/bluemayne/Projects/Lumie
rg -n "podDisruptionBudget:|maxUnavailable: 1" \
lumie-infra/applications/lumie/*/common-values.yaml
rg -n "default-deny-all|allow-egress-postgres|allow-egress-rabbitmq|allow-egress-vault|allow-egress-https|allow-ingress-from-traefik" \
lumie-infra/applications/lumie/{backend,frontend,worker/grading-svc,develop}/manifests/network-policy.yaml
rg -n "validationFailureAction|require-zot-registry|require-security-context|require-resource-limits|remove-cpu-limits" \
lumie-infra/security/kyverno/manifests
kubectl get poddisruptionbudgets -A
kubectl get networkpolicy -A
kubectl get clusterpolicy
kubectl get policyexception -n kyverno

성공은 체크인된 PDB opt-in이 실제 객체와 일치하고, 보호된 네임스페이스에 default-deny 정책이 존재하며, Kyverno가 문서화된 audit 모드 정책 집합과 예외를 계속 노출한다는 뜻입니다.