하이브리드 노드용 Kubernetes Ingress 구성하기
하이브리드 노드용 Kubernetes Ingress 구성하기 (Configure Kubernetes Ingress for hybrid nodes)
이 주제는 Amazon EKS Hybrid Nodes에서 실행되는 워크로드에 Kubernetes Ingress를 구성하는 방법을 설명해요. Kubernetes Ingress는 클러스터 외부에서 클러스터 내부의 서비스로 HTTP 및 HTTPS 경로를 노출해요. Ingress 리소스를 사용하려면 네트워크 트래픽을 제공하는 네트워킹 인프라와 컴포넌트를 설정하는 Kubernetes Ingress 컨트롤러가 필요해요.
AWS는 EKS Hybrid Nodes에서 실행되는 워크로드에 대한 Kubernetes Ingress에 AWS Application Load Balancer(ALB)와 Cilium을 지원해요. Ingress에 ALB를 사용할지 Cilium을 사용할지는 애플리케이션 트래픽의 소스에 따라 결정돼요. 애플리케이션 트래픽이 AWS 리전에서 발생한다면 AWS ALB와 AWS Load Balancer Controller를 사용하는 것을 권장해요. 애플리케이션 트래픽이 로컬 온프레미스나 엣지 환경에서 발생한다면 환경의 로드 밸런서 인프라와 함께 또는 없이 사용할 수 있는 Cilium의 내장 Ingress 기능을 사용하는 것을 권장해요.
출처: 문서
본문
AWS Application Load Balancer
하이브리드 노드에서 실행되는 워크로드에 대상 유형(target type)이 ip인 AWS Load Balancer Controller와 ALB(Application Load Balancer)를 사용할 수 있어요. 대상 유형 ip를 사용하면 ALB가 Service 레이어 네트워크 경로를 우회해 Pod로 직접 트래픽을 전달해요. ALB가 하이브리드 노드의 Pod IP 대상에 도달하려면 온프레미스 Pod CIDR이 온프레미스 네트워크에서 라우팅 가능해야 해요. 또한 AWS Load Balancer Controller는 웹훅을 사용하며 EKS 컨트롤 플레인과의 직접 통신이 필요해요. 자세한 내용은 하이브리드 노드용 웹훅 구성하기를 참고하세요.
고려 사항
- AWS Application Load Balancer 및 AWS Load Balancer Controller에 대한 자세한 내용은 Application Load Balancer로 애플리케이션 및 HTTP 트래픽 라우팅하기 및 Helm으로 AWS Load Balancer Controller 설치하기를 참고하세요.
- AWS Application Load Balancer와 AWS Network Load Balancer 사이에서 선택하는 방법은 로드 밸런싱 모범 사례를 참고하세요.
- AWS Application Load Balancer로 Ingress 리소스에 구성할 수 있는 어노테이션 목록은 AWS Load Balancer Controller Ingress 어노테이션을 참고하세요.
사전 요구 사항
- 하이브리드 노드용 CNI 구성하기의 지침에 따라 Cilium이 설치되어 있어야 해요.
- 하이브리드 노드용 Cilium BGP 구성하기의 지침에 따라 Cilium BGP Control Plane이 활성화되어 있어야 해요. BGP를 사용하지 않으려면 온프레미스 네트워크에서 온프레미스 Pod CIDR을 라우팅 가능하게 만드는 대체 방법을 사용해야 해요. 온프레미스 Pod CIDR을 라우팅 가능하게 만들지 않으면 ALB가 Pod IP 대상을 등록하거나 접촉할 수 없어요.
- 명령줄 환경에 Helm이 설치되어 있어야 해요. 자세한 내용은 Setup Helm 지침을 참고하세요.
- 명령줄 환경에 eksctl이 설치되어 있어야 해요. 자세한 내용은 eksctl 설치 지침을 참고하세요.
절차
- AWS Load Balancer Controller가 여러분을 대신해 AWS API를 호출할 수 있게 하는 IAM 정책을 다운로드해요.
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json - 이전 단계에서 다운로드한 정책으로 IAM 정책을 만들어요.
aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam_policy.json - 클러스터 이름(
CLUSTER_NAME), AWS 리전(AWS_REGION), AWS 계정 ID(AWS_ACCOUNT_ID) 값을 여러분의 설정으로 바꾸고 다음 명령을 실행해요.eksctl create iamserviceaccount \ --cluster=CLUSTER_NAME \ --namespace=kube-system \ --name=aws-load-balancer-controller \ --attach-policy-arn=arn:aws:iam::AWS_ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \ --override-existing-serviceaccounts \ --region AWS_REGION \ --approve - eks-charts Helm 차트 저장소를 추가하고 로컬 Helm 저장소를 업데이트해 가장 최신 차트가 있는지 확인해요.
helm repo add eks https://aws.github.io/eks-chartshelm repo update eks - AWS Load Balancer Controller를 설치해요. 클러스터 이름(
CLUSTER_NAME), AWS 리전(AWS_REGION), VPC ID(VPC_ID), AWS Load Balancer Controller Helm 차트 버전(AWS_LBC_HELM_VERSION) 값을 여러분의 설정으로 바꾸고 다음 명령을 실행해요. 하이브리드 노드와 AWS Cloud의 노드가 모두 있는 혼합 모드 클러스터를 실행한다면 AWS Load Balancer Controller 안내에 따라 클라우드 노드에서 AWS Load Balancer Controller를 실행할 수 있어요.helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ -n kube-system \ --version AWS_LBC_HELM_VERSION \ --set clusterName=CLUSTER_NAME \ --set region=AWS_REGION \ --set vpcId=VPC_ID \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controllerhelm search repo eks/aws-load-balancer-controller --versions를 실행해 Helm 차트의 최신 버전을 찾을 수 있어요. - AWS Load Balancer Controller가 성공적으로 설치되었는지 확인해요.
kubectl get -n kube-system deployment aws-load-balancer-controllerNAME READY UP-TO-DATE AVAILABLE AGE aws-load-balancer-controller 2/2 2 2 84s - 샘플 애플리케이션을 만들어요. 아래 예시는 Istio Bookinfo 샘플 마이크로서비스 애플리케이션을 사용해요.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml - 다음 내용으로
my-ingress-alb.yaml이라는 파일을 만들어요.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: default annotations: alb.ingress.kubernetes.io/load-balancer-name: "my-ingress-alb" alb.ingress.kubernetes.io/target-type: "ip" alb.ingress.kubernetes.io/scheme: "internet-facing" alb.ingress.kubernetes.io/healthcheck-path: "/details/1" spec: ingressClassName: alb rules: - http: paths: - backend: service: name: details port: number: 9080 path: /details pathType: Prefix - Ingress 구성을 클러스터에 적용해요.
Ingress 리소스용 ALB 프로비저닝에 몇 분이 걸릴 수 있어요. ALB가 프로비저닝되면 Ingress 리소스에 ALB 배포의 DNS 이름에 해당하는 주소가 할당돼요. 주소 형식은kubectl apply -f my-ingress-alb.yaml-..elb.amazonaws.com이에요.kubectl get ingress my-ingressNAME CLASS HOSTS ADDRESS PORTS AGE my-ingress alb * my-ingress-alb-..elb.amazonaws.com 80 23m - ALB의 주소를 사용해 Service에 접근해요.
curl -s http//my-ingress-alb-..elb.amazonaws.com:80/details/1 | jq{ "id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890" "details": "This is the details page" }
Cilium Ingress 및 Cilium Gateway 개요
Cilium의 Ingress 기능은 Cilium의 아키텍처에 내장되어 있으며 Kubernetes Ingress API나 Gateway API로 관리할 수 있어요. 기존 Ingress 리소스가 없다면 AWS는 Gateway API로 시작하는 것을 권장해요. Gateway API는 Kubernetes 네트워킹 리소스를 정의하고 관리하는 더 표현적이고 유연한 방식이기 때문이에요. Kubernetes Gateway API는 Ingress, Load Balancing, Service Mesh용 네트워킹 리소스가 Kubernetes 클러스터에서 정의되고 관리되는 방식을 표준화하는 것을 목표로 해요.
Cilium의 Ingress 또는 Gateway 기능을 활성화하면 Cilium operator가 클러스터의 Ingress / Gateway 객체를 조정하고, 각 노드의 Envoy 프록시가 레이어 7(L7) 네트워크 트래픽을 처리해요. Cilium은 로드 밸런서 같은 Ingress / Gateway 인프라를 직접 프로비저닝하지 않아요. 로드 밸런서와 함께 Cilium Ingress / Gateway를 사용할 계획이라면 일반적으로 Ingress 또는 Gateway 컨트롤러인 로드 밸런서의 도구를 사용해 로드 밸런서의 인프라를 배포하고 관리해야 해요.
Ingress / Gateway 트래픽의 경우 Cilium은 핵심 네트워크 트래픽과 L3/L4 정책 적용을 처리하고, 통합된 Envoy 프록시가 L7 네트워크 트래픽을 처리해요. Cilium Ingress / Gateway를 사용하면 Envoy가 L7 라우팅 규칙, 정책, 요청 조작, 트래픽 분할 및 미러링 같은 고급 트래픽 관리, TLS 종료 및 시작을 적용하는 역할을 해요. Cilium의 Envoy 프록시는 기본적으로 별도의 DaemonSet(cilium-envoy)으로 배포되며, 이를 통해 Envoy와 Cilium 에이전트를 별도로 업데이트하고, 확장하고, 관리할 수 있어요.
Cilium Ingress와 Cilium Gateway의 작동 방식에 대한 자세한 내용은 Cilium 문서의 Cilium Ingress 및 Cilium Gateway 페이지를 참고하세요.
Cilium Ingress 및 Gateway 비교
다음 표는 Cilium 버전 1.17.x 기준의 Cilium Ingress와 Cilium Gateway 기능을 요약해요.
| 기능 | Ingress | Gateway |
|---|---|---|
| Service 유형 LoadBalancer | 예 | 예 |
| Service 유형 NodePort | 예 | 아니요1 |
| 호스트 네트워크 | 예 | 예 |
| 공유 로드 밸런서 | 예 | 예 |
| 전용 로드 밸런서 | 예 | 아니요2 |
| 네트워크 정책 | 예 | 예 |
| 프로토콜 | 레이어 7 (HTTP(S), gRPC) | 레이어 7 (HTTP(S), gRPC)3 |
| TLS 패스스루 | 예 | 예 |
| 트래픽 관리 | 경로 및 호스트 라우팅 | 경로 및 호스트 라우팅, URL 리디렉트 및 재작성, 트래픽 분할, 헤더 수정 |
- NodePort 서비스에 대한 Cilium Gateway 지원은 Cilium 버전 1.18.x에서 계획됨 (#27273)
- 전용 로드 밸런서에 대한 Cilium Gateway 지원 (#25567)
- TCP/UDP에 대한 Cilium Gateway 지원 (#21929)
Cilium Gateway 설치
고려 사항
- 아래 예시처럼 Cilium을
nodePort.enabled가true로 구성해야 해요. Cilium의 kube-proxy 대체 기능을 사용한다면nodePort.enabled를true로 설정할 필요가 없어요. - 아래 예시처럼 Cilium을
envoy.enabled가true로 구성해야 해요. - Cilium Gateway는 로드 밸런서 모드(기본값) 또는 호스트 네트워크 모드로 배포할 수 있어요.
- Cilium Gateway를 로드 밸런서 모드로 사용할 때는 레거시 AWS 클라우드 프로바이더가 Cilium이 Gateway 리소스에 대해 만드는 Service of type LoadBalancer에 대해 Classic Load Balancer를 만들지 못하게 하려면 Gateway 리소스에
service.beta.kubernetes.io/aws-load-balancer-type: "external"어노테이션을 설정해야 해요. - Cilium Gateway를 호스트 네트워크 모드로 사용할 때는 Service of type LoadBalancer 모드가 비활성화돼요. 호스트 네트워크 모드는 로드 밸런서 인프라가 없는 환경에 유용해요. 자세한 내용은 호스트 네트워크를 참고하세요.
사전 요구 사항
- 명령줄 환경에 Helm이 설치되어 있어야 해요. Setup Helm 지침을 참고하세요.
- 하이브리드 노드용 CNI 구성하기의 지침에 따라 Cilium이 설치되어 있어야 해요.
절차
- Kubernetes Gateway API 커스텀 리소스 정의(CRD)를 설치해요.
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_gateways.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.2.1/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml - 다음 내용으로
cilium-gateway-values.yaml이라는 파일을 만들어요. 아래 예시는 Cilium Gateway를 기본 로드 밸런서 모드와, 하이브리드 노드에서만 실행되도록 구성된 별도의cilium-envoyDaemonSet을 사용하도록 구성해요.gatewayAPI: enabled: true # uncomment to use host network mode # hostNetwork: # enabled: true nodePort: enabled: true envoy: enabled: true affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/compute-type operator: In values: - hybrid - Helm 값 파일을 클러스터에 적용해요.
helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \ --namespace kube-system \ --reuse-values \ --set operator.rollOutPods=true \ --values cilium-gateway-values.yaml - Cilium operator, 에이전트, Envoy Pod가 실행 중인지 확인해요.
kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=ciliumNAME READY STATUS RESTARTS AGE cilium-envoy-5pgnd 1/1 Running 0 6m31s cilium-envoy-6fhg4 1/1 Running 0 6m30s cilium-envoy-jskrk 1/1 Running 0 6m30s cilium-envoy-k2xtb 1/1 Running 0 6m31s cilium-envoy-w5s9j 1/1 Running 0 6m31s cilium-grwlc 1/1 Running 0 4m12s cilium-operator-68f7766967-5nnbl 1/1 Running 0 4m20s cilium-operator-68f7766967-7spfz 1/1 Running 0 4m20s cilium-pnxcv 1/1 Running 0 6m29s cilium-r7qkj 1/1 Running 0 4m12s cilium-wxhfn 1/1 Running 0 4m1s cilium-z7hlb 1/1 Running 0 6m30s
Cilium Gateway 구성
Cilium Gateway는 Gateway 객체에서 gatewayClassName을 cilium으로 설정해 활성화해요. Cilium이 Gateway 리소스에 대해 만드는 Service는 Gateway 객체의 필드로 구성할 수 있어요. Gateway 컨트롤러가 로드 밸런서 인프라를 구성하는 데 사용하는 일반적인 어노테이션은 Gateway 객체의 infrastructure 필드로 구성할 수 있어요. Cilium의 LoadBalancer IPAM을 사용할 때(Service type LoadBalancer의 예시 참고) Service of type LoadBalancer에 사용할 IP 주소는 Gateway 객체의 addresses 필드로 구성할 수 있어요. Gateway 구성에 대한 자세한 내용은 Kubernetes Gateway API 사양을 참고하세요.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: cilium
infrastructure:
annotations:
service.beta.kubernetes.io/...
service.kubernetes.io/...
addresses:
- type: IPAddress
value:
listeners:
...
Cilium과 Kubernetes Gateway 사양은 GatewayClass, Gateway, HTTPRoute, GRPCRoute, ReferenceGrant 리소스를 지원해요.
사용 가능한 필드 목록은 HTTPRoute 및 GRPCRoute 사양을 참고하세요.
이러한 리소스를 사용하고 구성하는 방법은 아래의 Cilium Gateway 배포하기 섹션의 예시와 Cilium 문서의 예시를 참고하세요.
Cilium Gateway 배포
- 샘플 애플리케이션을 만들어요. 아래 예시는 Istio Bookinfo 샘플 마이크로서비스 애플리케이션을 사용해요.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml - 애플리케이션이 성공적으로 실행 중인지 확인해요.
kubectl get podsNAME READY STATUS RESTARTS AGE details-v1-766844796b-9965p 1/1 Running 0 81s productpage-v1-54bb874995-jmc8j 1/1 Running 0 80s ratings-v1-5dc79b6bcd-smzxz 1/1 Running 0 80s reviews-v1-598b896c9d-vj7gb 1/1 Running 0 80s reviews-v2-556d6457d-xbt8v 1/1 Running 0 80s reviews-v3-564544b4d6-cpmvq 1/1 Running 0 80s - 다음 내용으로
my-gateway.yaml이라는 파일을 만들어요. 아래 예시는 레거시 AWS 클라우드 프로바이더가 Cilium이 Gateway 리소스에 대해 만드는 Service of type LoadBalancer에 대해 Classic Load Balancer를 만들지 못하게 하는service.beta.kubernetes.io/aws-load-balancer-type: "external"어노테이션을 사용해요.--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway spec: gatewayClassName: cilium infrastructure: annotations: service.beta.kubernetes.io/aws-load-balancer-type: "external" listeners: - protocol: HTTP port: 80 name: web-gw allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http-app-1 spec: parentRefs: - name: my-gateway namespace: default rules: - matches: - path: type: PathPrefix value: /details backendRefs: - name: details port: 9080 - Gateway 리소스를 클러스터에 적용해요.
kubectl apply -f my-gateway.yaml - Gateway 리소스와 해당 Service가 생성되었는지 확인해요. 이 단계에서 Gateway 리소스의
ADDRESS필드는 IP 주소나 호스트 이름으로 채워지지 않고, Gateway 리소스의 Service of type LoadBalancer도 IP 주소나 호스트 이름이 할당되지 않은 것이 예상돼요.kubectl get gateway my-gatewayNAME CLASS ADDRESS PROGRAMMED AGE my-gateway cilium True 10skubectl get svc cilium-gateway-my-gatewayNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-gateway-my-gateway LoadBalancer 172.16.227.247 80:30912/TCP 24s - Service type LoadBalancer로 진행해 Gateway 리소스가 Cilium Load Balancer IPAM으로 할당된 IP 주소를 사용하도록 구성하고, Service type NodePort 또는 호스트 네트워크로 진행해 Gateway 리소스가 NodePort 또는 호스트 네트워크 주소를 사용하도록 구성해요.
Cilium Ingress 설치
고려 사항
- 아래 예시처럼 Cilium을
nodePort.enabled가true로 구성해야 해요. Cilium의 kube-proxy 대체 기능을 사용한다면nodePort.enabled를true로 설정할 필요가 없어요. - 아래 예시처럼 Cilium을
envoy.enabled가true로 구성해야 해요. ingressController.loadbalancerMode가dedicated로 설정되면 Cilium이 각 Ingress 리소스에 대해 전용 Service를 만들어요.ingressController.loadbalancerMode가shared로 설정되면 Cilium이 클러스터의 모든 Ingress 리소스에 대해 공유 Service of type LoadBalancer를 만들어요.shared로드 밸런서 모드를 사용할 때labels,annotations,type,loadBalancerIP같은 공유 Service의 설정은 Helm 값의ingressController.service섹션에 구성돼요. 자세한 내용은 Cilium Helm values 참조를 참고하세요.ingressController.default가true로 설정되면 Cilium이 클러스터의 기본 Ingress 컨트롤러로 구성되며, Ingress 리소스에ingressClassName이 지정되지 않아도 Ingress 항목을 만들어요.- Cilium Ingress는 로드 밸런서(기본값), 노드 포트, 호스트 네트워크 모드로 배포할 수 있어요. Cilium이 호스트 네트워크 모드로 설치되면 Service of type LoadBalancer 및 Service of type NodePort 모드가 비활성화돼요. 자세한 내용은 호스트 네트워크를 참고하세요.
- Cilium Helm 차트가 만드는 기본
cilium-ingressService에 대해 레거시 AWS 클라우드 프로바이더가 Classic Load Balancer를 만들지 못하게 하려면 Helm 값에서ingressController.service.annotations를 항상service.beta.kubernetes.io/aws-load-balancer-type: "external"로 설정하세요.
사전 요구 사항
- 명령줄 환경에 Helm이 설치되어 있어야 해요. Setup Helm 지침을 참고하세요.
- 하이브리드 노드용 CNI 구성하기의 지침에 따라 Cilium이 설치되어 있어야 해요.
절차
- 다음 내용으로
cilium-ingress-values.yaml이라는 파일을 만들어요. 아래 예시는 Cilium Ingress를 기본 로드 밸런서dedicated모드와, 하이브리드 노드에서만 실행되도록 구성된 별도의cilium-envoyDaemonSet을 사용하도록 구성해요.ingressController: enabled: true loadbalancerMode: dedicated service: annotations: service.beta.kubernetes.io/aws-load-balancer-type: "external" nodePort: enabled: true envoy: enabled: true affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/compute-type operator: In values: - hybrid - Helm 값 파일을 클러스터에 적용해요.
helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \ --namespace kube-system \ --reuse-values \ --set operator.rollOutPods=true \ --values cilium-ingress-values.yaml - Cilium operator, 에이전트, Envoy Pod가 실행 중인지 확인해요.
kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=ciliumNAME READY STATUS RESTARTS AGE cilium-envoy-5pgnd 1/1 Running 0 6m31s cilium-envoy-6fhg4 1/1 Running 0 6m30s cilium-envoy-jskrk 1/1 Running 0 6m30s cilium-envoy-k2xtb 1/1 Running 0 6m31s cilium-envoy-w5s9j 1/1 Running 0 6m31s cilium-grwlc 1/1 Running 0 4m12s cilium-operator-68f7766967-5nnbl 1/1 Running 0 4m20s cilium-operator-68f7766967-7spfz 1/1 Running 0 4m20s cilium-pnxcv 1/1 Running 0 6m29s cilium-r7qkj 1/1 Running 0 4m12s cilium-wxhfn 1/1 Running 0 4m1s cilium-z7hlb 1/1 Running 0 6m30s
Cilium Ingress 구성
Cilium Ingress는 Ingress 객체에서 ingressClassName을 cilium으로 설정해 활성화해요. Cilium이 Ingress 리소스에 대해 만드는 Service는 dedicated 로드 밸런서 모드에서 Ingress 객체의 어노테이션으로, shared 로드 밸런서 모드에서는 Cilium / Helm 구성으로 구성할 수 있어요. 이러한 어노테이션은 Ingress 컨트롤러가 로드 밸런서 인프라를 구성하거나 서비스 유형, 로드 밸런서 모드, 포트, TLS 패스스루 같은 Service의 다른 속성을 구성하는 데 일반적으로 사용돼요. 주요 어노테이션은 아래에 설명돼요. 지원되는 어노테이션의 전체 목록은 Cilium 문서의 Cilium Ingress 어노테이션을 참고하세요.
| 어노테이션 | 설명 |
|---|---|
ingress.cilium.io/loadbalancer-mode |
dedicated: 각 Ingress 리소스에 대한 전용 Service of type LoadBalancer(기본값). shared: 모든 Ingress 리소스에 대한 단일 Service of type LoadBalancer. |
ingress.cilium.io/service-type |
LoadBalancer: Service가 LoadBalancer 유형이 됨(기본값). NodePort: Service가 NodePort 유형이 됨. |
service.beta.kubernetes.io/aws-load-balancer-type |
"external": 레거시 AWS 클라우드 프로바이더가 Service of type LoadBalancer에 대해 Classic Load Balancer를 프로비저닝하지 못하게 함. |
lbipam.cilium.io/ips |
Cilium LoadBalancer IPAM에서 할당할 IP 주소 목록. |
Cilium과 Kubernetes Ingress 사양은 Ingress 경로에 Exact, Prefix, Implementation-specific 일치 규칙을 지원해요. Cilium은 구현별 일치 규칙으로 정규식을 지원해요. 자세한 내용은 Cilium 문서의 Ingress 경로 유형 및 우선순위와 Path types examples, 그리고 이 페이지의 Cilium Ingress 배포하기 섹션의 예시를 참고하세요.
예시 Cilium Ingress 객체는 아래와 같아요.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
service.beta.kubernetes.io/...
service.kubernetes.io/...
spec:
ingressClassName: cilium
rules:
...
Cilium Ingress 배포
- 샘플 애플리케이션을 만들어요. 아래 예시는 Istio Bookinfo 샘플 마이크로서비스 애플리케이션을 사용해요.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml - 애플리케이션이 성공적으로 실행 중인지 확인해요.
kubectl get podsNAME READY STATUS RESTARTS AGE details-v1-766844796b-9965p 1/1 Running 0 81s productpage-v1-54bb874995-jmc8j 1/1 Running 0 80s ratings-v1-5dc79b6bcd-smzxz 1/1 Running 0 80s reviews-v1-598b896c9d-vj7gb 1/1 Running 0 80s reviews-v2-556d6457d-xbt8v 1/1 Running 0 80s reviews-v3-564544b4d6-cpmvq 1/1 Running 0 80s - 다음 내용으로
my-ingress.yaml이라는 파일을 만들어요. 아래 예시는 레거시 AWS 클라우드 프로바이더가 Cilium이 Ingress 리소스에 대해 만드는 Service of type LoadBalancer에 대해 Classic Load Balancer를 만들지 못하게 하는service.beta.kubernetes.io/aws-load-balancer-type: "external"어노테이션을 사용해요.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: default annotations: service.beta.kubernetes.io/aws-load-balancer-type: "external" spec: ingressClassName: cilium rules: - http: paths: - backend: service: name: details port: number: 9080 path: /details pathType: Prefix - Ingress 리소스를 클러스터에 적용해요.
kubectl apply -f my-ingress.yaml - Ingress 리소스와 해당 Service가 생성되었는지 확인해요. 이 단계에서 Ingress 리소스의
ADDRESS필드는 IP 주소나 호스트 이름으로 채워지지 않고, Ingress 리소스의 공유 또는 전용 Service of type LoadBalancer도 IP 주소나 호스트 이름이 할당되지 않은 것이 예상돼요.kubectl get ingress my-ingress
로드 밸런서 모드NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress cilium * 80 8sshared의 경우:kubectl -n kube-system get svc cilium-ingress
로드 밸런서 모드NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress LoadBalancer 172.16.217.48 80:32359/TCP,443:31090/TCP 10mdedicated의 경우:kubectl -n default get svc cilium-ingress-my-ingressNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress-my-ingress LoadBalancer 172.16.193.15 80:32088/TCP,443:30332/TCP 25s - Service type LoadBalancer로 진행해 Ingress 리소스가 Cilium Load Balancer IPAM으로 할당된 IP 주소를 사용하도록 구성하고, Service type NodePort 또는 호스트 네트워크로 진행해 Ingress 리소스가 NodePort 또는 호스트 네트워크 주소를 사용하도록 구성해요.
Service type LoadBalancer
기존 로드 밸런서 인프라
기본적으로 Cilium Ingress와 Cilium Gateway 모두에서 Cilium은 Ingress / Gateway 리소스에 대해 Service of type LoadBalancer인 Kubernetes Service를 만들어요. Cilium이 만드는 Service의 속성은 Ingress 및 Gateway 리소스를 통해 구성할 수 있어요. Ingress 또는 Gateway 리소스를 만들 때 Ingress 또는 Gateway에 대해 외부로 노출된 IP 주소나 호스트 이름은 일반적으로 Ingress 또는 Gateway 컨트롤러가 프로비저닝하는 로드 밸런서 인프라에서 할당돼요.
많은 Ingress 및 Gateway 컨트롤러는 어노테이션을 사용해 로드 밸런서 인프라를 감지하고 구성해요. 이러한 Ingress 및 Gateway 컨트롤러의 어노테이션은 이전 예시에서 보여준 것처럼 Ingress 또는 Gateway 리소스에 구성돼요. 컨트롤러가 지원하는 어노테이션에 대해 Ingress 또는 Gateway 컨트롤러의 문서를 참조하고, 인기 있는 컨트롤러 목록은 Kubernetes Ingress 문서 및 Kubernetes Gateway 문서를 참고하세요.
중요
Cilium Ingress 및 Gateway는 EKS Hybrid Nodes에서 AWS Load Balancer Controller 및 AWS Network Load Balancer(NLB)와 함께 사용할 수 없어요. 이들을 함께 사용하려 하면 NLB의
target-type이ip로 설정될 때(EKS Hybrid Nodes에서 실행되는 워크로드에 NLB를 사용하기 위한 요구사항) NLB가 Service of type LoadBalancer를 백하는 Pod IP에 직접 연결하려 하므로 등록되지 않은 대상이 발생해요.
로드 밸런서 인프라 없음
환경에 로드 밸런서 인프라와 해당 Ingress / Gateway 컨트롤러가 없다면, Ingress / Gateway 리소스와 해당 Service of type LoadBalancer를 Cilium의 LB IPAM(Load Balancer IP 주소 관리)이 할당한 IP 주소를 사용하도록 구성할 수 있어요. Cilium LB IPAM은 온프레미스 환경의 알려진 IP 주소 범위로 구성할 수 있고, Cilium의 내장 BGP(Border Gateway Protocol) 지원 또는 L2 announcements를 사용해 LoadBalancer IP 주소를 온프레미스 네트워크에 광고할 수 있어요.
아래 예시는 Ingress / Gateway 리소스에 사용할 IP 주소로 Cilium의 LB IPAM을 구성하고, Cilium BGP Control Plane을 구성해 LoadBalancer IP 주소를 온프레미스 네트워크에 광고하는 방법을 보여줘요. Cilium의 LB IPAM 기능은 기본적으로 활성화되어 있지만 CiliumLoadBalancerIPPool 리소스가 생성될 때까지 활성화되지 않아요.
사전 요구 사항
- Cilium Ingress 또는 Gateway 설치하기의 지침에 따라 Cilium Ingress 또는 Gateway가 설치되어 있어야 해요.
- Cilium Ingress 또는 Gateway 배포하기의 지침에 따라 샘플 애플리케이션이 배포된 Cilium Ingress 또는 Gateway 리소스가 있어야 해요.
- Cilium BGP Control Plane은 하이브리드 노드용 Cilium BGP 구성하기의 지침에 따라 활성화되어 있어야 해요. BGP를 사용하지 않으려면 이 사전 요구 사항을 건너뛸 수 있지만, Cilium LB IPAM이 할당한 LoadBalancer IP 주소가 온프레미스 네트워크에서 라우팅 가능해질 때까지 Ingress 또는 Gateway 리소스에 접근할 수 없어요.
절차
- 선택 사항으로 Ingress 또는 Gateway 리소스를 패치해 Service of type LoadBalancer에 사용할 특정 IP 주소를 요청해요. 특정 IP 주소를 요청하지 않으면 Cilium은 후속 단계에서
CiliumLoadBalancerIPPool리소스에 구성된 IP 주소 범위에서 IP 주소를 할당해요. 아래 명령에서LB_IP_ADDRESS를 Service of type LoadBalancer에 요청할 IP 주소로 바꾸세요.- Gateway:
kubectl patch gateway -n default my-gateway --type=merge -p '{ "spec": { "addresses": [{"type": "IPAddress", "value": "LB_IP_ADDRESS"}] } }' - Ingress:
kubectl patch ingress my-ingress --type=merge -p '{ "metadata": {"annotations": {"lbipam.cilium.io/ips": "LB_IP_ADDRESS"}} }'
- Gateway:
- Ingress / Gateway 리소스의 Load Balancer IP 주소 범위를 구성하는
CiliumLoadBalancerIPPool리소스가 있는cilium-lbip-pool-ingress.yaml이라는 파일을 만들어요. Cilium Ingress를 사용한다면 Cilium이 Ingress 리소스에 대해 만드는 Service에cilium.io/ingress: "true"레이블을 자동으로 적용해요.CiliumLoadBalancerIPPool리소스 정의의serviceSelector필드에서 이 레이블을 사용해 LB IPAM에 적격한 Service를 선택할 수 있어요. Cilium Gateway를 사용한다면CiliumLoadBalancerIPPool리소스 정의의serviceSelector필드에서gateway.networking.k8s.io/gateway-name레이블을 사용해 LB IPAM에 적격한 Gateway 리소스를 선택할 수 있어요.LB_IP_CIDR을 Load Balancer IP 주소에 사용할 IP 주소 범위로 바꾸세요. 단일 IP 주소를 선택하려면/32CIDR을 사용하세요. 자세한 내용은 Cilium 문서의 LoadBalancer IP 주소 관리를 참고하세요.apiVersion: cilium.io/v2alpha1 kind: CiliumLoadBalancerIPPool metadata: name: bookinfo-pool spec: blocks: - cidr: "LB_IP_CIDR" serviceSelector: # if using Cilium Gateway matchExpressions: - { key: gateway.networking.k8s.io/gateway-name, operator: In, values: [ my-gateway ] } # if using Cilium Ingress matchLabels: cilium.io/ingress: "true" CiliumLoadBalancerIPPool리소스를 클러스터에 적용해요.kubectl apply -f cilium-lbip-pool-ingress.yaml- Ingress / Gateway 리소스에 대해 Cilium LB IPAM에서 IP 주소가 할당되었는지 확인해요.
- Gateway:
kubectl get gateway my-gatewayNAME CLASS ADDRESS PROGRAMMED AGE my-gateway cilium LB_IP_ADDRESS True 6m41s - Ingress:
kubectl get ingress my-ingressNAME CLASS HOSTS ADDRESS PORTS AGE my-ingress cilium * LB_IP_ADDRESS 80 10m
- Gateway:
- Ingress / Gateway 리소스의 LoadBalancer IP 주소를 광고하는
CiliumBGPAdvertisement리소스가 있는cilium-bgp-advertisement-ingress.yaml이라는 파일을 만들어요. Cilium BGP를 사용하지 않는다면 이 단계를 건너뛸 수 있어요. Ingress / Gateway 리소스에 사용된 LoadBalancer IP 주소는 다음 단계에서 서비스를 쿼리할 수 있으려면 온프레미스 네트워크에서 라우팅 가능해야 해요.apiVersion: cilium.io/v2alpha1 kind: CiliumBGPAdvertisement metadata: name: bgp-advertisement-lb-ip labels: advertise: bgp spec: advertisements: - advertisementType: "Service" service: addresses: - LoadBalancerIP selector: # if using Cilium Gateway matchExpressions: - { key: gateway.networking.k8s.io/gateway-name, operator: In, values: [ my-gateway ] } # if using Cilium Ingress matchLabels: cilium.io/ingress: "true" CiliumBGPAdvertisement리소스를 클러스터에 적용해요.kubectl apply -f cilium-bgp-advertisement-ingress.yaml- Cilium LB IPAM에서 할당한 IP 주소를 사용해 서비스에 접근해요.
curl -s http://LB_IP_ADDRESS:80/details/1 | jq{ "id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890" }
Service type NodePort
환경에 로드 밸런서 인프라와 해당 Ingress 컨트롤러가 없거나, 로드 밸런서 인프라를 자체 관리하거나 DNS 기반 로드 밸런싱을 사용한다면 Cilium Ingress를 구성해 Ingress 리소스에 대해 Service of type NodePort를 만들 수 있어요. Cilium Ingress와 함께 NodePort를 사용할 때 Service of type NodePort는 30000~32767 포트 범위의 각 노드 포트에 노출돼요. 이 모드에서 트래픽이 클러스터의 모든 노드의 NodePort에 도달하면, 같은 노드나 다른 노드에 있을 수 있는 서비스를 백하는 Pod로 전달돼요.
참고
NodePort 서비스에 대한 Cilium Gateway 지원은 Cilium 버전 1.18.x에서 계획됨 (#27273)
사전 요구 사항
- Cilium Ingress 설치하기의 지침에 따라 Cilium Ingress가 설치되어 있어야 해요.
- Cilium Ingress 배포하기의 지침에 따라 샘플 애플리케이션이 배포된 Cilium Ingress 리소스가 있어야 해요.
절차
- 기존 Ingress 리소스
my-ingress를 Service 유형 LoadBalancer에서 NodePort로 변경하도록 패치해요.
Ingress 리소스를 만들지 않았다면 다음 Ingress 정의를 클러스터에 적용해 만들 수 있어요. 아래 Ingress 정의는 Cilium Ingress 배포하기에서 설명하는 Istio Bookinfo 샘플 애플리케이션을 사용해요.kubectl patch ingress my-ingress --type=merge -p '{ "metadata": {"annotations": {"ingress.cilium.io/service-type": "NodePort"}} }'apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: default annotations: service.beta.kubernetes.io/aws-load-balancer-type: "external" "ingress.cilium.io/service-type": "NodePort" spec: ingressClassName: cilium rules: - http: paths: - backend: service: name: details port: number: 9080 path: /details pathType: Prefix - Ingress 리소스의 Service가 Service 유형 NodePort를 사용하도록 업데이트되었는지 확인해요. 출력에서 HTTP 프로토콜의 포트를 확인해요. 아래 예시에서 이 HTTP 포트는
32353이며, 후속 단계에서 Service를 쿼리하는 데 사용돼요. Service of type NodePort와 함께 Cilium Ingress를 사용하면 Ingress 없이는 표준 Service of type NodePort로는 할 수 없는 경로 및 호스트 기반 라우팅과 Ingress 트래픽에 대한 네트워크 정책을 적용할 수 있다는 이점이 있어요.kubectl -n default get svc cilium-ingress-my-ingressNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress-my-ingress NodePort 172.16.47.153 80:32353/TCP,443:30253/TCP 27m - 클러스터의 노드 IP 주소를 가져와요.
kubectl get nodes -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME mi-026d6a261e355fba7 Ready 23h v1.32.3-eks-473151a 10.80.146.150 Ubuntu 22.04.5 LTS 5.15.0-142-generic containerd://1.7.27 mi-082f73826a163626e Ready 23h v1.32.3-eks-473151a 10.80.146.32 Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-09183e8a3d755abf6 Ready 23h v1.32.3-eks-473151a 10.80.146.33 Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0d78d815980ed202d Ready 23h v1.32.3-eks-473151a 10.80.146.97 Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0daa253999fe92daa Ready 23h v1.32.3-eks-473151a 10.80.146.100 Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 - 노드의 IP 주소와 위에서 수집한 NodePort를 사용해 Service of type NodePort에 접근해요. 아래 예시에서 사용된 노드 IP 주소는
10.80.146.32, NodePort는32353이에요. 이를 환경의 값으로 바꾸세요.curl -s http://10.80.146.32:32353/details/1 | jq{ "id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890" }
호스트 네트워크 (Host network)
Service of type NodePort와 유사하게, 로드 밸런서 인프라와 Ingress 또는 Gateway 컨트롤러가 없거나 외부 로드 밸런서로 로드 밸런싱을 자체 관리한다면 Cilium Ingress와 Cilium Gateway를 구성해 Ingress 및 Gateway 리소스를 호스트 네트워크에서 직접 노출할 수 있어요. Ingress 또는 Gateway 리소스에 대해 호스트 네트워크 모드가 활성화되면 Service of type LoadBalancer 및 NodePort 모드가 자동으로 비활성화되며, 호스트 네트워크 모드는 각 Ingress 또는 Gateway 리소스에 대해 이 대체 모드들과 상호 배타적이에요. Service of type NodePort 모드와 비교해 호스트 네트워크 모드는 사용할 수 있는 포트 범위에 추가 유연성을 제공하고(30000~32767 NodePort 범위로 제한되지 않음), Envoy 프록시가 호스트 네트워크에서 실행되는 노드의 하위 집합을 구성할 수 있어요.
사전 요구 사항
- Cilium Ingress 설치하기 또는 Cilium Gateway 설치하기의 지침에 따라 Cilium Ingress 또는 Gateway가 설치되어 있어야 해요.
절차 — Gateway
- 다음 내용으로
cilium-gateway-host-network.yaml이라는 파일을 만들어요.gatewayAPI: enabled: true hostNetwork: enabled: true # uncomment to restrict nodes where Envoy proxies run on the host network # nodes: # matchLabels: # role: gateway - 호스트 네트워크 Cilium Gateway 구성을 클러스터에 적용해요.
helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \ --namespace kube-system \ --reuse-values \ --set operator.rollOutPods=true \ -f cilium-gateway-host-network.yaml - Gateway 리소스를 만들지 않았다면 다음 Gateway 정의를 클러스터에 적용해 만들 수 있어요. 아래 Gateway 정의는 Cilium Gateway 배포하기에서 설명하는 Istio Bookinfo 샘플 애플리케이션을 사용해요. 아래 예시에서 Gateway 리소스는 HTTP 리스너에
8111포트를 사용하도록 구성돼요. 이는 호스트 네트워크에서 실행되는 Envoy 프록시의 공유 리스너 포트예요. Gateway 리소스에 특권 포트(1023보다 낮은 포트)를 사용한다면 지침에 대해 Cilium 문서를 참고하세요.--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway spec: gatewayClassName: cilium listeners: - protocol: HTTP port: 8111 name: web-gw allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http-app-1 spec: parentRefs: - name: my-gateway namespace: default rules: - matches: - path: type: PathPrefix value: /details backendRefs: - name: details port: 9080 - 적용된 Cilium Envoy 구성을 다음 명령으로 관찰할 수 있어요.
kubectl get cec cilium-gateway-my-gateway -o yaml - 다음 명령으로
cilium-gateway-my-gatewayService의 Envoy 리스너 포트를 가져올 수 있어요. 이 예시에서 공유 리스너 포트는8111이에요.kubectl get cec cilium-gateway-my-gateway -o jsonpath={.spec.services[0].ports[0]} - 클러스터의 노드 IP 주소를 가져와요.
kubectl get nodes -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME mi-026d6a261e355fba7 Ready 23h v1.32.3-eks-473151a 10.80.146.150 Ubuntu 22.04.5 LTS 5.15.0-142-generic containerd://1.7.27 mi-082f73826a163626e Ready 23h v1.32.3-eks-473151a 10.80.146.32 Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 ... - 노드의 IP 주소와
cilium-gateway-my-gateway리소스의 리스너 포트를 사용해 Service에 접근해요. 아래 예시에서 사용된 노드 IP 주소는10.80.146.32, 리스너 포트는8111이에요. 이를 환경의 값으로 바꾸세요.curl -s http://10.80.146.32:8111/details/1 | jq{ "id": 1, "author": "William Shakespeare", ... }
절차 — Ingress
업스트림 Cilium 이슈(#34028) 때문에 호스트 네트워크 모드의 Cilium Ingress는 loadbalancerMode: shared를 사용해야 하며, 이는 클러스터의 모든 Ingress 리소스에 대해 단일 Service of type ClusterIP를 만들어요. Ingress 리소스에 특권 포트(1023보다 낮은 포트)를 사용한다면 지침에 대해 Cilium 문서를 참고하세요.
- 다음 내용으로
cilium-ingress-host-network.yaml이라는 파일을 만들어요.ingressController: enabled: true loadbalancerMode: shared # This is a workaround for the upstream Cilium issue service: externalTrafficPolicy: null type: ClusterIP hostNetwork: enabled: true # ensure the port does not conflict with other services on the node sharedListenerPort: 8111 # uncomment to restrict nodes where Envoy proxies run on the host network # nodes: # matchLabels: # role: ingress - 호스트 네트워크 Cilium Ingress 구성을 클러스터에 적용해요.
helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \ --namespace kube-system \ --reuse-values \ --set operator.rollOutPods=true \ -f cilium-ingress-host-network.yaml - Ingress 리소스를 만들지 않았다면 다음 Ingress 정의를 클러스터에 적용해 만들 수 있어요. 아래 Ingress 정의는 Cilium Ingress 배포하기에서 설명하는 Istio Bookinfo 샘플 애플리케이션을 사용해요.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress namespace: default spec: ingressClassName: cilium rules: - http: paths: - backend: service: name: details port: number: 9080 path: /details pathType: Prefix - 적용된 Cilium Envoy 구성을 다음 명령으로 관찰할 수 있어요.
kubectl get cec -n kube-system cilium-ingress -o yaml - 다음 명령으로
cilium-ingressService의 Envoy 리스너 포트를 가져올 수 있어요. 이 예시에서 공유 리스너 포트는8111이에요.kubectl get cec -n kube-system cilium-ingress -o jsonpath={.spec.services[0].ports[0]} - 클러스터의 노드 IP 주소를 가져와요.
kubectl get nodes -o wide - 노드의 IP 주소와
cilium-ingress리소스의sharedListenerPort를 사용해 Service에 접근해요. 아래 예시에서 사용된 노드 IP 주소는10.80.146.32, 리스너 포트는8111이에요. 이를 환경의 값으로 바꾸세요.curl -s http://10.80.146.32:8111/details/1 | jq{ "id": 1, "author": "William Shakespeare", ... }