スキップしてコンテンツを表示

Amazon EKS で Topology Aware Hints を使用する方法を教えてください。

所要時間3分
0

Amazon Elastic Kubernetes Service (Amazon EKS) クラスターで、Topology Aware Hints (TAH) を使用したいです。

解決策

注: TAH は Amazon Elastic Compute Cloud (Amazon EC2) スポットインスタンス、Horizontal Pod Autoscaling、または Auto Scaling が有効になっているクラスターには適していない場合があります。これらのクラスター設定を使用する場合、Amazon EKS がノードに割り当てる CPU コア数に比例した割り当てを行うことはできません。許容されるオーバーヘッドのしきい値を超過します。また、エンドポイントの再分散を禁止するポッド割り当ての制約がある場合、kube-proxy は TAH を使用しません。

クラスターに TAH をセットアップする

前提条件:

  • Amazon EKS クラスターのバージョンが 1.24 以降であることを確認してください。
  • Amazon EKS クラスターおよび、3 つのノードを持つマネージドノードグループを設定します。各ノードの CPU 容量が同じであり、3 つのアベイラビリティーゾーンにノードを分散する必要があります。

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. トラフィックが同じアベイラビリティーゾーンのポッドにルーティングされているかどうかを確認するには、次のコマンドを実行してテストポッドをデプロイします。

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

    注: example-node-name は、実際のノード名に置き換えてください。

  6. 次のコマンドを実行して、テストポッドの接続先のポッドとノードを見つけます。

    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 を使用して、トラフィックがテストポッドをデプロイしたのと同じアベイラビリティーゾーンかどうかを確認します。

  8. デプロイを 4 つのレプリカにスケールし、次のコマンドを実行して EndpointSlices を検査します。

    kubectl -n example-namespace scale deployments example-deployment-name --replicas=4

    注: example-namespace を実際の名前空間名に、example-deployment-name をデプロイ名に置き換えてください。

デプロイを 4 つのレプリカにスケーリングすると、1 つ以上のアベイラビリティーゾーンで、エンドポイントの比率が 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 ポッド名に置き換えてください。

カスタムドメイン名を使用すると、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 と Dynamic Host Configuration Protocol (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」を参照してください。

関連情報

Topology Aware Routing (Kubernetes のウェブサイト)

Exploring the effect of Topology Aware Hints on network traffic in Amazon Elastic Kubernetes Service (Amazon Elastic Kubernetes Service のネットワークトラフィックにおける Topology Aware Hints の効果について)

AWS公式更新しました 5ヶ月前
コメントはありません

関連するコンテンツ