AWS re:Postを使用することにより、以下に同意したことになります AWS re:Post 利用規約

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、または自動スケーリングが有効になっているクラスターには適していない場合があります。これらのクラスター構成を使用する場合、ノードに割り当てられた CPU コアに比例した割り当てを行うことはできません。許容されるオーバーヘッドのしきい値を超過することになります。また、エンドポイントの再配布を禁止するポッド割り当ての制約がある場合、kube-proxy は TAH を使用しません。

前提条件

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

Amazon EKS で TAH を使用するには、次のステップを完了してください。

  1. 新しい名前空間を作成します。

    注: example-namespace は、お使いの名前空間の名前に置き換えてください。

    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
  2. BusyBox イメージを使用してサンプルデプロイを作成します。

    注: お使いのものでそれぞれ、example-deployment-name をデプロイ名、example-namespace を名前空間名に置き換えてください。

    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: {}
  3. デプロイを、サービスタイプ ClusterIP で公開したら、アノテーションに service.kubernetes.io/topology-mode: auto を追加します。

    注: お使いのものでそれぞれ、example-service-name をサービス名、example-namespace を名前空間名に置き換えてください。バージョン 1.27 以降では、service.kubernetes.io/topology-aware-hints: auto アノテーションは、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
  4. エンドポイントに TAH が入力されているかどうかを確認します。

    注: お使いのものでそれぞれ、example-service-name をサービス名、example-namespace を名前空間名に置き換えてください。

    kubectl get 'endpointslices.discovery.k8s.io' -l kubernetes.io/service-name=example-service-name -n example-namespace -o yaml

    出力例

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

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

    kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot --overrides='{"spec": { "nodeSelector": {"kubernetes.io/hostname":"example-node-name"}}}'
  6. テストポッドが接続するポッドとノードを特定します。

    curl example-service-name.example-namespace:80

    出力例

    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 を検査します。

    注: お使いのものでそれぞれ、example-namespace を名前空間名、example-deployment-name をデプロイ名に置き換えてください。

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

    注: デプロイを 4 つのレプリカにスケーリングすると、1 つ以上のアベイラビリティーゾーンで、エンドポイントの比率が 50% になります。また、オーバーヘッドのしきい値である 20% を超えているため、kube-proxy では TAH を使用しません。

関連情報

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

Amazon Elastic Kubernetes Service のネットワークトラフィックにおける Topology Aware Hints の効果について

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