為混合節點設定 LoadBalancer 類型的服務 - Amazon EKS

協助改善此頁面

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

若要提供此使用者指南,請選擇位於每個頁面右窗格中的在 GitHub 上編輯此頁面連結。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

為混合節點設定 LoadBalancer 類型的服務

本主題說明如何為在 Amazon EKS 混合節點上執行的應用程式設定第 4 層 (L4) 負載平衡。LoadBalancer 類型的 Kubernetes 服務用於公開叢集外部的 Kubernetes 應用程式。LoadBalancer 類型的服務通常與雲端或內部部署環境中的實體負載平衡器基礎設施搭配使用,以提供工作負載的流量。此負載平衡器基礎設施通常使用環境特定的控制器進行佈建。

AWS 支援 AWS 在 EKS 混合節點上執行的 Network Load Balancer (NLB) 和 Cilium for Services 類型 LoadBalancer。使用 NLB 或 Cilium 的決定取決於應用程式流量的來源。如果應用程式流量來自 AWS 區域, AWS 建議使用 AWS NLB 和 AWS Load Balancer控制器。如果應用程式流量來自本機內部部署或邊緣環境, AWS 建議使用 Cilium 的內建負載平衡功能,這些功能可以搭配或不搭配您環境中的負載平衡器基礎設施使用。

如需第 7 層 (L7) 應用程式流量負載平衡,請參閱 設定混合節點的 Kubernetes 輸入。如需使用 EKS 進行負載平衡的一般資訊,請參閱負載平衡的最佳實務

AWS Network Load Balancer

對於在混合節點上執行ip的工作負載,您可以使用AWS Load Balancer控制器和 NLB 搭配目標類型。使用目標類型 時ip,NLB 會將流量直接轉送至 Pod,繞過服務層網路路徑。若要讓 NLB 達到混合節點上的 Pod IP 目標,您的內部部署 Pod CIDRs 必須可在內部部署網路上路由。此外, AWS Load Balancer控制器使用 Webhook,並且需要從 EKS 控制平面直接通訊。如需詳細資訊,請參閱設定混合節點的 Webhook

先決條件

程序

  1. 下載 AWS Load Balancer控制器的 IAM 政策,允許其代表您呼叫 AWS APIs。

    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)、 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
  4. 新增 eks-charts Helm Chart 儲存庫。 會在 GitHub 上 AWS 維護此儲存庫。

    helm repo add eks https://aws.github.io/eks-charts
  5. 更新本機 Helm 儲存庫,以確保您有最新的圖表。

    helm repo update eks
  6. 安裝 AWS Load Balancer控制器。將叢集名稱 (CLUSTER_NAME)、 AWS 區域 (AWS_REGION)、VPC ID (VPC_ID) 和 AWS Load Balancer控制器 Helm Chart 版本 (AWS_LBC_HELM_VERSION) 的值取代為您的設定。您可以執行 來尋找 Helm Chart 的最新版本helm search repo eks/aws-load-balancer-controller --versions。如果您在 AWS 雲端中同時執行混合模式叢集與混合節點和節點,您可以依照 中的指示,在雲端節點上執行 AWS Load Balancer控制器AWS Load Balancer控制器

    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
  7. 確認已成功安裝 AWS Load Balancer控制器。

    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
  8. 在名為 的檔案中定義範例應用程式tcp-sample-app.yaml。以下範例使用簡單的 NGINX 部署搭配 TCP 連接埠。

    apiVersion: apps/v1 kind: Deployment metadata: name: tcp-sample-app namespace: default spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - name: tcp containerPort: 80
  9. 將部署套用至您的叢集。

    kubectl apply -f tcp-sample-app.yaml
  10. 在名為 的檔案中定義部署的 LoadBalancer 類型服務tcp-sample-service.yaml

    apiVersion: v1 kind: Service metadata: name: tcp-sample-service namespace: default annotations: service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing spec: ports: - port: 80 targetPort: 80 protocol: TCP type: LoadBalancer selector: app: nginx
  11. 將服務組態套用至您的叢集。

    kubectl apply -f tcp-sample-service.yaml
  12. 為服務佈建 NLB 可能需要幾分鐘的時間。佈建 NLB 後,服務將為其指派一個與 NLB 部署的 DNS 名稱對應的地址。

    kubectl get svc tcp-sample-service
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tcp-sample-service LoadBalancer 172.16.115.212 k8s-default-tcpsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.<region>.amazonaws.com 80:30396/TCP 8s
  13. 使用 NLB 的地址存取 服務。

    curl k8s-default-tcpsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.<region>.amazonaws.com

    範例輸出如下。

    <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...]
  14. 清除您建立的 資源。

    kubectl delete -f tcp-sample-service.yaml kubectl delete -f tcp-sample-app.yaml

Cilium 叢集內負載平衡

Cilium 可以用作在 EKS 混合節點上執行的工作負載的叢集內負載平衡器,這對於沒有負載平衡器基礎設施的環境非常有用。Cilium 的負載平衡功能是建立在 Cilium 功能的組合上,包括 kube-proxy 替換、Load Balancer IP 地址管理 (IPAM) 和 BGP 控制平面。這些功能的責任詳述如下:

  • Cilium kube-proxy 取代:處理將服務流量路由到後端 Pod。

  • Cilium Load Balancer IPAM:管理可指派給類型 之 服務的 IP 地址LoadBalancer

  • Cilium BGP 控制平面:將 Load Balancer IPAM 配置的 IP 地址公告至內部部署網路。

如果您未使用 Cilium 的 kube-proxy 替換,您仍然可以使用 Cilium Load Balancer IPAM 和 BGP 控制平面為 LoadBalancer 類型的服務配置和指派 IP 地址。如果您不是使用 Cilium 的 kube-proxy 替換,則服務到後端 Pod 的負載平衡將由 kube-proxy 處理,且依預設 EKS 中的 iptables 規則。

先決條件

  • 在啟用設定混合節點的 CNI或未啟用 kube-proxy 取代的情況下,遵循 中的指示安裝的 Cilium。Cilium 的 kube-proxy 替換需要執行至少與 v4.19.57、v5.1.16 或 v5.2.0 相同的 Linux 核心作業系統。除了 Red Hat Enterprise Linux (RHEL) 8.x 以外,所有支援搭配混合節點使用的最新版作業系統都符合此條件。

  • 按照 中的指示啟用 Cilium BGP 控制平面為混合節點設定 Cilium BGP。如果您不想使用 BGP,則必須使用替代方法來讓內部部署 Pod CIDRs 可在內部部署網路上路由,可路由遠端 Pod CIDRs如需詳細資訊,請參閱 。

  • 安裝在命令列環境中的 Helm,請參閱設定 Helm 指示

程序

  1. 使用 CiliumLoadBalancerIPPool 資源建立名為 cilium-lbip-pool-loadbalancer.yaml 的檔案,以設定 Load Balancer 類型的服務之 Load Balancer IP 地址範圍。 LoadBalancer

    • LB_IP_CIDR 將 取代為用於Load Balancer IP 地址的 IP 地址範圍。若要選取單一 IP 地址,請使用 /32 CIDR。如需詳細資訊,請參閱 Cilium 文件中的 LoadBalancer IP 地址管理

    • serviceSelector 欄位設定為與您將在後續步驟中建立的 服務名稱相符。透過此組態,此集區的 IPs只會配置給名稱為 的服務tcp-sample-service

      apiVersion: cilium.io/v2alpha1 kind: CiliumLoadBalancerIPPool metadata: name: tcp-service-pool spec: blocks: - cidr: "LB_IP_CIDR" serviceSelector: matchLabels: io.kubernetes.service.name: tcp-sample-service
  2. CiliumLoadBalancerIPPool 資源套用至您的叢集。

    kubectl apply -f cilium-lbip-pool-loadbalancer.yaml
  3. 確認集區中至少有一個可用的 IP 地址。

    kubectl get ciliumloadbalancerippools.cilium.io
    NAME DISABLED CONFLICTING IPS AVAILABLE AGE tcp-service-pool false False 1 24m
  4. 使用 CiliumBGPAdvertisement 資源建立名為 cilium-bgp-advertisement-loadbalancer.yaml 的檔案,以公告您將在下一個步驟中建立之服務的負載平衡器 IP 地址。如果您不是使用 Cilium BGP,則可以略過此步驟。用於服務的負載平衡器 IP 地址必須可在內部部署網路上路由,您才能在最後一個步驟中查詢服務。

    • advertisementType 欄位設定為 Service,而service.addresses設定為 LoadBalancerIP只會針對類型LoadBalancerIP為 的 服務公告 LoadBalancer

    • selector 欄位設定為與您將在後續步驟中建立的 服務名稱相符。使用此組態,只會LoadBalancerIP針對具有 名稱的服務tcp-sample-service公告。

      apiVersion: cilium.io/v2alpha1 kind: CiliumBGPAdvertisement metadata: name: bgp-advertisement-tcp-service labels: advertise: bgp spec: advertisements: - advertisementType: "Service" service: addresses: - LoadBalancerIP selector: matchLabels: io.kubernetes.service.name: tcp-sample-service
  5. CiliumBGPAdvertisement 資源套用至您的叢集。如果您不是使用 Cilium BGP,則可以略過此步驟。

    kubectl apply -f cilium-bgp-advertisement-loadbalancer.yaml
  6. 在名為 的檔案中定義範例應用程式tcp-sample-app.yaml。以下範例使用簡單的 NGINX 部署搭配 TCP 連接埠。

    apiVersion: apps/v1 kind: Deployment metadata: name: tcp-sample-app namespace: default spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - name: tcp containerPort: 80
  7. 將部署套用至您的叢集。

    kubectl apply -f tcp-sample-app.yaml
  8. 在名為 的檔案中定義部署的 LoadBalancer 類型服務tcp-sample-service.yaml

    • 您可以從負載平衡器 IP 集區請求特定 IP 地址,並在服務物件上加上 lbipam.cilium.io/ips註釋。如果您不想請求服務的特定 IP 地址,您可以移除此註釋。

    • 需要 loadBalancerClass規格欄位,以防止舊版 AWS 雲端提供者為服務建立 Classic Load Balancer。在下面的範例中,這會設定為io.cilium/bgp-control-plane使用 Cilium 的 BGP 控制平面作為負載平衡器類別。或者,此欄位可設定為io.cilium/l2-announcer使用 Cilium 的 L2 公告功能 (目前為 Beta 版,且不受 正式支援 AWS)。

      apiVersion: v1 kind: Service metadata: name: tcp-sample-service namespace: default annotations: lbipam.cilium.io/ips: "LB_IP_ADDRESS" spec: loadBalancerClass: io.cilium/bgp-control-plane ports: - port: 80 targetPort: 80 protocol: TCP type: LoadBalancer selector: app: nginx
  9. 將 服務套用至您的叢集。服務將使用外部 IP 地址建立,您可以用來存取應用程式。

    kubectl apply -f tcp-sample-service.yaml
  10. 確認服務已成功建立,並從上一個步驟中CiliumLoadBalancerIPPool建立的 為其指派 IP。

    kubectl get svc tcp-sample-service
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tcp-sample-service LoadBalancer 172.16.117.76 LB_IP_ADDRESS 80:31129/TCP 14m
  11. 如果您在 kube-proxy 取代模式中使用 Cilium,您可以執行下列命令,確認 Cilium 正在處理服務的負載平衡。在下面的輸出中,10.86.2.x地址是服務的後端 Pod 的 Pod IP 地址。

    kubectl -n kube-system exec ds/cilium -- cilium-dbg service list
    ID Frontend Service Type Backend ... 41 LB_IP_ADDRESS:80/TCP LoadBalancer 1 => 10.86.2.76:80/TCP (active) 2 => 10.86.2.130:80/TCP (active) 3 => 10.86.2.141:80/TCP (active)
  12. 確認 Cilium 正在透過 BGP 將 IP 地址公告至內部部署網路。在下面的範例中,有五個混合節點,每個節點都會將LB_IP_ADDRESStcp-sample-service服務的 公告至內部部署網路。

    Node VRouter Prefix NextHop Age Attrs mi-026d6a261e355fba7 NODES_ASN LB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-082f73826a163626e NODES_ASN LB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-09183e8a3d755abf6 NODES_ASN LB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-0d78d815980ed202d NODES_ASN LB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-0daa253999fe92daa NODES_ASN LB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}]
  13. 使用指派的負載balancerIP 地址存取服務。

    curl LB_IP_ADDRESS

    範例輸出如下。

    <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...]
  14. 清除您建立的 資源。

    kubectl delete -f tcp-sample-service.yaml kubectl delete -f tcp-sample-app.yaml kubectl delete -f cilium-lb-ip-pool.yaml kubectl delete -f cilium-bgp-advertisement.yaml