본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout
TechProjectsBooksAbout
© 2026 Kreath. All rights reserved.
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 9장: 보안 강화와 정책 관리
2026년 6월 3일·인프라·

9장: 보안 강화와 정책 관리

OPA/Gatekeeper, Kyverno, Pod Security Standards, RBAC 모범 사례, External Secrets Operator, 공급망 보안(SLSA, Sigstore), 이미지 서명을 다룹니다.

11분917자7개 섹션
kubernetesci-cdinfrastructureautomationobservability
공유
kubernetes-gitops9 / 10
12345678910
이전8장: Crossplane - 인프라를 코드로 관리하기다음10장: 실전 프로젝트 - GitOps 기반 Kubernetes 플랫폼 구축

지금까지 배포, 스케일링, 비용 최적화, 인프라 관리를 다루었습니다. 하지만 이 모든 것이 적절한 보안 없이는 의미가 없습니다. Kubernetes 클러스터는 공격 표면(Attack Surface)이 넓고, 잘못된 설정 하나가 심각한 보안 사고로 이어질 수 있습니다. 이번 장에서는 Kubernetes 보안의 핵심 영역인 정책 관리, 시크릿 관리, 공급망 보안을 다루겠습니다.

정책 엔진

OPA/Gatekeeper

O픈 폴리시 에이전트(Open Policy Agent, OPA)는 CNCF Graduated 프로젝트로, 범용 정책 엔진입니다. Gatekeeper는 OPA를 Kubernetes Admission Controller로 통합한 프로젝트입니다.

ConstraintTemplate 정의

Gatekeeper에서 정책은 ConstraintTemplate과 Constraint 두 단계로 정의됩니다.

constraint-template.yaml
yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels
 
        violation[{"msg": msg}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Missing required labels: %v", [missing])
        }

Constraint 적용

constraint.yaml
yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: require-team-labels
spec:
  enforcementAction: deny  # deny | dryrun | warn
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment", "StatefulSet"]
    namespaces:
      - production
      - staging
  parameters:
    labels:
      - "app.kubernetes.io/name"
      - "app.kubernetes.io/part-of"
      - "cost.example.com/team"
Tip

새로운 정책을 도입할 때는 반드시 enforcementAction: dryrun으로 먼저 배포하여 기존 리소스에 미치는 영향을 파악하십시오. Gatekeeper의 감사(Audit) 기능으로 위반 현황을 확인한 후, 점진적으로 warn 그리고 deny로 전환하는 것이 안전합니다.

Kyverno

Kyverno는 Kubernetes 네이티브 정책 엔진으로, Rego 대신 YAML로 정책을 작성합니다. 학습 곡선이 낮아 많은 팀에서 선호합니다.

kyverno-require-labels.yaml
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
  annotations:
    policies.kyverno.io/title: Require Labels
    policies.kyverno.io/severity: medium
spec:
  validationFailureAction: Enforce  # Enforce | Audit
  background: true
  rules:
    - name: check-team-label
      match:
        any:
          - resources:
              kinds:
                - Deployment
                - StatefulSet
              namespaces:
                - production
                - staging
      validate:
        message: "The label 'cost.example.com/team' is required."
        pattern:
          metadata:
            labels:
              cost.example.com/team: "?*"

Kyverno의 고유 기능: Mutate와 Generate

Kyverno는 정책 검증 외에도 리소스 변환(Mutate)과 자동 생성(Generate) 기능을 제공합니다.

kyverno-mutate.yaml
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-security-context
spec:
  rules:
    - name: add-run-as-non-root
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          spec:
            securityContext:
              runAsNonRoot: true
              seccompProfile:
                type: RuntimeDefault
            containers:
              - (name): "*"
                securityContext:
                  allowPrivilegeEscalation: false
                  readOnlyRootFilesystem: true
                  capabilities:
                    drop:
                      - ALL
kyverno-generate.yaml
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-network-policy
spec:
  rules:
    - name: default-deny-ingress
      match:
        any:
          - resources:
              kinds:
                - Namespace
      generate:
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny-ingress
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress

Gatekeeper vs Kyverno

기준GatekeeperKyverno
정책 언어Rego (전용 언어)YAML (Kubernetes 네이티브)
학습 곡선높음 (Rego 학습 필요)낮음 (YAML만 알면 됨)
기능ValidateValidate, Mutate, Generate, Verify Image
감사별도 감사 모드배경 스캔 기본 제공
생태계OPA 생태계 공유 (Kubernetes 외에도 활용)Kubernetes 전용

Pod Security Standards

Kubernetes 1.25부터 Pod 보안 표준(Pod Security Standards, PSS)이 PodSecurityPolicy를 대체했습니다. 세 가지 보안 수준을 정의합니다.

namespace-pss.yaml
yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    # PSS 적용
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Privileged: 제한 없음. 시스템 컴포넌트용.

Baseline: 알려진 권한 상승을 방지. hostNetwork, hostPID, privileged 컨테이너를 차단합니다.

Restricted: 최소 권한 원칙 적용. non-root 실행, 모든 capability 드롭, seccomp 프로필 필수입니다.

Info

PSS의 restricted 수준을 모든 프로덕션 네임스페이스에 적용하는 것을 권장합니다. 처음에는 warn 모드로 적용하여 위반 사항을 파악하고, 애플리케이션을 수정한 후 enforce 모드로 전환하십시오.

RBAC 모범 사례

최소 권한 원칙

rbac-dev-team.yaml
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: backend
rules:
  # Pod 조회 및 로그 확인만 허용
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  # Deployment 조회만 허용 (수정 불가)
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch"]
  # ConfigMap/Secret은 조회만
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list"]
  # Secret은 조회 불가 (보안)
  # - apiGroups: [""]
  #   resources: ["secrets"]
  #   verbs: []
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: backend
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: developer
subjects:
  - kind: Group
    name: backend-developers
    apiGroup: rbac.authorization.k8s.io
Warning

cluster-admin ClusterRoleBinding은 절대 일반 사용자에게 부여하지 마십시오. 네임스페이스 범위의 Role/RoleBinding을 우선 사용하고, 클러스터 범위가 필요한 경우에만 ClusterRole을 최소한의 권한으로 정의하십시오.

시크릿 관리

External Secrets Operator

External Secrets Operator(ESO)는 외부 시크릿 저장소(AWS Secrets Manager, HashiCorp Vault 등)의 시크릿을 Kubernetes Secret으로 동기화합니다.

external-secret.yaml
yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secrets
  namespace: production
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-northeast-2
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets
    kind: SecretStore
  target:
    name: database-credentials
    creationPolicy: Owner
    template:
      type: Opaque
      data:
        DATABASE_URL: "postgresql://{{ .username }}:{{ .password }}@{{ .host }}:5432/appdb"
  data:
    - secretKey: username
      remoteRef:
        key: production/database
        property: username
    - secretKey: password
      remoteRef:
        key: production/database
        property: password
    - secretKey: host
      remoteRef:
        key: production/database
        property: host

Sealed Secrets

Sealed Secrets는 시크릿을 암호화하여 Git에 안전하게 저장할 수 있게 합니다.

sealed-secret.sh
bash
# kubeseal로 Secret을 SealedSecret으로 변환
kubectl create secret generic api-key \
  --from-literal=key=my-secret-api-key \
  --dry-run=client -o yaml | \
kubeseal \
  --controller-name=sealed-secrets \
  --controller-namespace=kube-system \
  --format=yaml > sealed-api-key.yaml
sealed-secret.yaml
yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: api-key
  namespace: production
spec:
  encryptedData:
    key: AgBy3i4OJSWK+PiTySYZZA9rO... # 암호화된 값
  template:
    type: Opaque
Info

External Secrets Operator와 Sealed Secrets 중 선택할 때, 이미 AWS Secrets Manager나 HashiCorp Vault를 사용하고 있다면 ESO가 더 적합합니다. 별도의 시크릿 관리 시스템이 없다면 Sealed Secrets가 더 간단합니다. 두 도구 모두 GitOps 워크플로우와 자연스럽게 통합됩니다.

공급망 보안 (Supply Chain Security)

SLSA 프레임워크

SLSA(Supply chain Levels for Software Artifacts)는 소프트웨어 공급망 보안을 위한 프레임워크입니다. 빌드 과정의 무결성을 보장하는 4단계 성숙도 모델을 정의합니다.

Level 1: 빌드 프로세스 문서화
  → 빌드가 어떻게 수행되었는지 기록

Level 2: 빌드 서비스 사용
  → 호스팅된 빌드 서비스에서 빌드 수행

Level 3: 소스와 빌드 무결성
  → 소스 코드의 출처 검증, 빌드 환경 격리

Level 4: 양방향 검증
  → 모든 종속성의 출처 검증

Sigstore를 활용한 이미지 서명

Sigstore는 소프트웨어 아티팩트에 디지털 서명을 하는 오픈소스 프로젝트입니다. Cosign 도구를 사용하여 컨테이너 이미지에 서명하고 검증합니다.

cosign-sign.sh
bash
# 이미지 서명 (키리스 방식 - OIDC 인증)
cosign sign --yes ghcr.io/org/api-server:v1.2.3
 
# 서명 검증
cosign verify \
  --certificate-identity=ci@org.com \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  ghcr.io/org/api-server:v1.2.3

Kyverno로 서명된 이미지만 허용

kyverno-verify-image.yaml
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/org/*"
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/org/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: https://rekor.sigstore.dev
          mutateDigest: true
          verifyDigest: true

GitHub Actions CI 파이프라인 예시

.github/workflows/build-sign.yaml
yaml
name: Build, Sign, and Push
on:
  push:
    branches: [main]
 
permissions:
  contents: read
  packages: write
  id-token: write  # Cosign 키리스 서명에 필요
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - uses: docker/build-push-action@v6
        id: build
        with:
          push: true
          tags: ghcr.io/org/api-server:${{ github.sha }}
 
      - uses: sigstore/cosign-installer@v3
 
      - name: Sign image
        run: |
          cosign sign --yes \
            ghcr.io/org/api-server@${{ steps.build.outputs.digest }}
 
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/org/api-server@${{ steps.build.outputs.digest }}
          format: spdx-json
          output-file: sbom.spdx.json
 
      - name: Attach SBOM to image
        run: |
          cosign attach sbom \
            --sbom sbom.spdx.json \
            ghcr.io/org/api-server@${{ steps.build.outputs.digest }}

정리

Kubernetes 보안은 정책 관리(Gatekeeper/Kyverno), 접근 제어(RBAC/PSS), 시크릿 관리(ESO/Sealed Secrets), 공급망 보안(SLSA/Sigstore)의 네 가지 축으로 구성됩니다. 모든 보안 설정은 GitOps로 관리하여 변경 이력을 추적하고, 정책 코드 리뷰를 통해 실수를 방지해야 합니다.

다음 장에서는 이 시리즈에서 다룬 모든 내용을 종합하여 실전 프로젝트 -- GitOps 기반 Kubernetes 플랫폼 구축을 진행하겠습니다. ArgoCD, Karpenter, Crossplane, Kyverno를 통합하여 완전한 플랫폼을 구축하는 과정을 단계별로 안내합니다.

이 글이 도움이 되셨나요?

관련 글

인프라

10장: 실전 프로젝트 - GitOps 기반 Kubernetes 플랫폼 구축

ArgoCD, Karpenter, Crossplane, Kyverno를 통합한 GitOps 기반 Kubernetes 플랫폼을 구축합니다. app-of-apps 패턴, 환경 프로모션, 모니터링, Day-2 운영 체크리스트를 다룹니다.

2026년 6월 6일·14분
인프라

8장: Crossplane - 인프라를 코드로 관리하기

Crossplane의 아키텍처, Provider와 Managed Resource, XRD와 Composition을 활용한 인프라 추상화, GitOps 통합, Terraform과의 비교를 다룹니다.

2026년 5월 30일·12분
인프라

7장: 비용 최적화와 리소스 관리

Kubernetes 리소스 requests/limits 모범 사례, VPA/HPA 전략, Goldilocks, Kubecost/OpenCost, 스팟 인스턴스, 네임스페이스 쿼터, FinOps 실천법을 다룹니다.

2026년 5월 27일·14분
이전 글8장: Crossplane - 인프라를 코드로 관리하기
다음 글10장: 실전 프로젝트 - GitOps 기반 Kubernetes 플랫폼 구축

댓글

목차

약 11분 남음
  • 정책 엔진
    • OPA/Gatekeeper
      • ConstraintTemplate 정의
      • Constraint 적용
    • Kyverno
      • Kyverno의 고유 기능: Mutate와 Generate
    • Gatekeeper vs Kyverno
  • Pod Security Standards
  • RBAC 모범 사례
    • 최소 권한 원칙
  • 시크릿 관리
    • External Secrets Operator
    • Sealed Secrets
  • 공급망 보안 (Supply Chain Security)
    • SLSA 프레임워크
    • Sigstore를 활용한 이미지 서명
    • Kyverno로 서명된 이미지만 허용
  • GitHub Actions CI 파이프라인 예시
  • 정리