호스트 정책

호스트 정책 (Host Policies)

CiliumClusterwideNetworkPolicy와 Node Selector를 사용해 Kubernetes 노드 자체에 적용하는 호스트 정책을 설명하는 문서예요. 활성화 방법, L3/L4/DNS 규칙, 문제 해결, 알려진 이슈를 다뤄요.

출처: Host Policies

본문

호스트 정책은 Endpoint Selector 대신 Node Selector를 사용하는 CiliumClusterwideNetworkPolicy의 형태를 가져요. 호스트 정책은 ingress와 egress 모두에서 레이어 3과 레이어 4 규칙을 가질 수 있어요. 또한 레이어 7 DNS 규칙을 가질 수 있지만, 다른 종류의 레이어 7 규칙은 가질 수 없어요.

참고: 호스트 L7 DNS 정책은 베타 기능이에요. 문제가 발생하면 피드백을 주고 GitHub issue를 제출해 주세요.

주의: 호스트 정책에 레이어 7 DNS 규칙을 추가하면, 모든 호스트 DNS 요청이 각 Cilium 에이전트에 제공되는 DNS 프록시를 거치게 되는 대가로 DNS 기반 호스트 정책이 활성화돼요. 여기에는 kubelet 같은 중요 프로세스가 FQDN으로 구성된(예: 관리형 Kubernetes 클러스터에서) kube-apiserver용 DNS 요청도 포함돼요. 이는 노드의 정상 동작에 중요한 의미를 갖는데, Cilium 에이전트가 재시작되는 동안 DNS 프록시는 사용할 수 없고, 그쪽으로 리다이렉션된 모든 DNS 요청은 타임아웃되기 때문이에요.

  • 노드 집합에서 Cilium 에이전트 이미지를 업그레이드할 때, kubelet이 이전 Cilium 에이전트 파드를 중지한 후에는 컨테이너 레지스트리에 접속할 수 없으므로 새 이미지를 미리 당겨(pre-pull) 두어야 해요.
  • Kubernetes 기능 게이트 KubeletEnsureSecretPulledImages가 활성화되고 kubelet이 원격 인증·권한 부여 서비스에 의존하는 이미지 자격 증명 제공자(관리형 Kubernetes에서 일반적)로 구성된 경우, Cilium 에이전트 이미지가 이미지 자격 증명 검증에서 면제되도록 이미지 풀 자격 증명 검증 정책을 구성해야 해요. 그렇지 않으면 kubelet이 새 Cilium 에이전트 파드의 이미지 풀 자격 증명을 검증하지 못해, 이미지가 미리 당겨졌음에도 파드가 시작에 실패할 수 있어요(노드를 사용 불가능하게 만들 수 있어요).
  • 일부 Kubernetes 버전은 호스트 L7 DNS 정책을 사용할 때 추가 주의가 필요해요. Kubernetes v1.33에서는 이미지가 존재하고 이미지 풀 정책이 Never 또는 IfNotPresent여도 kubelet이 항상 이미지 풀 자격 증명을 가져와요. 그 결과 이미지에 대해 원격 인증·권한 부여 서비스에 의존하는 클러스터에서는 노드에서 Cilium 데몬 파드를 재시작하는 데 최대 몇 분이 걸릴 수 있고, 그동안 노드는 ready 상태가 아니에요. 이 문제는 v1.34에서 수정됐어요. Kubernetes v1.34에서는 기능 게이트 KubeletEnsureSecretPulledImages가 활성화되면 이미지 풀 자격 증명 검증 정책이 비활성화되거나 Cilium 이미지가 화이트리스트에 있더라도 같은 동작이 발생해요. 이 문제는 v1.35에서 수정됐어요.

주의: 호스트 L7 DNS 정책은 엔드포인트별 경로(per-endpoint routes)와 완전히 호환되지 않아요. 엔드포인트별 경로가 활성화되면, 호스트와 호스트 네트워킹 파드가 DNS 요청을 보내는 업스트림 DNS 서버가 클러스터 외부에 있으면 DNS 프록시가 동작하지만, 업스트림 DNS가 클러스터 내부(예: kube-dns)이면 해당 DNS 요청은 타임아웃돼요.

호스트 정책은 Node Selector가 선택한 모든 노드에 적용돼요. 각 선택된 노드에서 호스트 네임스페이스에만 적용되며, 호스트 네트워킹 파드도 포함해요. 비호스트 네트워킹 파드와 클러스터 외부 위치 간의 통신에는 적용되지 않아요.

호스트 정책 설치에는 Cilium 설치 시 다음 helm 플래그 추가가 필요해요.

  • --set devices='{interface}' — 여기서 interface는 Cilium이 구성되는 네트워크 디바이스(예: eth0)를 가리켜요. 이 옵션을 생략하면 Cilium이 호스트 방화벽이 적용되는 인터페이스를 자동 감지해요.
  • --set hostFirewall.enabled=true

예를 들어 다음 정책은 type=ingress-worker 라벨을 가진 노드에 TCP 포트 22, 6443(kube-apiserver), 2379(etcd), 4240(health check), 그리고 UDP 포트 8472(VXLAN)에 대한 ingress 트래픽을 허용해요.

apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "lock-down-ingress-worker-node"
spec:
  description: "Allow a minimum set of required ports on ingress of worker nodes"
  nodeSelector:
    matchLabels:
      type: ingress-worker
  ingress:
  - fromEntities:
    - remote-node
    - health
  - toPorts:
    - ports:
      - port: "22"
        protocol: TCP
      - port: "6443"
        protocol: TCP
      - port: "2379"
        protocol: TCP
      - port: "4240"
        protocol: TCP
      - port: "8472"
        protocol: UDP

이 정책을 재사용하려면 port: 값을 여러분 환경에서 사용하는 포트로 바꾸세요.

VRRP, IGMP, 그리고 전송 계층 포트가 없는 터널/캡슐화 프로토콜 같은 프로토콜을 허용하려면 --enable-extended-ip-protocols 플래그를 true로 설정하세요. 기본적으로 이러한 트래픽은 DROP_CT_UNKNOWN_PROTO 오류로 버려져요. 지원되는 확장 프로토콜은 다음과 같아요.

  • VRRP (protocol 112) - Virtual Router Redundancy Protocol
  • IGMP (protocol 2) - Internet Group Management Protocol
  • GRE (protocol 47) - Generic Routing Encapsulation
  • IPIP (protocol 4) - IP-in-IP Encapsulation (RFC 2003)
  • IPV6 (protocol 41) - IPv6 Encapsulation / 6in4 (RFC 4213)
  • ESP (protocol 50) - Encapsulating Security Payload / IPsec (RFC 4303)
  • AH (protocol 51) - Authentication Header / IPsec (RFC 4302)

예를 들어 다음 정책은 type=egress-worker 라벨을 가진 노드에 TCP 포트 22, 6443/443(kube-apiserver), 2379(etcd), 4240(health check), UDP 포트 8472(VXLAN), 그리고 VRRP 프로토콜 트래픽에 대한 egress를 허용해요.

apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "allow-extended-egress-worker-node"
spec:
  description: "Allow specific traffic on egress of worker nodes"
  nodeSelector:
    matchLabels:
      type: ingress-worker
  egress:
  - toPorts:
    - ports:
      - port: "6443"
        protocol: TCP
      - port: "443"
        protocol: TCP
      - port: "2379"
        protocol: TCP
      - port: "4240"
        protocol: TCP
      - port: "8472"
        protocol: UDP
      # Extended IP protocols (no transport-layer ports)
      - protocol: VRRP
      # Tunnel/encapsulation protocols
      - protocol: GRE
      - protocol: IPIP
      - protocol: IPV6
      # IPsec protocols
      - protocol: ESP
      - protocol: AH

호스트 정책 문제 해결 (Troubleshooting Host Policies)

호스트 정책에 문제가 있다면 다음 단계를 시도해 보세요.

  • 설치는 Host Policies 설명에 나열된 helm 옵션이 적용됐는지 확인하세요.
  • 정책이 Cilium 에이전트에 의해 수락·적용됐는지 확인하려면 kubectl get CiliumClusterwideNetworkPolicy -o yaml을 실행해 정책이 나열되는지 확인하세요.
  • 정책이 노드에 적용되지 않는 것 같으면, 여러분 환경에서 nodeSelector가 올바르게 라벨링됐는지 확인하세요. 예제 구성에서는 kubectl get nodes -o custom-columns=NAME:.metadata.name,LABELS:.metadata.labels | grep type:ingress-worker를 실행해 라벨이 정책과 일치하는지 확인할 수 있어요.

특정 노드의 정책을 문제 해결하려면 다음 단계를 시도해 보세요. 모든 단계에서 해당 노드의 Cilium 에이전트 파드에서 관련 네임스페이스로 cilium-dbg를 실행하세요. 예를 들면:

$ kubectl exec -n $CILIUM_NAMESPACE $CILIUM_POD_NAME -- cilium-dbg ...

cilium-dbg endpoint get -l reserved:host -o jsonpath='{[0].id}'로 노드의 호스트 엔드포인트 ID를 가져오세요. 이 ID를 이후 단계의 $HOST_EP_ID에 사용하세요.

  • 정책이 적용됐지만 노드에 시행되지 않으면, cilium-dbg endpoint config $HOST_EP_ID | grep PolicyAuditMode로 정책 감사 모드의 상태를 확인하세요. 필요하면 감사 모드를 비활성화하세요.
  • cilium-dbg endpoint list를 실행하고 $HOST_EP_ID와 reserved:host 라벨로 호스트 엔드포인트를 찾으세요. 선택한 방향에서 정책이 활성화됐는지 확인하세요.
  • cilium-dbg status list를 실행하고 Host firewall 필드에 나열된 디바이스를 확인하세요. 나열된 디바이스로 트래픽이 실제로 도달하는지 확인하세요.
  • cilium-dbg monitor를 --related-to $HOST_EP_ID와 함께 사용해 호스트 엔드포인트의 트래픽을 검사하세요.

호스트 정책 알려진 이슈 (Host Policies known issues)

  • Cilium이 클러스터에서 호스트 정책을 처음 시행할 때, 시행 중인 정책이 허용해야 하는 합법적인 연결의 응답 트래픽을 버릴 수 있어요. 연결은 몇 초 후에 다시 안정화되어야 해요. 한 가지 해결 방법은 호스트 정책 시행을 활성화, 비활성화, 다시 활성화하는 거예요. 자세한 내용은 GitHub issue 25448을 참고하세요.
  • ClusterMesh 맥락에서 다음 옵션 조합은 지원되지 않아요: CRD 모드(KVstore 모드 대신)로 동작하는 Cilium, 호스트 정책 활성화, 터널링 활성화, kube-proxy-replacement 활성화, WireGuard 활성화. 이 조합은 clustermesh-apiserver에 연결하지 못하게 돼요. 자세한 내용은 GitHub issue 31209를 참고하세요.
  • 호스트 정책은 호스트 WireGuard 인터페이스에서 동작하지 않아요. 자세한 내용은 GitHub issue 17636을 참고하세요.
  • 호스트 정책이 활성화되면, 호스트가 로드된 호스트 정책이 없어도 알 수 없는 레이어 2 프로토콜의 트래픽을 버려요. 예를 들어 이는 LLC 트래픽(GitHub issue 17877 참고)이나 VRRP 트래픽(GitHub issue 18347 참고)에 영향을 줘요.
  • kube-proxy-replacement가 비활성화되거나 네이티브 디바이스에 서비스(예: NodePort)를 구현하지 않도록 구성된 경우, 호스트는 서비스 엔드포인트 대신 서비스 주소에 호스트 정책을 시행해요. 자세한 내용은 GitHub issue 12545를 참고하세요.
  • Host Firewall과 그에 따른 Host Policies는 IPsec과 함께 동작하지 않아요. 자세한 내용은 GitHub issue 41854를 참고하세요.

더 알아보기 (Learn more)