핵심 요약
- 외부 LB가 Kubernetes Service를 직접 관리할 수 있으면 기본
LoadBalancer모드가 가장 단순한 구성임 - Kubernetes와 분리된 하드웨어·가상 LB라면
NodePort를 대상으로 등록하고 포트 변경을 자동화하는 구성이 범용적임 - 고정된
80/443노드 포트가 필요하고 HTTP·HTTPS 중심이면 선택 노드에만hostNetwork리스너를 여는 구성이 적합할 수 있음 - 외부 LB의 헬스 체크는 Kubernetes API 서버가 아니라 Gateway 데이터 경로를 통과하는 전용 엔드포인트를 검사해야 함
- 클라이언트 IP는 L4 소스 보존 또는 신뢰 가능한 L7 헤더 중 하나를 선택하고 노드 접근 제어와 함께 구성해야 함
외부 LB와 Gateway의 책임을 분리함
- 외부 LB는 정상 노드를 선택하고 Cilium Gateway는 TLS와 L7 라우팅을 담당하는 구성이 기본안임
- 외부 LB에서 TLS를 종료하지 않으면 인증서와 호스트 라우팅 계약을 Gateway에 집중할 수 있음
- 외부 LB에서 TLS를 종료하면 LB와 Gateway 사이 재암호화 여부와
X-Forwarded-For신뢰 규칙이 추가됨
LB 연동 능력에 따라 세 가지 패턴을 선택함
-
패턴 A는 클라우드 컨트롤러가 생성한
LoadBalancerService를 외부 LB와 동기화하는 방식임- Cilium Gateway의 기본 동작이므로 별도 GatewayClass가 필요하지 않음
- 클라우드별 Service annotation은
Gateway.spec.infrastructure.annotations에 두어 생성 Service로 전달할 수 있음 - 외부 주소가 비어 있으면 Gateway 문제가 아니라 LoadBalancer 구현 또는 권한 문제일 가능성이 있음
-
패턴 B는 외부 LB가 모든 인그레스 노드의
NodePort를 대상으로 사용하는 방식임CiliumGatewayClassConfig로 생성 Service 타입을NodePort로 변경할 수 있음- 이 CRD는
v2alpha1이므로 버전 고정과 업그레이드 검증이 필요함
apiVersion: cilium.io/v2alpha1
kind: CiliumGatewayClassConfig
metadata:
name: external-lb
namespace: edge
spec:
service:
type: NodePort
externalTrafficPolicy: Cluster
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: cilium-external-lb
spec:
controllerName: io.cilium/gateway-controller
parametersRef:
group: cilium.io
kind: CiliumGatewayClassConfig
name: external-lb
namespace: edge
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public
namespace: edge
spec:
gatewayClassName: cilium-external-lb
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: wildcard-example-com- 생성된
nodePort는 외부 LB 구성의 입력값으로 자동 동기화해야 함
kubectl -n edge get svc cilium-gateway-public \
-o jsonpath='{range .spec.ports[*]}{.name}{"="}{.nodePort}{"\n"}{end}'- 패턴 C는
hostNetwork로 선택 노드의 리스너 포트에 직접 바인딩하는 방식임- 포트가 고정되어 외부 LB의 대상을
nodeIP:443으로 단순화할 수 있음 LoadBalancerService 모드와 상호 배타적이며TCPRoute·UDPRoute제약이 있음- 구성 방법은 LB 없는 클라우드 공인 IP 구성에서 상세히 다룸
- 포트가 고정되어 외부 LB의 대상을
인그레스 노드만 LB 대상에 포함함
- 외부 LB의 대상 집합은 역할이 명시된 노드로 제한해야 함
kubectl label node worker-a worker-b gateway.cilium.io/expose=true
kubectl get nodes -l gateway.cilium.io/expose=true -o wide-
NodePort는 기본적으로 여러 노드에서 수신될 수 있으므로 외부 LB와 방화벽이 대상 범위를 제한해야 함- 인터넷에서는 외부 LB의 VIP만 공개함
- 노드의 NodePort는 LB 소스 CIDR에서만 허용함
- 컨트롤 플레인 노드가 대상이 아니면
node.kubernetes.io/exclude-from-external-load-balancerslabel 또는 LB 대상 필터로 제외함
-
Cilium Gateway 트래픽에서는
externalTrafficPolicy: Cluster를 기본값으로 유지해도 Envoy가 관찰한 원격 주소를 HTTP 헤더로 전달할 수 있음- 일반 Service의 소스 IP 동작과 Cilium의 Envoy TPROXY 경로를 혼동하면 안 됨
- Node IPAM LB를 함께 사용할 때는 Cilium Gateway의 dummy Endpoint 제약 때문에
Local을 피해야 함
헬스 체크가 전체 데이터 경로를 검증해야 함
-
TCP 연결 확인은 포트 생존만 검증하고 Route·TLS·백엔드 장애를 발견하지 못함
- 빠른 노드 제거가 우선이면 TCP 체크를 사용함
- 사용자 요청 가능 여부가 우선이면 전용 hostname과
/healthzRoute를 사용함
-
전용 헬스 체크는 외부 LB와 동일한 포트·SNI·Host 헤더로 요청해야 함
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gateway-health
namespace: edge
spec:
parentRefs:
- name: public
hostnames: ["gateway-health.example.com"]
rules:
- matches:
- path:
type: Exact
value: /healthz
backendRefs:
- name: gateway-health
port: 8080- Kubernetes API 서버의
/readyz를 Gateway 헬스 체크로 사용하면 안 됨- API 서버가 정상이어도 Envoy·Route·백엔드 경로가 실패할 수 있음
- API 서버가 일시적으로 실패해도 이미 프로그램된 Envoy 데이터 경로는 계속 요청을 처리할 수 있음
클라이언트 IP 신뢰 규칙을 한 번만 적용함
-
L4 패스스루 LB가 소스 IP를 보존하면 Cilium의 기본
gatewayAPI.useRemoteAddress=true를 유지함- LB가 SNAT하면 Envoy에는 LB 주소만 보이므로 LB의 DSR 또는 소스 보존 기능을 검토함
-
L7 LB가 신뢰 가능한
X-Forwarded-For를 생성하면 trusted hop 설정과 접근 제어를 함께 적용함
gatewayAPI:
enabled: true
useRemoteAddress: false
xffNumTrustedHops: 1- trusted hop 수는 LB 체인 수와 정확히 일치해야 함
- CDN과 외부 LB가 연속되면 각 프록시의 헤더 append 규칙을 먼저 확인함
- 노드 포트로 직접 접근하는 경로를 차단하지 않으면 클라이언트가 신뢰 헤더를 위조할 수 있음
장애와 변경 시나리오를 검증함
- 정상 상태에서는 두 노드가 모두 LB 대상이고 Gateway와 Route condition이
True여야 함
kubectl get gateway -n edge public -o wide
kubectl get httproute -A
kubectl get svc -n edge cilium-gateway-public -o yaml-
장애 훈련에서는 한 인그레스 노드를 drain하거나 Envoy를 중지해 제거 시간을 측정해야 함
- LB 헬스 체크 간격과 실패 임계값을 기록함
- 기존 keep-alive 연결과 신규 연결의 실패 양상을 분리함
- 복구 후 대상 재등록과 연결 분산을 확인함
-
변경 훈련에서는 Gateway 재생성 시 NodePort가 바뀌어도 LB 자동화가 따라가는지 확인해야 함
- 정적 수동 등록만 가능한 장비라면
hostNetwork또는 예약 가능한 별도 Service 설계를 검토함
- 정적 수동 등록만 가능한 장비라면
실행 제안
- Kubernetes 연동 LB는 기본
LoadBalancer, 독립 외부 LB는NodePort, 고정 노드 포트가 핵심이면hostNetwork순서로 검토함 - 운영 반영 전
LB → 노드 → Envoy → Route → 백엔드전체를 통과하는 헬스 체크와 장애 훈련을 완료해야 함
참고 문서
관련 글
Cilium Gateway API 외부 트래픽 설계Cilium Gateway API 1편: 외부 트래픽 진입점 선택하기Cilium Gateway API의 데이터 경로를 이해하고 LoadBalancer, NodePort, hostNetwork 중 환경에 맞는 외부 노출 방식을 선택합니다.Cilium Gateway API 외부 트래픽 설계Cilium Gateway API 3편: 멀티 컨트롤 플레인에서 경계 나누기고가용성 Kubernetes 컨트롤 플레인과 Cilium Gateway API 데이터 플레인의 로드 밸런서, 노드 역할, 장애 경계를 분리합니다.Cilium Gateway API 외부 트래픽 설계Cilium Gateway API 4편: LB 없이 노드별 클라우드 공인 IP로 받기노드별 공인 IP를 VM에 연결하는 클라우드 SDN 환경에서 Cilium hostNetwork와 DNS로 외부 트래픽을 받습니다.