跳至內容

我該如何在 Amazon EKS 中使用拓撲感知提示?

3 分的閱讀內容
0

我想在 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,請完成以下步驟:

  1. 建立新的命名空間:

    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 替換為您的命名空間名稱。

  2. 若要建立範例部署,請使用 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 替換為您的命名空間名稱。

  3. 將部署公開為 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 註解。

  4. 若要檢查端點中是否填入 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
  5. 若要檢查流量是否路由至同一個可用區域中的 Pod,請執行以下命令來部署測試 Pod:

    kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot --overrides='{"spec": { "nodeSelector": {"kubernetes.io/hostname":"example-node-name"}}}'

    **注意:**將 example-node-name 替換為您的節點名稱。

  6. 執行以下命令以尋找您的測試 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
  7. 使用前述輸出中的 PodNameNodeName,檢查流量是否與您部署測試 Pod 的同一個可用區域一致。

  8. 將部署擴展至四個複本,然後執行以下命令來檢查 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 位址,您就可能會遇到這個問題。

若要解決此問題,請完成以下步驟:

  1. 若要驗證節點上是否存在標籤,請執行以下命令:

    kubectl get nodes --show-labels |grep "topology.kubernetes.io/zone"
  2. 如果 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 網站上的拓撲感知路由

探索拓撲感知提示對 Amazon Elastic Kubernetes Service 中網路流量的影響

AWS 官方已更新 5 個月前