協助改進此頁面
若要為本使用者指南貢獻內容,請點選每個頁面右側面板中的在 GitHub 上編輯此頁面連結。
為混合節點設定 LoadBalancer 類型的服務
本主題會說明如何為在 Amazon EKS 混合節點上執行的應用程式設定第 4 層 (L4) 負載平衡。LoadBalancer 類型的 Kubernetes Service 可用於向叢集外部公開 Kubernetes 應用程式。LoadBalancer 類型的服務通常可與雲端或內部部署環境中的實體負載平衡器基礎結構搭配使用,進而提供工作負載的流量。此負載平衡器基礎結構通常使用環境特定的控制器進行佈建。
AWS 支援針對 EKS 混合節點上執行的 LoadBalancer 類型的服務使用 AWS Network Load Balancer (NLB) 和 Cilium。使用 NLB 還是 Cilium 的決定取決於應用程式流量的來源。如果應用程式流量來自 AWS 區域,則 AWS 會建議使用 AWS NLB 和 AWS Load Balancer 控制器。如果應用程式流量來自本機內部部署或邊緣環境,則 AWS 會建議使用 Cilium 的內建負載平衡功能,而該功能可在您的環境中搭配或不搭配負載平衡器基礎結構使用。
如需第 7 層 (L7) 應用程式流量負載平衡,請參閱 設定混合節點的 Kubernetes Ingress。如需使用 EKS 進行負載平衡的一般資訊,請參閱負載平衡的最佳實務。
AWS Network Load Balancer
對於在混合節點上執行的工作負載,您可以搭配目標類型 ip 使用 AWS Load Balancer 控制器和 NLB。使用目標類型 ip 時,NLB 可繞過服務層網路路徑,將流量直接轉送至 Pod。若要讓 NLB 達到混合節點上的 Pod IP 目標,您的內部部署 Pod CIDR 必須在內部部署網路上可路由。此外,AWS Load Balancer 控制器使用 Webhook 並且需要從 EKS 控制平面直接通訊。如需詳細資訊,請參閱 設定混合節點的 Webhook。
-
如需有關 AWS Network Load Balancer 和 AWS Load Balancer 控制器的其他資訊,請參閱 透過 Network Load Balancer 路由 TCP 與 UDP 流量 以取得子網路組態需求,並參閱 使用 Helm 安裝 AWS Load Balancer 控制器 和負載平衡的最佳實務。
-
請參閱 AWS Load Balancer 控制器 NLB 組態
,了解可套用至具有 AWS Network Load Balancer 的 LoadBalancer類型的服務的組態。
先決條件
-
遵循 設定混合節點的 CNI 中的指示安裝 Cilium。
-
遵循 設定混合節點的 Cilium BGP 中的指示啟用 Cilium BGP 控制平面。如果您不想使用 BGP,則必須使用替代方法,以讓內部部署 Pod CIDR 在內部部署網路上可路由,如需詳細資訊,請參閱 可路由的遠端 Pod CIDR。
-
已在命令列環境中安裝 Helm,請參閱安裝 Helm 說明。
-
已在命令列環境中安裝 eksctl,請參閱安裝 eksctl 說明。
程序
-
下載適用於 AWS Load Balancer 控制器的 IAM 政策,允許它代表您呼叫 AWS API。
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 Chart 儲存庫。AWS 會在 GitHub 上維護此儲存庫。
helm repo add eks https://aws.github.io/eks-charts -
更新您的本機 Helm 儲存庫,以確保您擁有最近的圖表。
helm repo update eks -
安裝 AWS Load Balancer 控制器。使用您的設定取代下列值:叢集名稱 (
CLUSTER_NAME)、AWS 區域 (AWS_REGION)、VPC ID (VPC_ID) 和 AWS Load Balancer 控制器 Helm Chart 版本 (AWS_LBC_HELM_VERSION)。您可以透過執行helm search repo eks/aws-load-balancer-controller --versions來尋找最新版本的 Helm Chart。如果您執行具有混合節點和 AWS 雲端中的節點的混合模式叢集,則您可以遵循 AWS Load Balancer 控制器 中的指示,在雲端節點上執行 AWS Load Balancer 控制器。helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ -n kube-system \ --versionAWS_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 -
驗證 AWS Load Balancer 控制器是否已成功安裝。
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 -
在名為
tcp-sample-app.yaml的檔案中定義範例應用程式。以下範例使用具有 TCP 連接埠的簡單的 NGINX 部署。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 -
將部署套用至叢集。
kubectl apply -f tcp-sample-app.yaml -
在名為
tcp-sample-service.yaml的檔案中定義部署的 LoadBalancer 類型服務。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 -
將服務組態套用至叢集。
kubectl apply -f tcp-sample-service.yaml -
為服務佈建 NLB 可能需要幾分鐘的時間。佈建 NLB 後,服務將會為其指派一個與 NLB 部署的 DNS 名稱對應的地址。
kubectl get svc tcp-sample-serviceNAME 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 -
使用 NLB 的地址存取服務。
curl k8s-default-tcpsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.<region>.amazonaws.com範例輸出如下。
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...] -
清除您建立的 資源。
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:管理可指派給
LoadBalancer類型的服務的 IP 位址。 -
Cilium BGP 控制平面:將 Load Balancer IPAM 配置的 IP 位址公告至內部部署網路。
如果您沒有使用 Cilium 的 kube-proxy 取代,您仍然可以使用 Cilium Load Balancer IPAM 和 BGP 控制平面,以為 LoadBalancer 類型的服務配置和指派 IP 位址。如果您沒有使用 Cilium 的 kube-proxy 取代,則根據預設,EKS 中服務至後端 Pod 的負載平衡將由 kube-proxy 和 iptables 處理。
先決條件
-
在啟用或未啟用 kube-proxy 取代的情況下,遵循 設定混合節點的 CNI 中的指示安裝 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 CIDR 在內部部署網路上可路由,如需詳細資訊,請參閱 可路由的遠端 Pod CIDR。
-
已在命令列環境中安裝 Helm,請參閱安裝 Helm 說明。
程序
-
使用
CiliumLoadBalancerIPPool資源建立名為cilium-lbip-pool-loadbalancer.yaml的檔案,以為 Load Balancer 類型的服務設定 Load Balancer IP 位址範圍。-
使用用於 Load Balancer IP 位址的 IP 位址範圍取代
LB_IP_CIDR。若要選取單一 IP 位址,請使用/32CIDR。如需詳細資訊,請參閱 Cilium 文件中的 LoadBalancer IP 位址管理。 -
serviceSelector欄位設定為與您將在後續步驟中建立的服務名稱相符。使用此組態,此集區的 IP 將僅會配置給名稱為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
-
-
將
CiliumLoadBalancerIPPool資源套用至您的叢集。kubectl apply -f cilium-lbip-pool-loadbalancer.yaml -
確認集區中至少有一個 IP 位址可用。
kubectl get ciliumloadbalancerippools.cilium.ioNAME DISABLED CONFLICTING IPS AVAILABLE AGE tcp-service-pool false False 1 24m -
使用
CiliumBGPAdvertisement資源建立名為cilium-bgp-advertisement-loadbalancer.yaml的檔案,以公告您將在下一步驟中建立的服務的負載平衡器 IP 位址。如果您不使用 Cilium BGP,則可以略過此步驟。用於服務的負載平衡器 IP 位址必須在內部部署網路上可路由,這樣您才能在最後一個步驟中查詢服務。-
advertisementType欄位設定為Service,而service.addresses則設定為LoadBalancerIP,以便僅為LoadBalancer類型的服務公告LoadBalancerIP。 -
selector欄位設定為與您將在後續步驟中建立的服務名稱相符。使用此組態時,將僅會公告名稱為tcp-sample-service的服務的LoadBalancerIP。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
-
-
將
CiliumBGPAdvertisement資源套用至您的叢集。如果您不使用 Cilium BGP,則可以略過此步驟。kubectl apply -f cilium-bgp-advertisement-loadbalancer.yaml -
在名為
tcp-sample-app.yaml的檔案中定義範例應用程式。以下範例使用具有 TCP 連接埠的簡單的 NGINX 部署。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 -
將部署套用至叢集。
kubectl apply -f tcp-sample-app.yaml -
在名為
tcp-sample-service.yaml的檔案中定義部署的 LoadBalancer 類型服務。-
您可以從負載平衡器 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
-
-
將服務套用至叢集。服務將使用外部 IP 位址建立,而您可用其來存取應用程式。
kubectl apply -f tcp-sample-service.yaml -
確認服務已成功建立,並從上一個步驟中建立的
CiliumLoadBalancerIPPool為其指派 IP。kubectl get svc tcp-sample-serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tcp-sample-service LoadBalancer 172.16.117.76LB_IP_ADDRESS80:31129/TCP 14m -
如果您以 kube-proxy 取代模式使用 Cilium,您可以執行下列命令,以確認 Cilium 正在處理服務的負載平衡。在以下輸出中,
10.86.2.x位址是服務的後端 Pod 的 Pod IP 位址。kubectl -n kube-system exec ds/cilium -- cilium-dbg service listID Frontend Service Type Backend ... 41LB_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) -
確認 Cilium 正透過 BGP 將 IP 位址公告至內部部署網路。在以下範例中,有五個混合節點,並且每個節點都會向內部部署網路公告
tcp-sample-service服務的LB_IP_ADDRESS。Node VRouter Prefix NextHop Age Attrs mi-026d6a261e355fba7NODES_ASNLB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-082f73826a163626eNODES_ASNLB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-09183e8a3d755abf6NODES_ASNLB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-0d78d815980ed202dNODES_ASNLB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] mi-0daa253999fe92daaNODES_ASNLB_IP_ADDRESS/32 0.0.0.0 12m3s [{Origin: i} {Nexthop: 0.0.0.0}] -
使用指派的 load balancerIP 位址存取服務。
curlLB_IP_ADDRESS範例輸出如下。
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...] -
清除您建立的 資源。
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