클러스터 네트워크 정책 구성

ClusterNetworkPolicy를 사용하면 전체 클러스터에서 전역 GKE 보안 상황을 정의할 수 있습니다. 이 문서는 필수 보안 가이드레일을 적용하거나 제로 트러스트 기준을 설정해야 하는 클러스터 관리자를 대상으로 합니다.

이 리소스는 표준 네임스페이스 범위 NetworkPolicy 리소스보다 우선순위가 높은 엄격한 평가 계층 구조를 사용합니다. ClusterNetworkPolicy 리소스를 사용하여 명시적 거부, 수락 또는 통과 작업을 구현할 수 있습니다. 이러한 작업을 통해 전역 허용 또는 거부 정책을 구성하고, 특정 네임스페이스에 트래픽 제어를 위임하고, 이그레스 트래픽을 CIDR 블록으로 제한할 수 있습니다.

시작하기 전에

클러스터 네트워크 정책을 구성하기 전에 다음 요구사항을 충족하는지 확인하세요.

  1. GKE 클러스터에서 버전 1.36.0-gke.4447000 이상을 실행하는지 확인합니다.
  2. 클러스터가 GKE Dataplane V2를 사용하는지 확인합니다.

지원되는 프로토콜 및 포트

ClusterNetworkPolicy 규칙은 TCP, UDP 또는 SCTP 프로토콜을 기반으로 트래픽을 일치시킬 수 있습니다. 다음과 같은 방법으로 목적지 포트를 지정할 수 있습니다.

  • 특정 포트 번호: destinationPort.number 설정을 사용하여 단일 포트 (예: 80)를 타겟팅합니다.
  • 포트 범위: destinationPort.range 설정을 사용하여 포트 범위를 타겟팅합니다 (예: 8000~9000).
  • 명명된 포트: destinationNamedPort 설정을 사용하여 포드 사양에 정의된 기호 이름을 타겟팅합니다.

정책 평가 계층 구조

표준 가산 NetworkPolicy와 달리 ClusterNetworkPolicy (CNP)는 첫 번째 일치 규칙이 우선하는 엄격한 평가 계층 구조를 사용합니다. 트래픽은 다음 세 가지 레이어 파이프라인을 통해 순차적으로 흐릅니다.

  • 등급: 관리자 규칙이 먼저 실행되고 NetworkPolicy, 기준 순으로 하향식으로 적용됩니다.
  • CNP 우선순위: 등급 내에서 정책은 명시적인 숫자 우선순위에 따라 평가됩니다.
  • CNP 규칙 순서: 단일 정책 내에서 규칙은 액세스 제어 목록 (ACL)과 같이 위에서 아래로 처리됩니다.

GKE 네트워크 정책 평가 계층 구조를 보여주는 다이어그램

위 다이어그램은 CNP 평가 계층 구조의 결정 흐름을 보여줍니다.

  1. 관리자 등급: 트래픽은 먼저 Admin 등급의 ClusterNetworkPolicy 규칙에 따라 평가됩니다. 허용 또는 거부 일치가 있으면 평가가 중지됩니다. 일치하는 항목이 없거나 Pass 작업이 있는 경우 트래픽은 NetworkPolicy 등급으로 진행됩니다.
  2. NetworkPolicy 등급: 트래픽이 표준 네임스페이스 정책에 따라 평가됩니다. 일치하는 항목이 있으면 트래픽이 허용됩니다. 일치하는 항목이 없으면 트래픽은 기준 등급으로 진행됩니다.
  3. 기준 등급: 트래픽이 기준 등급의 ClusterNetworkPolicy 규칙에 따라 평가됩니다. 허용 또는 거부 일치가 있으면 평가가 중지됩니다. 일치하는 항목이 없으면 트래픽은 기본 동작으로 진행됩니다.
  4. 기본 GKE 동작: 어떤 등급에서도 일치하는 정책이 없으면 트래픽에 암시적 허용 동작이 적용됩니다.

결과 작업: 허용, 거부, 통과

패킷이 일치하면 모든 규칙은 다음 세 가지 엄격한 작업 중 하나를 트리거합니다.

  • 거부: 트래픽을 즉시 차단합니다.
  • 수락: 트래픽을 허용합니다. 두 작업 모두 파이프라인을 즉시 단락시켜 나머지 모든 정책을 무시합니다.
  • Pass: 제어권을 다음 계층으로 전달하여 플랫폼 엔지니어가 전반적인 관리 제어권을 포기하지 않고도 특정 트래픽 결정을 표준 네임스페이스 수준 정책에 위임할 수 있습니다.

전역 거부 정책 구성

민감한 네임스페이스를 다른 모든 클러스터 내부 트래픽과 격리하려면 재정의할 수 없는 거부 규칙을 적용합니다. 이 기본 거부 정책은 민감한 네임스페이스로 오가는 모든 트래픽이 관리 수준에서 차단되도록 합니다. 이 정책은 네임스페이스 수준 규칙에 의해 실수로 우회될 수 없는 보호 기준선 역할을 합니다.

  1. 다음 매니페스트를 global-deny.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: cluster-wide-deny-sensitive
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            kubernetes.io/metadata.name: sensitive-ns
      ingress:
      - action: Deny
        name: deny-all-ingress
        from:
        - namespaces:
            matchLabels: {}
      egress:
      - action: Deny
        name: deny-all-egress
        to:
        - namespaces:
            matchLabels: {}
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f global-deny.yaml
    

전역 허용 정책 구성

전역 허용 정책을 사용하면 개발자가 만든 네트워크 정책과 관계없이 모든 포드가 클러스터 DNS 서비스에 도달할 수 있습니다.

  1. 다음 매니페스트를 global-allow-dns.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-kube-dns-admin
    spec:
      tier: Admin
      priority: 20
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-dns-egress
        to:
        - pods:
            namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: kube-system
            podSelector:
              matchLabels:
                k8s-app: kube-dns
        protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f global-allow-dns.yaml
    

트래픽을 네임스페이스 정책에 위임

특정 트래픽 패턴을 표준 네임스페이스 범위 NetworkPolicy 객체에 위임합니다.

  1. 다음 매니페스트를 delegate-policy.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: delegate-to-netpol
    spec:
      tier: Admin
      priority: 30
      subject:
        namespaces: {}
      egress:
      - action: Pass
        name: delegate-web-traffic
        to:
        - namespaces:
            matchLabels:
              app: web-backend
        protocols:
        - tcp:
            destinationPort:
              number: 8080
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f delegate-policy.yaml
    
  3. 타겟 네임스페이스 내에서 위임된 트래픽을 허용하려면 다음 표준 NetworkPolicy 매니페스트를 allow-web-backend.yaml로 저장합니다.

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-web-backend
      namespace: backend-ns
    spec:
      podSelector:
        matchLabels:
          app: web-backend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              app: web-frontend
        ports:
        - protocol: TCP
          port: 8080
    
  4. 표준 NetworkPolicy 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f allow-web-backend.yaml
    

기준 가드레일 구성

네임스페이스 관리자가 표준 네트워크 정책을 사용하여 재정의할 수 있는 기본 GKE 보안 상황을 설정합니다.

  1. 다음 기준 매니페스트를 baseline-deny.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: default-deny-baseline
    spec:
      tier: Baseline
      priority: 100
      subject:
        namespaces: {}
      ingress:
      - action: Deny
        name: baseline-deny-all
        from:
        - namespaces: {}
    
  2. 기준 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f baseline-deny.yaml
    
  3. 다음 개발자 재정의 매니페스트를 developer-allow.yaml로 저장합니다.

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend-access
      namespace: my-app-ns
    spec:
      podSelector:
        matchLabels:
          app: frontend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
    
  4. 재정의 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f developer-allow.yaml
    

이름이 지정된 포트를 사용하여 정책 구성

보안 정책에서 포트 번호를 추상화하려면 포드 사양에 정의된 이름이 지정된 포트를 참조하세요.

  1. 다음 배포 매니페스트를 app-deployment.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-webapp
    spec:
      template:
        spec:
          containers:
          - name: web-container
            image: nginx
            ports:
            - name: http-web
              containerPort: 8080
    
  2. 배포 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f app-deployment.yaml
    
  3. 다음 정책 매니페스트를 named-port-policy.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-web-named-port
    spec:
      tier: Admin
      priority: 40
      subject:
        namespaces: {}
      egress:
      - action: Accept
        to:
        - namespaces:
            matchLabels:
              app: my-webapp
        protocols:
        - tcp:
            destinationNamedPort: http-web
    
  4. 정책 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f named-port-policy.yaml
    

이그레스를 CIDR 블록으로 제한

CIDR 블록을 지정하여 외부 리소스 또는 회사 인트라넷에 대한 액세스를 제어합니다.

  1. 다음 매니페스트를 cidr-policy.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-egress-to-intranet
    spec:
      tier: Admin
      priority: 60
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-intranet
        to:
        - networks:
          - 10.0.0.0/8
          - 192.168.0.0/16
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f cidr-policy.yaml
    

우선순위 우선순위 구성

동일한 포드에 여러 정책이 적용될 때 평가 순서를 제어하려면 우선순위를 지정하세요. 우선순위는 0~1000이며, 숫자가 낮을수록 우선순위가 높습니다. 단일 ClusterNetworkPolicy 객체에는 최대 100개의 인그레스 규칙과 100개의 이그레스 규칙이 포함될 수 있습니다.

  1. 다음 매니페스트를 priority-policies.yaml로 저장합니다.

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: deny-beta
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-beta-monitoring
        from:
        - pods:
            namespaceSelector:
              matchLabels:
                team: beta
            podSelector:
              matchLabels:
                app: monitoring
      - action: Deny
        name: deny-all-other-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    ---
    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-beta
    spec:
      tier: Admin
      priority: 50
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-all-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f priority-policies.yaml
    

문제 해결

정책 오류를 진단하고 해결하는 방법을 찾으려면 다음 명령어를 사용합니다.

클러스터의 모든 클러스터 네트워크 정책을 나열합니다.

kubectl get clusternetworkpolicies

특정 정책을 설명하여 상태 및 평가 등급을 검사합니다.

kubectl describe clusternetworkpolicy/<policy-name>

출력의 status.conditions 필드는 클러스터의 네트워킹 구현에 의해 정책이 성공적으로 조정되었는지에 관한 정보를 제공합니다.

트래픽 흐름 및 정책 결정을 모니터링하려면 GKE Dataplane V2 관측 가능성을 사용합니다.

다음 단계