Gateway API 지원
Gateway API 지원 (Gateway API Support)
Gateway API는 Ingress 객체의 후속을 설계하기 위한 Kubernetes SIG-Network 서브프로젝트예요. Cilium은 Gateway API v1.6.1을 지원하며 모든 Core conformance 테스트를 통과해요.
본문
Gateway API란 무엇인가요? (What is Gateway API?)
Gateway API는 Ingress 객체의 후속을 설계하기 위한 Kubernetes SIG-Network 서브프로젝트예요. Kubernetes에서 서비스 네트워킹을 모델링하는 리소스 집합이며, 역할 중심적이고 이식 가능하며 표현력 있고 확장 가능하도록 설계됐어요.
자세한 내용은 Gateway API 사이트를 참고해주세요.
Cilium Gateway API 지원 (Cilium Gateway API Support)
Cilium은 아래 리소스에 대해 Gateway API v1.6.1을 지원하며, 모든 Core conformance 테스트를 통과해요.
- GatewayClass
- Gateway
- HTTPRoute
- GRPCRoute
- TLSRoute
- BackendTLSPolicy
- ReferenceGrant
- ListenerSet
- TCPRoute
- UDPRoute
추가로 Cilium은 CiliumGatewayClassConfig CRD를 제공하며, 이를 GatewayClass.parametersRef에서 참조할 수 있어요.
영상
Cilium의 Gateway API 지원에 대해 더 알고 싶다면 eCHO 에피소드 58 "Cilium Service Mesh and Ingress"를 확인해보세요.
사전 요구사항 (Prerequisites)
- Cilium은
kubeProxyReplacement=true로 kube-proxy 교체가 구성되어야 해요. 자세한 내용은 kube-proxy replacement를 참고해주세요. - Cilium은
l7Proxy=true(기본 활성화)로 L7 프록시가 활성화되어야 해요. - Gateway의 Service에 도착한 트래픽은
TPROXY커널 기능을 사용해 Envoy로 투명하게 전달돼요. 기본bpf.tproxy=false에서는TPROXY가 iptables로 구현되므로, 노드는 L7 프록시 시스템 요구사항에 나열된 netfilter 모듈과 함께 iptables를 제공해야 해요. 일부 배포판은 기본적으로 이를 제공하지 않아서, Gateway에 대한 연결이 Envoy에 도달하지 못한 채 타임아웃될 수 있어요. eBPF 기반bpf.tproxy=true(베타)는 이 iptables 의존성을 제거해요. - 기본적으로 Cilium Gateway API 컨트롤러는 LoadBalancer 유형의 서비스를 만들므로, 환경이 이를 지원해야 해요. 또는 Cilium 1.16부터 호스트 네트워크에서 Cilium L7 프록시를 직접 노출할 수 있어요.
설치 (Installation)
Gateway API v1.6.1의 아래 CRD들이 반드시 설치되어야 해요.
- GatewayClass
- Gateway
- HTTPRoute
- GRPCRoute
- BackendTLSPolicy
- ReferenceGrant
- TLSRoute
설치 단계는 이 문서들을 참고해주세요. 또는 아래 스니펫을 사용할 수도 있어요.
experimental 릴리스 채널에는 standard 릴리스 채널의 모든 것과 일부 실험 리소스/필드가 포함돼 있어요. 현재 experimental로 표시된 기능(예: HTTPRoute 리소스의 HTTPRoute Retry)이 필요하다면 해당 CRD를 설치해야 해요. 실험 기능 전체 목록은 experimental GEP 목록을 참고해주세요.
기존 설치를 업데이트하는 경우, 항상 먼저 Upgrade Guide를 확인해서 새 버전에 필요한 breaking changes, deprecated 기능, 중요한 구성 업데이트를 검토해주세요. Cilium 1.20 업그레이드의 경우, Gateway API CRD를 업데이트하기 전에 업그레이드 가이드의 Gateway API v1.6.1과 TLSRoute 참고 사항을 검토하세요.
필요한 CRD 집합은 다음과 같이 설치할 수 있어요:
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_tlsroutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
TCPRoute, UDPRoute 또는 ListenerSet CRD는 선택 사항이며, 이 기능을 사용하려면 해당 CRD 리소스를 설치해야 해요. 설치하지 않으면 Cilium은 이 기능들에 대한 지원을 비활성화해요.
선택적 CRD 집합은 다음과 같이 설치할 수 있어요:
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_listenersets.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_tcproutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/standard/gateway.networking.k8s.io_udproutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_listenersets.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml
kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.6.1/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml
CRD가 설치되면 Helm 또는 Cilium CLI를 사용해 Cilium Gateway API 컨트롤러를 활성화해주세요.
최신 버전의 Cilium CLI를 설치해볼게요. Cilium CLI는 Cilium 설치, Cilium 설치 상태 검사, 다양한 기능(예: clustermesh, Hubble) 활성화/비활성화에 사용할 수 있어요.
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "arm64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
shasum -a 256 -c cilium-darwin-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-darwin-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
전체 릴리스 페이지를 참고해주세요.
Helm으로 활성화하기 — Cilium Gateway API Controller는 helm 플래그 gatewayAPI.enabled를 true로 설정해서 활성화할 수 있어요. 새 설치에 대해서는 Installation using Helm을 참고해주세요.
helm upgrade cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--reuse-values \
--set kubeProxyReplacement=true \
--set gatewayAPI.enabled=true
kubectl -n kube-system rollout restart deployment/cilium-operator
kubectl -n kube-system rollout restart ds/cilium
helm upgrade cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--reuse-values \
--set kubeProxyReplacement=true \
--set gatewayAPI.enabled=true
kubectl -n kube-system rollout restart deployment/cilium-operator
kubectl -n kube-system rollout restart ds/cilium
Cilium CLI로 활성화하기 — Cilium Gateway API Controller는 아래 명령으로 활성화할 수 있어요.
$ cilium upgrade 1.20.2 \
--set kubeProxyReplacement=true \
--set gatewayAPI.enabled=true
다음으로 Cilium agent와 operator의 상태를 확인할 수 있어요:
$ cilium status
참조 (Reference)
Cilium Ingress와 Gateway API가 다른 Ingress 컨트롤러와 다른 점 (How Cilium Ingress and Gateway API differ from other Ingress controllers)
Cilium의 Ingress 및 Gateway API 지원과 다른 Ingress 컨트롤러 사이의 가장 큰 차이점 중 하나는 구현이 CNI와 얼마나 밀접하게 연결돼 있는지예요. Cilium에서는 Ingress와 Gateway API가 네트워킹 스택의 일부이므로, 다른 Ingress나 Gateway API 컨트롤러와는 다르게 동작해요 (심지어 Cilium 클러스터에서 실행되는 다른 Ingress/Gateway API 컨트롤러라도요).
다른 Ingress/Gateway API 컨트롤러는 일반적으로 클러스터에 Deployment나 DaemonSet으로 설치되고, Loadbalancer Service 등으로 노출돼요 (물론 Cilium이 이를 활성화할 수도 있어요).
Cilium의 Ingress 및 Gateway API 구성은 Loadbalancer나 NodePort 서비스로 노출되거나, 선택적으로 호스트 네트워크에서도 노출될 수 있어요. 하지만 이 모든 경우에 트래픽이 Service의 포트에 도착하면 eBPF 코드가 트래픽을 가로채서 (TPROXY 커널 기능을 사용해) Envoy로 투명하게 전달해요.
이것은 클라이언트 IP 가시성 같은 것에 영향을 주는데, 이는 Cilium의 Ingress/Gateway API 지원에서 다른 Ingress 컨트롤러와 다르게 동작해요.
또한 Cilium의 Network Policy 엔진이 Ingress로 향하는 트래픽과 Ingress에서 나오는 트래픽에 CiliumNetworkPolicy를 적용할 수 있게 해줘요.
Cilium의 ingress 구성과 CiliumNetworkPolicy (Cilium's ingress config and CiliumNetworkPolicy)
Cilium을 통해 백엔드 서비스로 향하는 Ingress 및 Gateway API 트래픽은 노드별 Envoy 프록시를 통과해요.
노드별 Envoy 프록시에는 eBPF 정책 엔진과 상호작용하고 트래픽에 대한 정책 조회를 수행할 수 있는 특수 코드가 있어요. 이를 통해 Envoy는 Ingress(및 Gateway API) 트래픽과 GAMMA나 L7 Traffic Management를 통한 동서(east-west) 트래픽 모두에 대해 Network Policy enforcement point가 될 수 있어요.
하지만 ingress 구성에는 추가 단계가 하나 더 있어요. Ingress나 Gateway API를 위해 Envoy에 도착한 트래픽은 Cilium의 Policy 엔진에서 특별한 ingress 아이덴티티로 지정돼요.
클러스터 외부에서 온 트래픽은 (클러스터에 IP CIDR 정책이 없다면) 보통 world 아이덴티티로 지정돼요. 즉 Cilium Ingress에는 실제로 두 개의 논리적 Policy enforcement point가 있다는 뜻이에요 — 트래픽이 ingress 아이덴티티에 도착하기 전과, 노드별 Envoy를 빠져나가려는 그 이후예요.
즉, 클러스터에 Network Policy를 적용할 때는 두 단계 모두 허용되는지, 그리고 world에서 ingress로, ingress에서 클러스터 안의 아이덴티티(위 이미지의 productpage 아이덴티티 등)로 트래픽이 허용되는지 확인하는 게 중요해요.
Ingress에 대한 자세한 내용은 Ingress and Network Policy Example을 참고해주세요. 단, 같은 원칙이 Gateway API에도 적용돼요.
소스 IP 가시성 (Source IP Visibility)
참고
기본적으로 Cilium ingress 구성(Ingress와 Gateway API 모두)의 소스 IP 가시성은 대부분의 설치에서 그냥 동작해야 해요. 요구사항과 관련 설정에 대한 자세한 내용은 이 섹션을 읽어주세요.
백엔드가 실제 요청이 어떤 IP 주소에서 왔는지 추론할 수 있는 것은 대부분의 애플리케이션에서 중요해요.
기본적으로 Cilium의 Envoy 인스턴스는 일반적인 규칙을 사용해 인입 HTTP 연결의 보이는 소스 주소를 X-Forwarded-For 헤더에 추가하도록 구성돼 있어요. 즉 기본적으로 Cilium은 신뢰된 홉(hop) 수를 0으로 설정해서, Envoy가 X-Forwarded-For 목록 안의 값이 아니라 연결이 열린 주소를 사용하도록 해요. 이 개수를 늘리면 Envoy가 목록의 오른쪽에서부터 세어 n 번째 값을 사용하게 돼요.
Envoy는 또한 X-Forwarded-For를 기반으로 결정된 신뢰된 클라이언트 주소가 무엇이든 X-Envoy-External-Address 헤더로 설정해요.
기본적으로 Cilium은 Ingress를 포함한 Layer 7 기능에 대한 정책을 적용할 때 연결 클라이언트의 소스 IP를 사용해요. 트래픽의 소스가 X-Forwarded-For 헤더를 주입하는 것을 신뢰한다면(예: 클라우드 로드 밸런서 사용 시), values 파일의 gatewayAPI 또는 ingressController 섹션에서 useRemoteAddress를 false로 설정해 Envoy가 X-Forwarded-For 헤더에 인코딩된 클라이언트 IP에서 온 트래픽으로 취급하도록 강제할 수 있어요.
자세한 내용은 Envoy X-Forwarded-For headers 문서를 참고해주세요.
참고
Cilium ingress(Ingress든 Gateway API든)를 사용하는 백엔드는
X-Forwarded-For와X-Envoy-External-Address헤더만 보면 돼요 (많은 HTTP 라이브러리가 이를 투명하게 처리해요).
Loadbalancer 또는 NodePort Service의 externalTrafficPolicy
Cilium의 ingress 지원(Ingress와 Gateway API 모두)은 종종 Loadbalancer나 NodePort Service를 사용해 Envoy DaemonSet을 노출해요.
이런 경우 Service 객체에는 클라이언트 IP 가시성과 특히 관련된 필드인 externalTrafficPolicy 필드가 하나 있어요.
관련 설정 두 가지가 있어요:
Local: 노드는 소스 IP를 마스커레이드하지 않고 로컬 노드에서 실행 중인 파드로만 트래퇵을 라우팅해요. 그렇기 때문에kube-proxy를 사용하는 클러스터에서는 이것이 소스 IP 가시성을 보장하는 유일한 방법이에요.externalTrafficPolicy: local의 계약의 일부에는 노드가 포트를 연다는 것(externalTrafficPolicy: Local이 설정되면 Kubernetes가 자동으로 설정하는healthCheckNodePort)도 있으며, 로컬 파드가 실행 중인 노드에서는http://<nodeIP>:<healthCheckNodePort>/healthz요청이 200을 반환하고, 그렇지 않은 노드에서는 200이 아닌 값을 반환해요. Cilium은 일반 Loadbalancer Service에 대해 이를 구현하지만, Cilium ingress 구성(Ingress와 Gateway API 모두)에서는 조금 다르게 동작해요.Cluster: 노드는 클러스터 전체의 모든 엔드포인트로 균등하게 라우팅해요. 여기에는 몇 가지 다른 효과가 있어요. 첫째, 업스트림 로드 밸런서는 아무 노드로나 트래픽을 보내도 백엔드 파드에 도달할 것으로 기대하며, 노드는 소스 IP를 마스커레이드할 수도 있어요. 즉 많은 경우externalTrafficPolicy: Cluster는 백엔드 파드가 소스 IP를 보지 못할 수 있다는 뜻이에요.
Cilium의 경우, Envoy를 노출하는 Service로 향하는 모든 ingress 트래픽은 항상 로컬 노드로 가고, 항상 Linux Kernel TPROXY 함수(백엔드로 패킷을 투명하게 전달)를 사용해 Envoy로 전달돼요.
즉 Cilium ingress 구성(Ingress와 Gateway API 모두)의 경우, 두 externalTrafficPolicy 경우 모두에서 조금 다르게 동작해요.
참고
두
externalTrafficPolicy경우 모두에서 트래픽은 클러스터의 아무 노드에나 도착해서, 소스 IP를 그대로 유지한 채 Envoy로 전달돼요.
또한 Cilium의 Envoy를 노출하는 모든 Service에 대해, Cilium은 externalTrafficPolicy: Local이 설정되면 클러스터의 모든 노드가 healthCheckNodePort 검사를 통과하도록 보장해서, 외부 로드 밸런서가 올바르게 전달하게 해요.
하지만 Cilium의 ingress 구성(Ingress와 Gateway API 모두)의 경우, 백엔드 파드에 소스 IP를 보이게 유지하기 위해 externalTrafficPolicy: Local을 구성하는 것은 필요하지 않아요 (X-Forwarded-For와 X-Envoy-External-Address 필드 덕분이에요).
TLS 패스스루와 소스 IP 가시성 (TLS Passthrough and source IP visibility)
Ingress와 Gateway API 모두 TLS 패스스루 구성을 지원해요 (Ingress는 어노테이션, Gateway API는 TLSRoute 리소스). 이 구성은 여러 TLS 패스스루 백엔드가 로드 밸런서에서 동일한 TLS 포트를 공유할 수 있게 해주며, Envoy가 TLS 핸드셰이크의 Server Name Indicator(SNI) 필드를 검사해서 그 값을 사용해 TLS 스트림을 백엔드로 전달해요.
하지만 Envoy가 TLS 스트림의 TCP 프록시를 수행하므로, 이것은 소스 IP 가시성에 문제가 돼요.
어떤 일이 벌어지냐면, TLS 트래픽이 Envoy에 도착해서 TCP 스트림을 종료하고, Envoy가 client hello를 검사해 SNI를 찾은 다음 전달할 백엔드를 선택하고, 새 TCP 스트림을 시작해 다운스트림(외부) 패킷 안의 TLS 트래픽을 업스트림(백엔드)으로 전달해요.
이것은 새 TCP 스트림이므로, 백엔드 입장에서는 소스 IP가 Envoy예요 (Cilium 구성에 따라 보통 Node IP예요).
참고
TLS 패스스루를 수행할 때 백엔드는 전달된 TLS 스트림의 소스로 Cilium Envoy의 IP 주소를 보게 돼요.
호스트 네트워크 모드 (Host network mode)
참고
Cilium 1.16+부터 지원돼요
호스트 네트워크 모드를 사용하면 호스트 네트워크에서 Cilium Gateway API Gateway를 직접 노출할 수 있어요. 이는 LoadBalancer Service를 사용할 수 없는 경우(개발 환경이나 클러스터 외부 로드 밸런서가 있는 환경 등)에 유용해요.
참고
- Cilium Gateway API 호스트 네트워크 모드를 활성화하면 LoadBalancer 유형 Service 모드가 자동으로 비활성화돼요. 둘은 상호 배타적이에요.
- 리스너는 모든 인터페이스(IPv4는
0.0.0.0, IPv6는::)에서 노출돼요.- 호스트 네트워크 모드는
TCPRoute와UDPRoute와 호환되지 않아요. 이들의 트래픽은 Envoy를 우회해서 Gateway가 생성한 Service에 직접 도달하는데, 이 Service는 보통 구성된Gateway리스너 포트를LoadBalancerService로 노출해요. 호스트 네트워크 모드를 활성화하면 이 Service가NodePortService로 바뀌며,Gateway리스너에 구성된 포트가 아니라 노드 포트 범위에서 무작위로 할당된 포트를 받게 돼요.
호스트 네트워크 모드는 Helm으로 활성화할 수 있어요:
gatewayAPI:
enabled: true
hostNetwork:
enabled: true
활성화하면 Gateway의 호스트 네트워크 포트는 spec.listeners.port로 지정할 수 있어요. 포트는 Gateway 리소스마다 고유해야 하며, 1023보다 높은 포트 번호를 선택해야 해요 (Bind to privileged port 참고).
경고
잘못 구성하면 포트 충돌이 발생할 수 있다는 점을 유의해주세요. 각 gateway에 대해 Gateway API 리스너가 노출되는 모든 Cilium 노드에서 아직 사용 가능한 고유 포트를 구성하세요.
gateway의 GatewayStatusAddress 필드는 최대 16개의 주소를 가질 수 있어요. 호스트 네트워크 모드가 활성화된 Cilium은 일관성을 위해 노드 주소를 자동으로 정렬해서, 동일한 주소가 선택되도록 보장해요.
특권(privileged) 포트 바인딩 (Bind to privileged port)
기본적으로 Cilium L7 Envoy 프로세스는 out-of-the-box로 Linux 능력(capabilities)이 없어서 특권 포트에서 수신할 수 없어요.
1023 이하의 포트를 선택한다면, Helm 값 envoy.securityContext.capabilities.keepCapNetBindService=true를 구성하고 해당 Cilium Envoy 컨테이너에 NET_BIND_SERVICE 능력을 추가해야 해요 (Helm values로요):
- 독립 DaemonSet 모드:
envoy.securityContext.capabilities.envoy - 임베디드 모드:
securityContext.capabilities.ciliumAgent
호스트 네트워크 모드에서 특권 포트 바인딩을 허용하려면 다음 Helm 값들을 구성해주세요:
gatewayAPI:
enabled: true
hostNetwork:
enabled: true
envoy:
enabled: true
securityContext:
capabilities:
keepCapNetBindService: true
envoy:
# Add NET_BIND_SERVICE to the list (keep the others!)
- NET_BIND_SERVICE
gatewayAPI:
enabled: true
hostNetwork:
enabled: true
envoy:
securityContext:
capabilities:
keepCapNetBindService: true
securityContext:
capabilities:
ciliumAgent:
# Add NET_BIND_SERVICE to the list (keep the others!)
- NET_BIND_SERVICE
노드 부분 집합에 Gateway API 리스너 배포하기 (Deploy Gateway API listeners on subset of nodes)
Cilium Gateway API Envoy 리스너는 노드의 특정 부분 집합에서만 노출할 수 있어요. 이는 호스트 네트워크 모드와 결합해서만 동작하며, Helm values의 노드 레이블 셀렉터로 구성할 수 있어요:
gatewayAPI:
enabled: true
hostNetwork:
enabled: true
nodes:
matchLabels:
role: infra
component: gateway-api
이렇게 하면 구성된 레이블과 일치하는 Cilium 노드에서만 Gateway API Envoy 리스너가 배포돼요. 빈 셀렉터는 모든 노드를 선택하며 모든 Cilium 노드에서 계속 기능을 노출해요.
Gateway API 주소 지원 (Gateway API Addresses Support)
Cilium Gateway는 Gateway API 스펙이 제공하는 Addresses를 지원해요. spec.addresses 필드는 gateway의 IP 주소를 지정하는 데 사용돼요.
참고
이 기능은
IPAddress유형의 주소만 지원하며, LB-IPAM과 함께 동작해요. 자세한 내용은 LoadBalancer IP Address Management (LB IPAM) 문서를 참고해주세요.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
addresses:
- type: IPAddress
value: 172.18.0.140
gatewayClassName: cilium
listeners:
- allowedRoutes:
namespaces:
from: Same
name: web-gw
port: 80
protocol: HTTP
위 구성의 출력은 다음과 같아요:
$ kubectl get gateway my-gateway
NAME CLASS ADDRESS PROGRAMMED AGE
my-gateway cilium 172.18.0.140 True 2d7h
이미 spec.infrastructure.annotations에서 io.cilium/lb-ipam-ips를 사용해 IP를 지정하고 있다면, spec.addresses 필드는 무시돼요.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
infrastructure:
annotations:
io.cilium/lb-ipam-ips: "172.18.0.141"
addresses: # This will be ignored
- type: IPAddress
value: 172.18.0.140
gatewayClassName: cilium
listeners:
- allowedRoutes:
namespaces:
from: Same
name: web-gw
port: 80
protocol: HTTP
위 구성의 출력은 다음과 같아요:
$ kubectl get gateway my-gateway
NAME CLASS ADDRESS PROGRAMMED AGE
my-gateway cilium 172.18.0.141 True 2d7h
참고
향후 어느 시점에
io.cilium/lb-ipam-ips의 사용이 더 이상 사용되지 않을(deprecate) 예정이고, 그 이후로는spec.addresses가 설정되지 않으면 이 어노테이션은 무시될 거예요. 두 경우 모두 Cilium agent 로그에 경고 로그가 추가되고, Gateway에는 경고 Condition이 배치돼요.
예제 (Examples)
Cilium의 Gateway API 기능을 사용하고 활용하는 방법은 아래 예제 중 하나를 참고해주세요:
- HTTP 예제
- HTTPS 예제
- gRPC 예제
- Traffic Splitting 예제
- HTTP Header Modifier 예제
- GatewayClass Parameters 지원
- Default TLS Certificate
- BackendTLSPolicy 예제
- Access Logs
- ListenerSet 지원
더 많은 예제는 업스트림 저장소에서 찾을 수 있어요.
문제 해결 (Troubleshooting)
이 페이지는 Gateway API의 다양한 메커니즘과 문제 해결 방법을 안내해요.
Troubleshooting Ingress & Service Mesh 페이지의 Generic 및 Setup Verification 단계를 반드시 따라주세요.
리소스 확인하기 (Checking resources)
- Gateway 리소스 확인
$ kubectl get gateway -A
NAMESPACE NAME CLASS ADDRESS PROGRAMMED AGE
website http-gateway cilium 172.21.255.202 True 5h
webshop tls-gateway cilium 172.21.255.203 True 5h
앞선 명령은 클러스터의 모든 Gateway에 대한 개요를 반환해요. 다음을 확인해주세요:
- Gateway가 프로그래밍됐나요?
- 프로그래밍된 Gateway란 Cilium이 그에 대한 구성을 준비했다는 뜻이에요.
Programmed true표시가 없다면 Cilium 구성에서 Gateway API가 활성화됐는지 확인해주세요.
- Gateway에 주소가 있나요?
kubectl get service로 서비스를 확인할 수 있어요.- Gateway에 주소가 있다면 LoadBalancer 서비스가 gateway에 할당됐다는 뜻이에요.
- IP가 나타나지 않는다면 LoadBalancer 구현이 빠졌을 수 있어요.
- 클래스가
cilium인가요?- Cilium은
cilium클래스의 Gateway만 프로그래밍해요.
- Cilium은
- Gateway API 리소스 유형(
Gateway,HTTPRoute등)이 발견되지 않으면 Gateway API CRD가 설치됐는지 확인해주세요.
kubectl describe gateway로 문제를 더 자세히 조사할 수 있어요.
$ kubectl describe gateway <name>
Conditions:
Message: Gateway successfully scheduled
Reason: Accepted
Status: True
Type: Accepted
Message: Gateway successfully reconciled
Reason: Programmed
Status: True
Type: Programmed
[...]
Listeners:
Attached Routes: 2
Conditions:
Message: Listener Ready
Reason: Programmed
Status: True
Type: Programmed
Message: Listener Accepted
Reason: Accepted
Status: True
[...]
gateway의 일반 상태와 구성된 리스너의 상태를 볼 수 있어요.
리스너 상태는 리스너에 성공적으로 연결된 라우트 수를 표시해요.
gateway와 listener 모두에 대한 상태 조건을 볼 수 있어요:
Accepted: Gateway 구성이 수락됐어요.Programmed: Gateway 구성이 Envoy에 프로그래밍됐어요.ResolvedRefs: 참조된 모든 시크릿이 발견됐고 사용 권한이 있어요.
이 조건 중 하나라도 false로 설정되면, Message와 Reason 필드가 더 많은 정보를 제공해요.
- HTTPRoute 리소스 확인
Gateway가 동작하면 라우트를 확인해서 올바르게 구성됐는지 검증할 수 있어요. 라우트 상태를 확인하는 방법은 gateway 리소스 상태를 확인하는 것과 비슷해요.
이 지침은 HTTPRoute용으로 작성됐지만, 다른 라우트 유형에도 적용돼요.
$ kubectl get httproute -A
NAMESPACE NAME HOSTNAMES AGE
website homepage www.example.org 17m
webshop catalog-service 17m
webshop cart-service 17m
더 많은 정보를 얻으려면 kubectl describe httproute <name>을 입력해주세요.
$ kubectl describe httproute <name>
Status:
Parents:
Conditions:
Last Transition Time: 2023-06-05T15:11:53Z
Message: Accepted HTTPRoute
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2023-06-05T15:11:53Z
Message: Service reference is valid
Observed Generation: 1
Reason: ResolvedRefs
Status: True
Type: ResolvedRefs
Controller Name: io.cilium/gateway-controller
Parent Ref:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: same-namespace
Status는 특정 HTTPRoute와 관련된 조건들을 나열해요. 조건은 gateway에 대한 부모 참조별로 나열돼요. 라우트를 여러 gateway에 연결했다면 여러 항목이 나타나요. 조건에는 Reason, Type, Status, Message가 포함돼요. Type은 조건 유형을 나타내고, Status는 조건 유형이 충족되는지 여부를 boolean으로 나타내요. 선택적으로 Message가 조건에 대한 추가 정보를 제공해요.
다음 조건 유형을 주목해주세요:
Accepted: HTTPRoute 구성이 올바르고 수락됐어요.ResolvedRefs: 참조된 서비스가 발견됐고 유효한 참조예요.
이 중 하나라도 false로 설정되면 Message와 Reason 필드를 살펴보면 더 많은 정보를 얻을 수 있어요.
- Cilium Operator 로그 확인
Cilium Operator 로그에는 추가 디버깅 정보가 있을 수 있어요. 예를 들어 필요한 CRD(Custom Resource Definitions)가 설치되지 않으면 오류가 기록돼요:
$ kubectl logs -n kube-system deployments/cilium-operator | grep gateway
level=error msg="Required GatewayAPI resources are not found, please
refer to docs for installation instructions" error="customresourcedefinitions.apiextensions.k8s.io \"gatewayclasses.gateway.networking.k8s.io\" not found
customresourcedefinitions.apiextensions.k8s.io \"gateways.gateway.networking.k8s.io\" not found
customresourcedefinitions.apiextensions.k8s.io \"httproutes.gateway.networking.k8s.io\" not found
customresourcedefinitions.apiextensions.k8s.io \"referencegrants.gateway.networking.k8s.io\" not found
customresourcedefinitions.apiextensions.k8s.io \"grpcroutes.gateway.networking.k8s.io\" not found
customresourcedefinitions.apiextensions.k8s.io \"tlsroutes.gateway.networking.k8s.io\" not found" subsys=gateway-api
흔한 실수 (Common mistakes)
경고
Gateway API는 Kubernetes에 최근에 추가된 것이며, Cilium 프로젝트는 아직 많은 사용자 피드백을 받지 못했어요. 이 섹션에 아직 나열되지 않은 문제를 만난다면 이 목록에 여러분의 문제를 추가하는 PR을 여는 것을 고려해보세요.
- 백엔드 서비스가 존재하지 않아요.
- 백엔드 서비스가 발견됐는지 확인하려면
kubectl describe httproute <name>을 실행하고conditions필드를 검사해주세요:
- 백엔드 서비스가 발견됐는지 확인하려면
Parents:
Conditions:
Last Transition Time: 2023-06-06T13:55:10Z
Message: Service "backend" not found
Observed Generation: 1
Reason: BackendNotFound
Status: False
Type: ResolvedRefs
Last Transition Time: 2023-06-06T13:55:10Z
Message: Accepted HTTPRoute
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Controller Name: io.cilium/gateway-controller
parentRefs아래에 지정된 gateway가 존재하지 않아요.- gateway가 발견됐는지 확인하려면
kubectl describe httproute <name>을 실행하고conditions필드를 검사해주세요:
- gateway가 발견됐는지 확인하려면
Parents:
Conditions:
Last Transition Time: 2023-06-06T13:56:40Z
Message: Gateway.gateway.networking.k8s.io "my-gateway" not found
Observed Generation: 2
Reason: InvalidHTTPRoute
Status: False
Type: Accepted
기본 메커니즘: 높은 수준 개요 (Underlying mechanics: a high level overview)
Cilium 배포에는 Gateway API 리소스를 처리하는 두 부분이 있어요: Cilium agent와 Cilium operator예요.
Cilium operator는 모든 Gateway API 리소스를 감시하고 리소스가 유효한지 검증해요. 리소스가 유효하면 operator가 이를 accepted로 표시해요. 그러면 Cilium Envoy Configuration 리소스로의 변환 과정이 시작돼요.
그 다음 Cilium agent가 Cilium Envoy Configuration 리소스를 가져와요.
Cilium agent는 이 리소스들을 사용해 내장 Envoy 또는 Envoy DaemonSet에 구성을 공급해요. Envoy가 트래픽을 처리해요.
더 알아보기 (Learn more)
- Gateway API (HTTP) — HTTP Gateway 예제
- Gateway API (HTTPS) — HTTPS Gateway 예제
- Gateway API 설치 — CRD 설치와 컨트롤러 활성화
- GAMMA 지원 — GAMMA 메시 기능 지원