为混合节点配置 Kubernetes 入口 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

帮助改进此页面

要帮助改进本用户指南,请选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。

为混合节点配置 Kubernetes 入口

本主题介绍如何为在 Amazon EKS 混合节点上运行的工作负载配置 Kubernetes 入口。Kubernetes 入口向集群内的服务公开来自集群外部的 HTTP 和 HTTPS 路由。要使用入口资源,需要使用 Kubernetes 入口控制器来设置联网基础设施以及为网络流量提供服务的组件。

Amazon 支持 Amazon 应用程序负载均衡器(ALB)和适用于 Kubernetes 入口的 Cilium,可用于在 EKS 混合节点上运行的工作负载。使用 ALB 还是适用于入口的 Cilium,取决于应用程序流量的来源。如果应用程序流量来自某个 Amazon 区域,Amazon 建议使用 Amazon ALB 和 Amazon 负载均衡器控制器。如果应用程序流量来自本地或边缘环境,Amazon 建议使用 Cilium 的内置入口功能,无论是否在环境中使用负载均衡器基础设施,均可使用该功能。

EKS 混合节点入口

Amazon 应用程序负载均衡器

您可以将 Amazon 负载均衡器控制器和目标类型为 ip 的应用程序负载均衡器(ALB)用于在混合节点上运行的工作负载。使用目标类型 ip 时,ALB 会绕过服务层网络路径,直接将流量转发到容器组(pod)。为了让 ALB 到达混合节点上的容器组(pod)IP 目标,本地容器组(pod)CIDR 必须可在本地网络中路由。此外,Amazon 负载均衡器控制器使用 Webhook,需要来自 EKS 控制面板的直接通信。有关更多信息,请参阅 为混合节点配置 Webhook

注意事项

先决条件

  • 按照为混合节点配置 CNI中的说明安装 Cilium。

  • 按照为混合节点配置 Cilium BGP 中的说明启用 Cilium BGP 控制面板。如果您不想使用 BGP,则必须使用其他方法,使本地容器组(pod)CIDR 可在本地网络中路由。如果您不将本地容器组(pod)CIDR 设置为可路由,ALB 将无法注册或联系您的容器组(pod)IP 目标。

  • 在命令行环境中安装 Helm,有关更多信息,请参阅安装 Helm 说明

  • 在命令行环境中安装 eksctl,有关更多信息,请参阅 eksctl 安装说明

过程

  1. 下载Amazon负载均衡器控制器的 IAM 策略,该策略允许负载均衡器代表您调用 Amazon API。

    curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json
  2. 使用上一步中下载的策略创建一个 IAM 策略。

    aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam_policy.json
  3. 将集群名称 (CLUSTER_NAME)、Amazon 区域 (AWS_REGION) 和 Amazon 账户 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
  4. 添加 eks-charts Helm 图表存储库并更新您的本地 Helm 存储库,确保您拥有最新的图表。

    helm repo add eks https://aws.github.io/eks-charts
    helm repo update eks
  5. 安装Amazon负载均衡器控制器。将集群名称 (CLUSTER_NAME)、Amazon 区域 (AWS_REGION)、VPC ID (VPC_ID) 和 Amazon 负载均衡器控制器 Helm 图表版本 (AWS_LBC_HELM_VERSION) 的值替换为您的设置,并运行下列命令。如果您运行的混合模式集群同时包含混合节点和 Amazon 云中的节点,则可以按照Amazon Load Balancer Controller 中的说明,在云端节点上运行 Amazon 负载均衡器控制器。

    • 您可以通过运行 helm search repo eks/aws-load-balancer-controller --versions 找到最新版本的 Helm 图表。

      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-controller
  6. 验证 Amazon 负载均衡器控制器是否成功安装。

    kubectl get -n kube-system deployment aws-load-balancer-controller
    NAME READY UP-TO-DATE AVAILABLE AGE aws-load-balancer-controller 2/2 2 2 84s
  7. 创建示例应用程序。以下示例使用 Istio Bookinfo 示例微服务应用程序。

    kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
  8. 使用以下内容创建名为 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
  9. 将入口配置应用于集群。

    kubectl apply -f my-ingress-alb.yaml
  10. 为您的入口资源预置 ALB 可能需要几分钟时间。预置 NLB 后,将为您的入口资源分配一个与 ALB 部署的 DNS 名称相对应的地址。该地址将采用以下格式:<alb-name>-<random-string>.<region>.elb.amazonaws.com

    kubectl get ingress my-ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress alb * my-ingress-alb-<random-string>.<region>.elb.amazonaws.com 80 23m
  11. 使用 ALB 的地址访问服务。

    curl -s http//my-ingress-alb-<random-string>.<region>.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 入口和 Cilium 网关概述

Cilium 的入口功能内置在 Cilium 的架构中,可以使用 Kubernetes 入口 API 或网关 API 进行管理。如果您没有现有的入口资源,Amazon 建议您从网关 API 开始,因为它是定义和管理 Kubernetes 联网资源的一种更具表现力和灵活性的方式。Kubernetes 网关 API 旨在标准化在 Kubernetes 集群中定义和管理入口、负载均衡和服务网格的联网资源的方式。

启用 Cilium 的入口或网关功能时,Cilium 管理器会协调集群中的入口/网关对象,每个节点上的 Envoy 代理负责处理第 7 层(L7)网络流量。Cilium 不直接预置入口/网关基础设施,例如负载均衡器。如果您计划将 Cilium 入口/网关与负载均衡器一起使用,则必须使用负载均衡器的工具(通常是入口或网关控制器)来部署和管理负载均衡器的基础设施。

对于入口/网关流量,Cilium 会处理核心网络流量和 L3/L4 策略执行,集成的 Envoy 代理负责处理第 7 层网络流量。借助 Cilium 入口/网关,Envoy 负责应用 L7 路由规则、策略和请求操作、高级流量管理(例如流量拆分和镜像)以及 TLS 终止和发起。默认情况下,Cilium 的 Envoy 代理作为单独的 DaemonSet (cilium-envoy) 部署,这使得可以单独对 Envoy 和 Cilium 代理进行更新、扩展和管理。

有关 Cilium 入口和 Cilium 网关如何工作的更多信息,请参阅 Cilium 文档中的 Cilium IngressCilium Gateway 页面。

Cilium 入口和网关比较

下表汇总了截至 Cilium 1.17.x 版本的 Cilium 入口和 Cilium 网关功能。

功能 入口 Gateway

服务类型 LoadBalancer

支持

服务类型 NodePort

1

主机网络

支持

共享负载均衡器

支持

专用负载均衡器

2

网络策略

支持

协议

第 7 层 [HTTP(S)、gRPC]

第 7 层 [HTTP(S)、gRPC]3

TLS 传递

支持

流量管理

路径和主机路由

路径和主机路由、URL 重定向和重写、流量拆分、标头修改

1 Cilium 1.18.x 版本计划提供 NodePort 服务的 Cilium 网关支持(#27273

2 针对专用负载均衡器的 Cilium 网关支持(#25567

3 针对 TCP/UDP 的 Cilium 网关支持(#21929

安装 Cilim 网关

注意事项

  • 配置 Cilium 时,必须将 nodePort.enabled 设置为 true,如下列示例所示。如果您使用的是 Cilium 的 kube-proxy 替换功能,则无需将 nodePort.enabled 设置为 true

  • 配置 Cilium 时,必须将 envoy.enabled 设置为 true,如下列示例所示。

  • Cilium 网关可以在负载均衡器(默认)或主机网络模式下部署。

  • 在负载均衡器模式下使用 Cilium 网关时,必须在网关资源上设置 service.beta.kubernetes.io/aws-load-balancer-type: "external" 注释,以防止传统 Amazon 云提供商为 Cilium 为网关资源创建的 LoadBalancer 类型服务创建经典负载均衡器。

  • 在主机网络模式下使用 Cilium 网关时,将禁用 LoadBalancer 模式类型的服务。主机网络模式对于没有负载均衡器基础设施的环境非常有用,有关更多信息,请参阅主机网络

先决条件

  1. 在命令行环境中安装 Helm,请参阅安装 Helm 说明

  2. 按照为混合节点配置 CNI中的说明安装 Cilium。

过程

  1. 安装 Kubernetes 网关 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
  2. 创建以下内容的名为 cilium-gateway-values.yaml 的文件。以下示例将 Cilium 网关配置为使用默认负载均衡器模式,并为配置为仅在混合节点上运行的 Envoy 代理使用单独的 cilium-envoy DaemonSet。

    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
  3. 将 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
  4. 确认 Cilium 管理器、代理和 Envoy 容器组(pod)正在运行。

    kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=cilium
    NAME 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

配置 Cilim 网关

通过将 gatewayClassName 设置为 cilium,可以在网关对象上启用 Cilium 网关。Cilium 为网关资源创建的服务可以使用网关对象上的字段进行配置。可以使用网关对象的 infrastructure 字段,配置网关控制器用于配置负载均衡器基础设施的常用注释。使用 Cilium 的 LoadBalancer IPAM(请参阅服务类型 LoadBalancer中的示例)时,可以在网关对象的 addresses 字段上配置用于 LoadBalancer 类型服务的 IP 地址。有关网关配置的更多信息,请参阅 Kubernetes Gateway API specification

apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway spec: gatewayClassName: cilium infrastructure: annotations: service.beta.kubernetes.io/... service.kuberentes.io/... addresses: - type: IPAddress value: <LoadBalancer IP address> listeners: ...

Cilium 和 Kubernetes 网关规范支持 GatewayClass、网关、httpRoute、grpcRoute 和 ReferenceGrant 资源。

部署 Cilium 网关

  1. 创建示例应用程序。以下示例使用 Istio Bookinfo 示例微服务应用程序。

    kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
  2. 确认应用程序在成功运行。

    kubectl get pods
    NAME 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
  3. 使用以下内容创建名为 my-gateway.yaml 的文件。以下示例使用 service.beta.kubernetes.io/aws-load-balancer-type: "external" 注释,防止传统 Amazon 云提供商为 Cilium 为网关资源创建的 LoadBalancer 类型服务创建经典负载均衡器。

    --- 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
  4. 将网关资源应用于集群。

    kubectl apply -f my-gateway.yaml
  5. 确认网关资源和相应的服务已创建。在此阶段,预计网关资源的 ADDRESS 字段中没有填充 IP 地址或主机名,网关资源的 LoadBalancer 类型服务同样没有分配 IP 地址或主机名。

    kubectl get gateway my-gateway
    NAME CLASS ADDRESS PROGRAMMED AGE my-gateway cilium True 10s
    kubectl get svc cilium-gateway-my-gateway
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-gateway-my-gateway LoadBalancer 172.16.227.247 <pending> 80:30912/TCP 24s
  6. 继续执行服务类型 LoadBalancer,将网关资源配置为使用 Cilium 负载均衡器 IPAM 分配的 IP 地址,并执行服务类型 NodePort主机网络,将网关资源配置为使用 NodePort 或主机网络地址。

安装 Cilium 入口

注意事项

  • 配置 Cilium 时,必须将 nodePort.enabled 设置为 true,如下列示例所示。如果您使用的是 Cilium 的 kube-proxy 替换功能,则无需将 nodePort.enabled 设置为 true

  • 配置 Cilium 时,必须将 envoy.enabled 设置为 true,如下列示例所示。

  • ingressController.loadbalancerMode 设置为 dedicated 后,Cilium 会为每个入口资源创建专用服务。将 ingressController.loadbalancerMode 设置为 shared 后,Cilium 会为集群中的所有入口资源创建 LoadBalancer 类型的共享服务。使用 shared 负载均衡器模式时,共享服务的设置(例如 labelsannotationstypeloadBalancerIP)在 Helm 值的 ingressController.service 部分中进行配置。有关更多信息,请参阅 Cilium Helm values reference

  • ingressController.default 设置为 true 后,Cilium 将被配置为集群的默认入口控制器并会创建入口条目(即使未在入口资源上指定 ingressClassName,也是如此)。

  • Cilium 入口可以在负载均衡器(默认)、节点端口或主机网络模式下部署。在主机网络模式下安装 Cilium 时,将禁用 LoadBalancer 类型服务和 NodePort 类型服务的模式。请参阅主机网络了解更多信息。

  • 在 Helm 值中,始终将 ingressController.service.annotations 设置为 service.beta.kubernetes.io/aws-load-balancer-type: "external",以防止传统 Amazon 云提供商为 Cilium Helm 图表创建的默认 cilium-ingress 服务创建经典负载均衡器。

先决条件

  1. 在命令行环境中安装 Helm,请参阅安装 Helm 说明

  2. 按照为混合节点配置 CNI中的说明安装 Cilium。

过程

  1. 创建以下内容的名为 cilium-ingress-values.yaml 的文件。以下示例将 Cilium 入口配置为使用默认负载均衡器 dedicated 模式,并对配置为仅在混合节点上运行的 Envoy 代理使用单独的 cilium-envoy DaemonSet。

    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
  2. 将 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
  3. 确认 Cilium 管理器、代理和 Envoy 容器组(pod)正在运行。

    kubectl -n kube-system get pods --selector=app.kubernetes.io/part-of=cilium
    NAME 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 入口

通过将 ingressClassName 设置为 cilium,可以在入口对象上启用 Cilium 入口。Cilium 为入口资源创建的服务在使用 dedicated 负载均衡器模式时可以在入口对象上使用注释进行配置,在使用 shared 负载均衡器模式时可以在 Cilium/Helm 配置中进行配置。入口控制器通常使用这些注释来配置负载均衡器基础设施或服务的其他属性,例如服务类型、负载均衡器模式、端口和 TLS 传递。下面介绍了关键注释。有关支持的注释的完整列表,请参阅 Cilium 文档中的 Cilium Ingress annotations

注释 描述

ingress.cilium.io/loadbalancer-mode

dedicated:每个入口资源的 LoadBalancer 类型的专用服务(默认)。

shared:所有入口资源的 LoadBalancer 类型的单一服务。

ingress.cilium.io/service-type

LoadBalancer:该服务将为 LoadBalancer 类型(默认)

NodePort:该服务将为 NodePort 类型。

service.beta.kubernetes.io/aws-load-balancer-type

"external":防止传统 Amazon 云提供商为 LoadBalancer 类型服务预置经典负载均衡器。

lbipam.cilium.io/ips

要从 Cilium LoadBalancer IPAM 分配的 IP 地址列表

Cilium 和 Kubernetes 入口规范支持入口路径的精确、前缀和特定于实现的匹配规则。Cilium 支持正则表达式作为其特定于实现的匹配规则。有关更多信息,请参阅 Cilium 文档中的 Ingress path types and precedencePath types examples,以及本页部署 Cilium 入口部分中的示例。

以下显示了示例 Cilium 入口对象。

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: service.beta.kuberentes.io/... service.kuberentes.io/... spec: ingressClassName: cilium rules: ...

部署 Cilium 入口

  1. 创建示例应用程序。以下示例使用 Istio Bookinfo 示例微服务应用程序。

    kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml
  2. 确认应用程序在成功运行。

    kubectl get pods
    NAME 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
  3. 使用以下内容创建名为 my-ingress.yaml 的文件。以下示例使用 service.beta.kubernetes.io/aws-load-balancer-type: "external" 注释,防止传统 Amazon 云提供商为 Cilium 为入口资源创建的 LoadBalancer 类型服务创建经典负载均衡器。

    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
  4. 将入口资源应用于集群。

    kubectl apply -f my-ingress.yaml
  5. 确认入口资源和相应的服务已创建。在此阶段,预计入口资源的 ADDRESS 字段中没有填充 IP 地址或主机名,同样,入口资源的 LoadBalancer 类型的共享或专用服务也没有分配 IP 地址或主机名。

    kubectl get ingress my-ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress cilium * 80 8s

    适用于负载均衡器模式 shared

    kubectl -n kube-system get svc cilium-ingress
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress LoadBalancer 172.16.217.48 <pending> 80:32359/TCP,443:31090/TCP 10m

    适用于负载均衡器模式 dedicated

    kubectl -n default get svc cilium-ingress-my-ingress
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress-my-ingress LoadBalancer 172.16.193.15 <pending> 80:32088/TCP,443:30332/TCP 25s
  6. 继续执行服务类型 LoadBalancer,将入口资源配置为使用 Cilium 负载均衡器 IPAM 分配的 IP 地址,并执行服务类型 NodePort主机网络,将入口资源配置为使用 NodePort 或主机网络地址。

服务类型 LoadBalancer

现有的负载均衡器基础设施

默认情况下,对于 Cilium 入口和 Cilium 网关,Cilium 会为入口/网关资源创建 LoadBalancer 类型的 Kubernetes 服务。Cilium 创建的服务的属性可以通过入口和网关资源进行配置。在创建入口或网关资源时,入口或网关的对外部公开的 IP 地址或主机名是从负载均衡器基础设施进行分配,而负载均衡器基础设施通常由入口或网关控制器预置。

许多入口和网关控制器都使用注释来检测和配置负载均衡器基础设施。这些入口和网关控制器的注释是在入口或网关资源上配置,如上面的示例所示。请参阅入口或网关控制器的文档,了解其支持的注释,并参阅 Kubernetes 入口文档Kubernetes 网关文档,获取常用控制器列表。

重要

在具有 EKS 混合节点的情况下,Cilium 入口和网关不能与 Amazon 负载均衡器控制器和 Amazon 网络负载均衡器(NLB)一起使用。尝试将它们一起使用会导致目标未注册,因为当 NLB 的 target-type 设置为 ip 时(在 EKS 混合节点上运行工作负载时使用 NLB 的要求),NLB 会尝试直接连接到支持 LoadBalancer 类型服务的容器组(pod)IP。

没有负载均衡器基础设施

如果您的环境中没有负载均衡器基础设施和相应的入口/网关控制器,则可以将入口/网关资源和相应的 LoadBalancer 类型服务配置为使用 Cilium 的 负载均衡器 IP 地址管理(LB IPAM)分配的 IP 地址。Cilium LB IPAM 可以使用本地环境中的已知 IP 地址范围进行配置,并且可以使用 Cilium 的内置边界网关协议(BGP)支持或 L2 通告向您的本地网络通告 LoadBalancer IP 地址。

以下示例说明如何使用用于入口/网关资源的 IP 地址配置 Cilium 的 LB IPAM,以及如何配置 Cilium BGP 控制面板以向本地网络通告 LoadBalancer IP 地址。默认情况下,Cilium 的 LB IPAM 功能处于启用状态,但在创建 CiliumLoadBalancerIPPool 资源后才会激活。

先决条件

过程

  1. 可选择修补入口或网关资源,以请求用于 LoadBalancer 类型服务的特定 IP 地址。如果您不请求特定 IP 地址,Cilium 将在后续步骤中从 CiliumLoadBalancerIPPool 资源中配置的 IP 地址范围分配一个 IP 地址。在下面的命令中,将 LB_IP_ADDRESS 替换为请求 LoadBalancer 类型服务的 IP 地址。

    网关

    kubectl patch gateway -n default my-gateway --type=merge -p '{ "spec": { "addresses": [{"type": "IPAddress", "value": "LB_IP_ADDRESS"}] } }'

    入口

    kubectl patch ingress my-ingress --type=merge -p '{ "metadata": {"annotations": {"lbipam.cilium.io/ips": "LB_IP_ADDRESS"}} }'
  2. 使用 CiliumLoadBalancerIPPool 资源创建一个名为 cilium-lbip-pool-ingress.yaml 的文件,用于为您的入口/网关资源配置负载均衡器 IP 地址范围。

    • 如果使用的是 Cilium 入口,Cilium 会自动将 cilium.io/ingress: "true" 标签应用于它为入口资源创建的服务。您可以在 CiliumLoadBalancerIPPool 资源定义的 serviceSelector 字段中使用此标签来选择符合 LB IPAM 条件的服务。

    • 如果您使用的是 Cilium 网关,则可以使用 CiliumLoadBalancerIPPool 资源定义 serviceSelector 字段中的 gateway.networking.k8s.io/gateway-name 标签来选择符合 LB IPAM 条件的网关资源。

    • LB_IP_CIDR 替换为用于负载均衡器 IP 地址的 IP 地址范围。要选择单个 IP 地址,请使用 /32 CIDR。有关更多信息,请参阅 Cilium 文档中的 LoadBalancer IP Address Management

      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"
  3. CiliumLoadBalancerIPPool 资源应用于集群。

    kubectl apply -f cilium-lbip-pool-ingress.yaml
  4. 确认已从 Cilium LB IPAM 为入口/网关资源分配了 IP 地址。

    网关

    kubectl get gateway my-gateway
    NAME CLASS ADDRESS PROGRAMMED AGE my-gateway cilium LB_IP_ADDRESS True 6m41s

    入口

    kubectl get ingress my-ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE my-ingress cilium * LB_IP_ADDRESS 80 10m
  5. 使用 CiliumBGPAdvertisement 资源创建一个名为 cilium-bgp-advertisement-ingress.yaml 的文件,用于通告入口/网关资源的 LoadBalancer IP 地址。如果您不使用 Cilium BGP,则可跳过此步骤。用于入口/网关资源的 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"
  6. CiliumBGPAdvertisement 资源应用于集群。

    kubectl apply -f cilium-bgp-advertisement-ingress.yaml
  7. 使用从 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" }

服务类型 NodePort

如果您的环境中没有负载均衡器基础设施和相应的入口控制器,或者您要自行管理负载均衡器基础设施或使用基于 DNS 的负载均衡,则可以将 Cilium 入口配置成为入口资源创建 NodePort 类型服务。将 NodePort 与 Cilium 入口配合使用时,NodePort 类型服务会在端口范围为 30000-32767 的每个节点的端口上公开。在此模式下,当流量到达 NodePort 上集群中的任何节点时,它会被转发到支持该服务的容器组(pod),而该容器组可能位于同一节点或不同节点上。

注意

Cilium 1.18.x 版本计划提供 NodePort 服务的 Cilium 网关支持(#27273

先决条件

过程

  1. 修补现有入口资源 my-ingress,将其从 LoadBalancer 类型服务更改为 NodePort 类型服务。

    kubectl patch ingress my-ingress --type=merge -p '{ "metadata": {"annotations": {"ingress.cilium.io/service-type": "NodePort"}} }'

    如果您尚未创建入口资源,则可以通过将以下入口定义应用于集群来创建它。请注意,下面的入口定义使用了部署 Cilium 入口中所述的 Istio Bookinfo 示例应用程序。

    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
  2. 确认入口资源的服务已更新为使用 NodePort 类型服务。记下输出中 HTTP 协议的端口。在下面的示例中,此 HTTP 端口为 32353,将在后续步骤中使用它来查询服务。将 Cilium 入口与 NodePort 类型服务配合使用的好处是,您可以为入口流量应用基于路径和主机的路由,以及网络策略,而对于没有入口的 NodePort 类型的标准服务,则无法做到这一点。

    kubectl -n default get svc cilium-ingress-my-ingress
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cilium-ingress-my-ingress NodePort 172.16.47.153 <none> 80:32353/TCP,443:30253/TCP 27m
  3. 获取集群节点的 IP 地址。

    kubectl get nodes -o wide
    NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME mi-026d6a261e355fba7 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.150 <none> Ubuntu 22.04.5 LTS 5.15.0-142-generic containerd://1.7.27 mi-082f73826a163626e Ready <none> 23h v1.32.3-eks-473151a 10.80.146.32 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-09183e8a3d755abf6 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.33 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0d78d815980ed202d Ready <none> 23h v1.32.3-eks-473151a 10.80.146.97 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0daa253999fe92daa Ready <none> 23h v1.32.3-eks-473151a 10.80.146.100 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27
  4. 使用您的节点的 IP 地址和上面捕获的 NodePort 访问 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" }

主机网络

与 NodePort 类型服务类似,如果您没有负载均衡器基础设施和入口或网关控制器,或者您要使用外部负载均衡器自行管理负载均衡,则可以将 Cilium 入口和 Cilium 网关配置为直接在主机网络上公开入口和网关资源。当为入口或网关资源启用主机网络模式时,会自动禁用 LoadBalancer 类型服务和 NodePort 类型服务的模式,主机网络模式与每个入口或网关资源的这些替代模式相互排斥。与 NodePort 类型服务模式相比,主机网络模式为可使用的端口范围提供了更大灵活性(不限于 30000-32767 NodePort 范围),您可以配置 Envoy 代理在主机网络上运行的节点子集。

先决条件

过程

Gateway

  1. 使用以下内容创建名为 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
  2. 将主机网络 Cilium 网关配置应用于集群。

    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

    如果您尚未创建网关资源,则可以通过将以下网关定义应用于集群来创建它。下面的网关定义使用了部署 Cilium 网关中所述的 Istio Bookinfo 示例应用程序。在下面的示例中,网关资源配置为使用 HTTP 侦听器的 8111 端口,该端口是在主机网络上运行的 Envoy 代理的共享侦听器端口。如果您将特权端口(低于 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-gateway 服务的 Envoy 侦听器端口。在此示例中,共享侦听器端口为 8111

    kubectl get cec cilium-gateway-my-gateway -o jsonpath={.spec.services[0].ports[0]}
  3. 获取集群节点的 IP 地址。

    kubectl get nodes -o wide
    NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME mi-026d6a261e355fba7 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.150 <none> Ubuntu 22.04.5 LTS 5.15.0-142-generic containerd://1.7.27 mi-082f73826a163626e Ready <none> 23h v1.32.3-eks-473151a 10.80.146.32 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-09183e8a3d755abf6 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.33 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0d78d815980ed202d Ready <none> 23h v1.32.3-eks-473151a 10.80.146.97 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0daa253999fe92daa Ready <none> 23h v1.32.3-eks-473151a 10.80.146.100 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27
  4. 使用节点的 IP 地址和 cilium-gateway-my-gateway 资源的侦听器端口访问服务。在下面的示例中,使用的节点 IP 地址是 10.80.146.32,侦听器端口是 8111。请将这些值替换为您环境的相应值。

    curl -s http://10.80.146.32:8111/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" }

入口

由于上游 Cilium 问题(#34028),主机网络模式下的 Cilium 入口需要使用 loadbalancerMode: shared,这会为集群中的所有入口资源创建 ClusterIP 类型的单一服务。如果您将特权端口(低于 1023)用于入口资源,请参阅 Cilium 文档获取相关说明。

  1. 使用以下内容创建名为 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
  2. 将主机网络 Cilium 入口配置应用于集群。

    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

    如果您尚未创建入口资源,则可以通过将以下入口定义应用于集群来创建它。下面的入口定义使用了部署 Cilium 入口中所述的 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-ingress 服务的 Envoy 侦听器端口。在此示例中,共享侦听器端口为 8111

    kubectl get cec -n kube-system cilium-ingress -o jsonpath={.spec.services[0].ports[0]}
  3. 获取集群节点的 IP 地址。

    kubectl get nodes -o wide
    NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME mi-026d6a261e355fba7 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.150 <none> Ubuntu 22.04.5 LTS 5.15.0-142-generic containerd://1.7.27 mi-082f73826a163626e Ready <none> 23h v1.32.3-eks-473151a 10.80.146.32 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-09183e8a3d755abf6 Ready <none> 23h v1.32.3-eks-473151a 10.80.146.33 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0d78d815980ed202d Ready <none> 23h v1.32.3-eks-473151a 10.80.146.97 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27 mi-0daa253999fe92daa Ready <none> 23h v1.32.3-eks-473151a 10.80.146.100 <none> Ubuntu 22.04.4 LTS 5.15.0-142-generic containerd://1.7.27
  4. 使用节点的 IP 地址和 cilium-ingress 资源的 sharedListenerPort 访问服务。在下面的示例中,使用的节点 IP 地址是 10.80.146.32,侦听器端口是 8111。请将这些值替换为您环境的相应值。

    curl -s http://10.80.146.32:8111/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" }