我該如何在 Amazon EKS 中使用拓撲感知提示?
我想在 Amazon Elastic Kubernetes Service (Amazon EKS) 叢集中使用拓樸感知提示 (TAH)。
解決方法
**注意:**對於已開啟 Amazon Elastic Compute Cloud (Amazon EC2) Spot 執行個體、Horizontal Pod Autoscaling 或自動擴展的叢集,TAH 可能不適用。當您使用這些叢集組態時,您無法達到與 Amazon EKS 分配給節點的 CPU 核心成比例的配置。您會超過允許的額外負荷閾值。此外,如果存在禁止重新分配端點的 Pod 指派限制,則 kube-proxy 不會使用 TAH。
在您的叢集中設定 TAH
必要條件:
- 請確保您的 Amazon EKS 叢集版本為 1.24 或更新版本。
- 設定一個具有三個節點的 Amazon EKS 叢集和受管節點群組。每個節點都必須具有相同的 CPU 容量,而且您必須將節點分散到三個可用區域。
若要在 Amazon EKS 中使用 TAH,請完成以下步驟:
-
建立新的命名空間:
apiVersion: v1 kind: Namespace metadata: name: "example-namespace" labels: pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/warn: restricted**注意:**將 example-namespace 替換為您的命名空間名稱。
-
若要建立範例部署,請使用 BusyBox 映像:
apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment-name namespace: example-namespace spec: replicas: 3 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: dnsPolicy: Default enableServiceLinks: false automountServiceAccountToken: false securityContext: seccompProfile: type: RuntimeDefault runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 containers: - name: busybox image: public.ecr.aws/docker/library/busybox:latest command: ["/bin/sh"] args: - "-c" - | echo "<html><body><h1>PodName: $MY_POD_NAME NodeName: $MY_NODE_NAME podIP:$MY_POD_IP</h1></body></html>" > /tmp/index.html; while true; do printf 'HTTP/1.1 200 OK\n\n%s\n' $(cat /tmp/index.html) | nc -l -p 8080 done ports: - containerPort: 8080 env: - name: MY_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name resources: limits: memory: "128Mi" cpu: "500m" requests: memory: "64Mi" cpu: "250m" securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {}**注意:**將 example-deployment-name 替換為您的部署名稱,並將 example-namespace 替換為您的命名空間名稱。
-
將部署公開為 ClusterIP 服務類型,然後新增 service.kubernetes.io/topology-mode: auto 作為註解:
apiVersion: v1 kind: Service metadata: name: example-service-name namespace: example-namespace annotations: service.kubernetes.io/topology-mode: auto spec: selector: app: demo ports: - protocol: TCP port: 80 targetPort: 8080**注意:**將 example-service-name 替換為您的服務名稱,並將 example-namespace 替換為您的命名空間名稱。對於 1.26 或更早版本,請改用 service.kubernetes.io/topology-aware-hints: auto 註解。
-
若要檢查端點中是否填入 TAH,請執行以下命令:
kubectl get 'endpointslices.discovery.k8s.io' -l kubernetes.io/service-name=example-service-name -n example-namespace -o yaml**注意:**將 example-namespace 替換為您的命名空間名稱,並將 example-service-name 替換為您的服務名稱。
範例輸出:endpoints: - addresses: - 10.0.21.125 conditions: ready: true serving: true terminating: false hints: forZones: - name: eu-west-1b nodeName: ip-10-0-17-215.eu-west-1.compute.internal targetRef: kind: Pod name: example-deployment-name-5875bbbb7c-m2j8t namespace: example-namespace uid: 4e789648-965e-4caa-91db-bd27d240ea59 zone: eu-west-1b -
若要檢查流量是否路由至同一個可用區域中的 Pod,請執行以下命令來部署測試 Pod:
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot --overrides='{"spec": { "nodeSelector": {"kubernetes.io/hostname":"example-node-name"}}}'**注意:**將 example-node-name 替換為您的節點名稱。
-
執行以下命令以尋找您的測試 Pod 連線到的 Pod 和節點:
curl example-service-name.example-namespace:80**注意:**將 example-namespace 替換為您的命名空間名稱,並將 example-service-name 替換為您的服務名稱。
範例輸出:PodName: 7b7b9bf455-c27z9 HTTP/1.1 200 OK NodeName: ip-10-0-9-45.eu-west-1.compute.internal HTTP/1.1 200 OK podIP: example-10.0.11.140 -
使用前述輸出中的 PodName 和 NodeName,檢查流量是否與您部署測試 Pod 的同一個可用區域一致。
-
將部署擴展至四個複本,然後執行以下命令來檢查 EndpointSlices:
kubectl -n example-namespace scale deployments example-deployment-name --replicas=4**注意:**將 example-namespace 替換為您的命名空間名稱,並將 example-deployment-name 替換為您的部署名稱。
您擴展至四個複本的部署,會導致至少有一個可用區域具有 50% 的端點比率。此外,您會超過 20% 的額外負荷閾值,而且 kube-proxy 不會使用 TAH。
疑難排解您叢集中的 TAH 問題
當您在 Amazon EKS 中使用 TAH 時,您可能會看到以下錯誤:
「Skipping topology aware endpoint filtering since node is missing label」
若您的節點缺少標籤,或您使用了自訂網域名稱但未識別節點 IP 位址,您就可能會遇到這個問題。
若要解決此問題,請完成以下步驟:
-
若要驗證節點上是否存在標籤,請執行以下命令:
kubectl get nodes --show-labels |grep "topology.kubernetes.io/zone" -
如果 Amazon EKS 已為節點加上標籤,請檢查 kube-proxy 日誌,以確認 Amazon EKS 已正確識別節點 IP 位址:
kubectl logs -n kube-system kube-proxy-pod-name | grep -i retrieved**注意:**將 kube-proxy-pod-name 替換為您的 kube-proxy Pod 名稱。
如果您使用自訂網域名稱,則 Amazon EKS 可能無法正確識別您的節點 IP 位址,而您會收到以下錯誤:
「I1215 12:24:22.082120 1 server_others.go:138] "Detected node IP" address="127.0.0.1"」
--hostname-override 必須等於 EC2 DescribeInstances 呼叫所傳回的 PrivateDnsName。
若要修改虛擬私有雲端 (VPC) DNS 和動態主機組態協定 (DHCP) 選項,請使用自訂網域。以下範例使用修改後的主機名稱:
kubectl edit ds -n kube-system kube-proxy spec: template: spec: containers: - name: kube-proxy command: - kube-proxy - --hostname-override=$(NODE_NAME) - --v=6 - --config=/var/lib/kube-proxy-config/config env: - name: NODE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName
如需更多資訊,請參閱 GitHub 網站上的 bootstrap.sh。
相關資訊
Kubernetes 網站上的拓撲感知路由
- 語言
- 中文 (繁體)

相關內容
已提問 3 年前
已提問 2 年前
已提問 3 年前