AKS クラスターでのネットワークの問題のトラブルシューティング

ネットワークの問題は、Kubernetes の新規インストール時や、Kubernetes の負荷を増やしたときに発生する可能性があります。 ネットワークの問題に起因する他の問題も発生する可能性があります。 いつでも「AKS のトラブルシューティング」ガイドを参照して、そこに問題について説明されていないか確認してください。 この記事では、ネットワークのトラブルシューティングの観点から追加の詳細情報と考慮事項について、および発生する可能性のある特定の問題について説明します。

クライアントが API サーバーに到達できない

このようなエラーは、Kubernetes クラスター コマンド ライン ツール (kubectl) や、プログラミング言語を介した REST API などの他のツールを使用して、Azure Kubernetes Service (AKS) クラスターの API サーバーに到達できない場合に発生する接続の問題が関係しています。

Error

次のようなエラーが表示される場合があります。

Unable to connect to the server: dial tcp <API-server-IP>:443: i/o timeout 
Unable to connect to the server: dial tcp <API-server-IP>:443: connectex: A connection attempt
failed because the connected party did not properly respond after a period, or established 
connection failed because connected host has failed to respond. 

原因 1

API サーバーによって承認された IP 範囲がクラスターの API サーバーで有効になっていても、クライアントの IP アドレスがそれらの IP 範囲に含まれていない可能性があります。 IP 範囲が有効かどうかを確認するには、Azure CLI で以下の az aks show コマンドを使用します。 IP 範囲が有効になっている場合、このコマンドによって IP 範囲の一覧が生成されます。

az aks show --resource-group <cluster-resource-group> \ 
    --name <cluster-name> \ 
    --query apiServerAccessProfile.authorizedIpRanges 

解決策 1

クライアントの IP アドレスが、クラスターの API サーバーによって承認された範囲内にあることを確認してください。

  1. ローカル IP アドレスを確認します。 Windows および Linux で確認する方法については、IP を見つける方法に関するセクションを参照してください。

  2. Azure CLI で az aks update コマンドを使用して、API サーバーによって承認される範囲を更新します。 クライアントの IP アドレスを承認します。 手順については、「クラスターの、API サーバーの許可された IP 範囲を更新する」を参照してください。

原因 2

AKS クラスターがプライベート クラスターの場合、API サーバー エンドポイントにはパブリック IP アドレスがありません。 AKS クラスターの仮想ネットワークへのネットワーク アクセスがある VM を使用する必要があります。

解決策 2

この問題を解決する方法については、「プライベート クラスターに接続するための選択肢」を参照してください。

ポッドが IP アドレスの割り当てに失敗する

Error

ポッドが ContainerCreating 状態でスタックし、そのイベントで Failed to allocate address エラーが報告されます。

Normal   SandboxChanged          5m (x74 over 8m)    kubelet, k8s-agentpool-00011101-0 Pod sandbox
changed, it will be killed and re-created. 

  Warning  FailedCreatePodSandBox  21s (x204 over 8m)  kubelet, k8s-agentpool-00011101-0 Failed 
create pod sandbox: rpc error: code = Unknown desc = NetworkPlugin cni failed to set up pod 
"deployment-azuredisk6-874857994-487td_default" network: Failed to allocate address: Failed to 
delegate: Failed to allocate address: No available addresses 

または、not enough IPs available エラーが発生します。

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox 
'ac1b1354613465324654c1588ac64f1a756aa32f14732246ac4132133ba21364': plugin type='azure-vnet' 
failed (add): IPAM Invoker Add failed with error: Failed to get IP address from CNS with error: 
%w: AllocateIPConfig failed: not enough IPs available for 9c6a7f37-dd43-4f7c-a01f-1ff41653609c, 
waiting on Azure CNS to allocate more with NC Status: , IP config request is [IPConfigRequest: 
DesiredIPAddress , PodInterfaceID a1876957-eth0, InfraContainerID 
a1231464635654a123646565456cc146841c1313546a515432161a45a5316541, OrchestratorContext 
{'PodName':'a_podname','PodNamespace':'my_namespace'}]

プラグイン IPAM ストアで割り当てられた IP アドレスを確認します。 すべての IP アドレスが割り当てられていても、その数が実行中のポッドの数よりもはるかに少ないことが示されている可能性があります。

kubenet を使用している場合:

# Kubenet, for example. The actual path of the IPAM store file depends on network plugin implementation. 
chroot /host/
ls -la "/var/lib/cni/networks/$(ls /var/lib/cni/networks/ | grep -e "k8s-pod-network" -e "kubenet")" | grep -v -e "lock\|last\|total" -e '\.$' | wc -l
244

Note

Calico のない kubenet の場合、パスは /var/lib/cni/networks/kubenet です。 Calico を使用した kubenet の場合、パスは /var/lib/cni/networks/k8s-pod-network です。 上記のスクリプトでは、コマンドの実行中にパスが自動的に選択されます。

# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=<your_node_name>,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
7 

動的IP 割り当てにAzure CNIを使用する場合:

kubectl get nnc -n kube-system -o wide
NAME                               REQUESTED IPS  ALLOCATED IPS  SUBNET  SUBNET CIDR   NC ID                                 NC MODE  NC TYPE  NC VERSION
aks-agentpool-12345678-vmss000000  32             32             subnet  10.18.0.0/15  559e239d-f744-4f84-bbe0-c7c6fd12ec17  dynamic  vnet     1
# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=aks-agentpool-12345678-vmss000000,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
21

原因 1

このエラーは、ネットワーク プラグインのバグが原因である可能性があります。 ポッドが終了するときに、プラグインが IP アドレスの割り当てを解除できない場合があります。

解決策 1

回避策または修正プログラムについては、Microsoft にお問い合わせください。

原因 2

ポッドの作成が、終了したポッドのガベージ コレクションよりもはるかに速く行われています。

解決策 2

kubelet で高速のガベージ コレクションを構成します。 手順については、 Kubernetes のガベージ コレクションに関するドキュメントをご覧ください。

ポッド内でサービスにアクセスできない

この問題を解決するための最初の手順は、サービスのエンドポイントが自動的に作成されているかどうかを確認することです。

kubectl get endpoints <service-name> 

空の結果が返された場合、サービスのラベル セレクターが間違っている可能性があります。 ラベルが正しいことを確認してください。

# Query Service LabelSelector. 
kubectl get svc <service-name> -o jsonpath='{.spec.selector}' 

# Get Pods matching the LabelSelector and check whether they're running. 
kubectl get pods -l key1=value1,key2=value2 

上記の手順で予期される値が返される場合:

  • ポッドの containerPort がサービスの containerPort と同じかどうかを確認します。

  • podIP:containerPort が機能しているかどうかを確認します。

    # Testing via cURL. 
    curl -v telnet ://<Pod-IP>:<containerPort>
    
    # Testing via Telnet. 
    telnet <Pod-IP>:<containerPort> 
    

サービスの問題の他の原因として、以下も考えられます。

  • コンテナーが、指定された containerPort をリッスンしていません。 (ポッドの説明を確認してください。)
  • CNI プラグインのエラーまたはネットワーク ルートのエラーが発生しています。
  • kube-proxy が実行されていないか、iptables 規則が正しく構成されていません。
  • ネットワーク ポリシーによってトラフィックが破棄されています。 ネットワーク ポリシーの適用とテストの詳細については、「Azure Kubernetes ネットワーク ポリシーの概要」を参照してください。
    • ネットワーク プラグインとして Calico を使用している場合は、ネットワーク ポリシー トラフィックをキャプチャすることもできます。 その構成の詳細については、Calico のサイトをご覧ください。

ノードが API サーバーに到達できない

多くのアドオンとコンテナーは、Kubernetes API (kube-dns およびオペレーター コンテナーなど) にアクセスする必要があります。 このプロセス中にエラーが発生した場合は、問題の原因を特定するのに以下の手順が役立ちます。

まず、ポッド内で Kubernetes API にアクセスできるかどうかを確認します。

kubectl run curl --image=mcr.microsoft.com/azure-cli -i -t --restart=Never --overrides='[{"op":"add","path":"/spec/containers/0/resources","value":{"limits":{"cpu":"200m","memory":"128Mi"}}}]' --override-type json --command -- sh

次に、シェル化されたコンテナ内から次を実行します。

# If you don't see a command prompt, try selecting Enter. 
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) 
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods

正常な出力は次のようになります。

{ 
  "kind": "PodList", 
  "apiVersion": "v1", 
  "metadata": { 
    "selfLink": "/api/v1/namespaces/default/pods", 
    "resourceVersion": "2285" 
  }, 
  "items": [ 
   ... 
  ] 
} 

エラーが発生した場合は、kubernetes-internal サービスとそのエンドポイントが正常かどうかを確認します。

kubectl get service kubernetes-internal
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE 
kubernetes-internal ClusterIP   10.96.0.1    <none>        443/TCP   25m 
kubectl get endpoints kubernetes-internal
NAME                ENDPOINTS          AGE 
kubernetes-internal 172.17.0.62:6443   25m 

両方のテストで上記のような応答が返され、返された IP とポートがコンテナーのものと一致する場合は、kube-apiserver が実行されていないか、ネットワークからブロックされている可能性があります。

アクセスがブロックされる主な理由として、以下の 4 つが考えられます。

Container insights を使用して kube-apiserver ログを確認することもできます。 kube-apiserver ログのクエリの実行と、その他の多くのクエリについては、「Container insights のログのクエリを実行する方法」を参照してください。

最後に、クラスター自体で kube-apiserver の状態とそのログを確認することができます。

# Check kube-apiserver status. 
kubectl -n kube-system get pod -l component=kube-apiserver 

# Get kube-apiserver logs. 
PODNAME=$(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system logs $PODNAME --tail 100

403 - Forbidden エラーが返された場合、kube-apiserver はおそらく、ロールベースのアクセス制御 (RBAC) が構成されており、コンテナーの ServiceAccount はおそらく、リソースへのアクセスが許可されていません。 この場合は、適切な RoleBinding および ClusterRoleBinding オブジェクトを作成する必要があります。 ロールとロール バインディングの詳細については、アクセスと ID に関する記事を参照してください。 クラスターで RBAC を構成する方法の例については、「RBAC 認可を使用する」を参照してください。

共同作成者

この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。

プリンシパル作成者:

その他の共同作成者:

次の手順