Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
Amazon EKS で Topology Aware Hints を使用する方法を教えてください。
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 を使用するには、次の手順を完了してください。
-
新しい名前空間を作成します。
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 -
トラフィックが同じアベイラビリティーゾーンのポッドにルーティングされているかどうかを確認するには、次のコマンドを実行してテストポッドをデプロイします。
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot --overrides='{"spec": { "nodeSelector": {"kubernetes.io/hostname":"example-node-name"}}}'注: example-node-name は、実際のノード名に置き換えてください。
-
次のコマンドを実行して、テストポッドの接続先のポッドとノードを見つけます。
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 を使用して、トラフィックがテストポッドをデプロイしたのと同じアベイラビリティーゾーンかどうかを確認します。
-
デプロイを 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 アドレスを特定しなかったことが原因である可能性があります。
この問題を解決するには、次の手順を実行します。
-
ラベルがノードに存在することを確認するには、次のコマンドを実行します。
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 ポッド名に置き換えてください。
カスタムドメイン名を使用すると、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 の効果について)
- トピック
- Containers
- 言語
- 日本語
