Cilium Gateway API 외부 트래픽 설계

Cilium Gateway API 1편: 외부 트래픽 진입점 선택하기

Cilium Gateway API의 데이터 경로를 이해하고 LoadBalancer, NodePort, hostNetwork 중 환경에 맞는 외부 노출 방식을 선택합니다.

검증일 근거 자료

핵심 요약

  • Cilium Gateway API는 GatewayHTTPRoute를 Envoy 설정으로 변환하고, Cilium eBPF 데이터 경로가 외부 연결을 노드별 Envoy로 전달하는 구조
  • 외부 진입점은 기본 LoadBalancer Service, 외부 장비가 노드 포트를 조회하는 NodePort, 노드 포트에 직접 바인딩하는 hostNetwork 중 하나로 결정해야 함
  • 멀티 컨트롤 플레인은 Kubernetes API의 가용성 문제이고 애플리케이션 외부 트래픽의 가용성과는 별도 설계 대상
  • 클라우드 공인 IP가 eth0에 보이지 않아도 공급자 SDN·가상 네트워크가 노드 vNIC와 연결할 수 있으므로 VM에서 관측한 목적지와 공급자 요구사항을 먼저 확인해야 함
  • 운영 전에는 주소 할당뿐 아니라 라우팅·광고, 보안 정책, 클라이언트 IP 신뢰 경계, 장애 제거 방식까지 함께 검증해야 함

Gateway API는 역할과 데이터 경로를 분리함

  • Gateway API는 인프라 소유자와 애플리케이션 소유자의 책임을 분리하는 API

    • 플랫폼 팀은 GatewayClassGateway에서 구현체, 리스너, TLS 종료 지점을 관리함
    • 애플리케이션 팀은 HTTPRouteGRPCRoute에서 호스트·경로와 백엔드 연결을 관리함
  • Cilium에서는 일반적인 인그레스 컨트롤러 Deployment를 한 번 더 통과하는 구조로 이해하면 안 됨

    • Cilium operator가 Gateway API 리소스를 검증하고 CiliumEnvoyConfig로 변환함
    • 각 노드의 eBPF 데이터 경로가 Service 또는 호스트 포트로 들어온 패킷을 Envoy에 투명하게 전달함
    • Envoy가 L7 라우팅과 TLS 종료를 수행한 뒤 백엔드 Service로 새 연결을 생성함
Cilium Gateway API control plane and data plane

공통 전제조건을 먼저 고정함

  • 이 시리즈의 예시는 검증일 기준 Cilium 1.20.1과 Gateway API 1.6.1을 기준으로 작성

    • 실제 적용 시 설치된 Cilium 버전의 공식 문서와 업그레이드 가이드를 먼저 확인해야 함
    • CiliumGatewayClassConfigv2alpha1이므로 릴리스 간 변경 가능성이 있음
  • Cilium Gateway API에는 kube-proxy replacement와 L7 proxy가 필요

values-cilium-gateway.yaml
kubeProxyReplacement: true
l7Proxy: true
gatewayAPI:
  enabled: true
  • Gateway API CRD는 Cilium 설치 전에 호환 버전으로 설치해야 함
kubectl apply --server-side \
  -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml

helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --values values-cilium-gateway.yaml
  • 설치 직후에는 설정값과 컨트롤러 상태를 함께 확인해야 함
cilium status --wait
kubectl -n kube-system exec ds/cilium -- \
  cilium-dbg config --all | rg 'KubeProxyReplacement|EnableL7Proxy'
kubectl get gatewayclass cilium

외부 노출 방식은 네트워크 소유권으로 선택함

환경권장 진입 방식주소를 제공하는 주체핵심 조건
관리형 클라우드 LB 연동LoadBalancer Service클라우드 컨트롤러Service 감시와 LB 생성 권한 필요
사내·베어메탈 VIPLB IPAM + BGP 또는 L2Cilium + 라우터/L2IP 할당과 네트워크 광고를 모두 구성
기존 외부 LBNodePort 또는 hostNetwork외부 LB 운영 계층노드 대상·포트·헬스 체크 동기화 필요
노드별 클라우드 공인 IPhostNetwork공급자 SDN + DNS노드별 IP 연결과 장애 DNS 제거 필요
  • LB IPAM은 IP를 할당할 뿐 외부 네트워크에 경로를 만들지 않음

    • 라우터가 BGP를 지원하면 Cilium BGP Control Plane으로 Service VIP를 광고함
    • 같은 L2 네트워크에서 VIP를 제공하면 L2 Announcements로 ARP 또는 NDP 응답을 제공함
    • 공급자 SDN이 서로 다른 공인 IP를 각 노드 vNIC에 연결하면 LB IPAM 대신 hostNetwork와 외부 DNS를 사용함
  • hostNetwork와 기본 LoadBalancer Service 모드는 상호 배타적

    • hostNetwork는 리스너를 선택 노드의 모든 인터페이스에 노출함
    • TCPRouteUDPRoute가 필요하면 현재 제약을 확인하고 Service 기반 모드를 우선 검토해야 함

하나의 Gateway 계약을 공통 기준으로 사용함

  • 외부 노출 방식이 달라도 GatewayHTTPRoute의 애플리케이션 계약은 유지할 수 있음
gateway-and-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public
  namespace: edge
spec:
  gatewayClassName: cilium
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.example.com"
      tls:
        mode: Terminate
        certificateRefs:
          - kind: Secret
            name: wildcard-example-com
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: public
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop
  namespace: shop
spec:
  parentRefs:
    - name: public
      namespace: edge
  hostnames: ["shop.example.com"]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: shop-web
          port: 8080
  • 네임스페이스 간 연결에는 양쪽의 명시적 허용이 필요
    • Gateway.spec.listeners.allowedRoutes가 Route 네임스페이스를 허용해야 함
    • 다른 네임스페이스의 Service나 Secret을 참조하면 대상 측 ReferenceGrant가 필요함

보안과 클라이언트 IP 경계를 함께 설계함

  • Cilium 정책에서는 외부에서 Envoy까지와 Envoy에서 백엔드까지를 별도 흐름으로 허용해야 함

    • 첫 번째 구간은 일반적으로 world에서 ingress identity로 들어오는 흐름임
    • 두 번째 구간은 ingress identity에서 애플리케이션 identity로 나가는 흐름임
  • 외부 LB가 추가되면 실제 클라이언트 IP를 누가 보증하는지 정해야 함

    • L4 LB가 소스 IP를 보존하면 Cilium 기본 remote address 동작을 유지함
    • 신뢰하는 L7 LB가 X-Forwarded-For를 추가하면 노드 방화벽에서 LB만 허용하고 trusted hop 수를 정확히 설정함
    • 인터넷에서 Envoy로 직접 접근 가능한 상태에서 임의의 X-Forwarded-For를 신뢰하면 IP 기반 정책과 감사 로그가 우회될 수 있음

주소보다 실제 요청 경로를 검증함

  • Programmed=True는 설정이 생성됐다는 의미이며 인터넷에서 도달 가능하다는 보장은 아님
kubectl get gateway -A
kubectl describe gateway -n edge public
kubectl get httproute -A
kubectl get svc -n edge
kubectl -n kube-system logs ds/cilium-envoy --since=10m
  • 검증은 외부 관측 지점에서 DNS·TCP·TLS·HTTP 순서로 수행해야 함
dig +short shop.example.com
nc -vz shop.example.com 443
openssl s_client -connect shop.example.com:443 -servername shop.example.com </dev/null
curl --fail-with-body --resolve shop.example.com:443:203.0.113.10 \
  https://shop.example.com/healthz

참고 문서