AKS クラスターでホストされているアプリへの接続の問題のトラブルシューティング
Microsoft Azure Kubernetes Service (AKS) クラスターへの接続の問題は、さまざまなことを意味する可能性があります。 場合によっては、API サーバーへの接続が影響を受ける可能性があります (たとえば、kubectl を使用)。 場合によっては、AKS クラスターでホストされているアプリケーションに一般的な接続の問題が影響を与える可能性があります。 この記事では、AKS クラスター接続の問題をトラブルシューティングする方法について説明します。
注:
AKS API サーバーに接続しようとしたときの一般的な問題のトラブルシューティングについては、「API サーバーでの クラスター接続の問題の基本的なトラブルシューティング」を参照してください。
前提条件
クライアント URL (cURL) ツール、または同様のコマンド ライン ツール。
パッケージを処理するための apt-get コマンド ライン ツール。
Kubernetes kubectl ツール、またはクラスターに接続するための同様のツール。 Azure CLI を使用して kubectl をインストールするには、az aks install-cli コマンドを実行します。
考慮すべき要因
このセクションでは、AKS クラスターでホストされているアプリケーションに接続しようとしたときに問題が発生した場合に実行するトラブルシューティング手順について説明します。
どのネットワーク シナリオでも、管理者はトラブルシューティングを行うときに、次の重要な要素を考慮する必要があります。
要求のソースと宛先は何ですか?
ソースと宛先の間のホップは何ですか?
要求/応答フローとは
次の項目など、上に追加のセキュリティ レイヤーを持つホップ。
- ファイアウォール
- ネットワーク セキュリティ グループ (NSG)
- ネットワーク ポリシー
各コンポーネントをチェックしたら、HTTP 応答コードを取得して分析します。 これらのコードは、問題の性質を特定するのに役立ち、アプリケーションが HTTP 要求に応答するシナリオで特に役立ちます。
他のトラブルシューティング手順で決定的な結果が得られない場合は、クライアントとサーバーからパケット キャプチャを実行します。 パケット キャプチャは、クライアントとサーバーの間に HTTP 以外のトラフィックが関係している場合にも役立ちます。 AKS 環境のパケット キャプチャを収集する方法の詳細については、データ収集ガイドの次の記事を参照してください。
HTTP 応答コードを取得してパケット キャプチャを取得する方法を理解すると、ネットワーク接続の問題のトラブルシューティングが容易になります。
AKS 上のアプリケーションの基本的なネットワーク フロー
一般に、AKS クラスターでホストされているアプリケーションにアクセスするための要求フローは次のとおりです。
クライアント >> DNS 名 >> AKS ロード バランサーの IP アドレス >> AKS ノード >> ポッド
追加のコンポーネントが関与する可能性があるその他の状況もあります。 以下に例を示します。
- アプリケーション ゲートウェイは、Azure Load Balancerではなく、Application Gateway イングレス コントローラー (AGIC) を介して使用されます。
- Azure Front Door と API Managementは、ロード バランサーの上で使用される場合があります。
- このプロセスでは、内部ロード バランサーが使用されます。
- 接続がポッドと要求された URL で終了しない可能性があります。 これは、ポッドが別のエンティティ (データベースなど)、または同じクラスター内の他のサービスに接続できるかどうかによって異なります。
アプリケーションの要求フローを理解することが重要です。
AKS クラスター上のアプリケーションへの基本的な要求フローは、次の図に示すフローのようになります。
インサイド アウトのトラブルシューティング
接続の問題のトラブルシューティングには多くのチェックが必要な場合がありますが、 インサイドアウト アプローチは問題の原因を見つけ、ボトルネックを特定するのに役立ちます。 この方法では、ポッド自体から開始し、アプリケーションがポッドの IP アドレスで応答しているかどうかを確認します。 次に、各コンポーネントをエンド クライアントにチェックします。
手順 1: ポッドが実行されていて、ポッド内のアプリまたはコンテナーが正しく応答しているかどうかを確認する
ポッドが実行されているかどうかを確認するには、次のいずれかの kubectl get コマンドを実行します。
# List pods in the specified namespace.
kubectl get pods -n <namespace-name>
# List pods in all namespaces.
kubectl get pods -A
ポッドが実行されていない場合はどうすればよいですか? この場合、kubectl describe コマンドを使用してポッド イベントをチェックします。
kubectl describe pod <pod-name> -n <namespace-name>
ポッドがまたは 状態ではないReady
場合、または何度も再起動した場合は、出力をチェックしますkubectl describe
。Running
イベントによって、ポッドを起動できない問題が表示されます。 または、ポッドが起動した場合、ポッド内のアプリケーションが失敗し、ポッドが再起動された可能性があります。 ポッドが適切な状態であることを確認するために、それに応じてポッドのトラブルシューティングを行います。
ポッドが実行されている場合は、ポッドとその中にあるコンテナーのログをチェックすることも便利です。 次の一連の kubectl ログ コマンドを実行します。
kubectl logs <pod-name> -n <namespace-name>
# Check logs for an individual container in a multicontainer pod.
kubectl logs <pod-name> -n <namespace-name> -c <container-name>
# Dump pod logs (stdout) for a previous container instance.
kubectl logs <pod-name> --previous
# Dump pod container logs (stdout, multicontainer case) for a previous container instance.
kubectl logs <pod-name> -c <container-name> --previous
ポッドは実行されていますか? この場合は、クラスターでテスト ポッドを起動して接続をテストします。 テスト ポッドから、アプリケーションのポッド IP アドレスに直接アクセスし、アプリケーションが正しく応答しているかどうかをチェックできます。
kubectl run、、apt-get
および コマンドをcURL
次のように実行します。
# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable
# After the test pod is running, you will gain access to the pod.
# Then you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
# After the packages are installed, test the connectivity to the application pod:
curl -Iv http://<pod-ip-address>:<port>
他のプロトコルでリッスンするアプリケーションの場合は、関連するツールをテスト ポッド内にインストールしてから、アプリケーション ポッドへの接続をチェックできます。
ポッドのトラブルシューティングを行うその他のコマンドについては、「 実行中のポッドをデバッグする」を参照してください。
手順 2: アプリケーションがサービスから到達可能かどうかを確認する
ポッド内のアプリケーションが実行されているシナリオでは、主にポッドの公開方法のトラブルシューティングに焦点を当てることができます。
ポッドはサービスとして公開されていますか? この場合、サービス イベントをチェックします。 また、ポッド IP アドレスとアプリケーション ポートをサービスの説明でエンドポイントとして使用できるかどうかをチェックします。
# Check the service details.
kubectl get svc -n <namespace-name>
# Describe the service.
kubectl describe svc <service-name> -n <namespace-name>
次の例のように、ポッドの IP アドレスがサービスのエンドポイントとして存在するかどうかを確認します。
$ kubectl get pods -o wide # Check the pod's IP address.
NAME READY STATUS RESTARTS AGE IP NODE
my-pod 1/1 Running 0 12m 10.244.0.15 aks-agentpool-000000-vmss000000
$ kubectl describe service my-cluster-ip-service # Check the endpoints in the service.
Name: my-cluster-ip-service
Namespace: default
Selector: app=my-pod
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.174.133
IPs: 10.0.174.133
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.15:80 # <--- Here
$ kubectl get endpoints # Check the endpoints directly for verification.
NAME ENDPOINTS AGE
my-cluster-ip-service 10.244.0.15:80 14m
エンドポイントが正しいポッド IP アドレスを指していない場合は、ポッドとサービスの と Selectors
を確認Labels
します。
サービス内のエンドポイントは正しいですか? その場合は、サービスにアクセスし、アプリケーションに到達できるかどうかをチェックします。
ClusterIP サービスにアクセスする
サービスの ClusterIP
場合は、クラスターでテスト ポッドを開始し、サービス IP アドレスにアクセスできます。
# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable
# After the test pod is running, you will gain access to the pod.
# Then, you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
# After the packages are installed, test the connectivity to the service:
curl -Iv http://<service-ip-address>:<port>
前のコマンドが適切な応答を返さない場合は、エラーに対してサービス イベントをチェックします。
LoadBalancer サービスにアクセスする
サービスの LoadBalancer
場合は、クラスターの外部からロード バランサーの IP アドレスにアクセスできます。
curl -Iv http://<service-ip-address>:<port>
サービス IP アドレスは LoadBalancer
正しい応答を返しますか? そうでない場合は、次の手順に従います。
サービスのイベントを確認します。
AKS ノードと AKS サブネットに関連付けられているネットワーク セキュリティ グループ (NSG) で、サービス ポートでの受信トラフィックが許可されていることを確認します。
サービスのトラブルシューティングを行うその他のコマンドについては、「 サービスのデバッグ」を参照してください。
サービスの代わりにイングレスを使用するシナリオ
リソースを使用 Ingress
してアプリケーションが公開されるシナリオでは、トラフィック フローは次の進行のようになります。
クライアント >> DNS 名 >> ロード バランサーまたはアプリケーション ゲートウェイ IP アドレス >> クラスター >> 内のイングレス ポッド サービスまたはポッド
トラブルシューティングのインサイドアウト アプローチもここで適用できます。 詳細については、イングレス コントローラーとイングレス コントローラーの詳細をチェックすることもできます。
$ kubectl get ing -n <namespace-of-ingress> # Checking the ingress details and events.
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-world-ingress <none> myapp.com 20.84.x.x 80, 443 7d22h
$ kubectl describe ing -n <namespace-of-ingress> hello-world-ingress
Name: hello-world-ingress
Namespace: <namespace-of-ingress>
Address: 20.84.x.x
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
tls-secret terminates myapp.com
Rules:
Host Path Backends
---- ---- --------
myapp.com
/blog blog-service:80 (10.244.0.35:80)
/store store-service:80 (10.244.0.33:80)
Annotations: cert-manager.io/cluster-issuer: letsencrypt
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: true
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 5m41s nginx-ingress-controller Scheduled for sync
Normal Sync 5m41s nginx-ingress-controller Scheduled for sync
この例には、次の Ingress
リソースが含まれています。
- ホストでリッスンします
myapp.com
。 - 2 つの
Path
文字列が構成されています。 - バックエンドの 2 に
Services
ルーティングします。
バックエンド サービスが実行されていることを確認し、イングレスの説明に記載されているポートに応答します。
$ kubectl get svc -n <namespace-of-ingress>
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
ingress-basic blog-service ClusterIP 10.0.155.154 <none> 80/TCP
ingress-basic store-service ClusterIP 10.0.61.185 <none> 80/TCP
ingress-basic nginx-ingress-ingress-nginx-controller LoadBalancer 10.0.122.148 20.84.x.x 80:30217/TCP,443:32464/TCP
エラーが発生した場合は、イングレス コントローラー ポッドのログを確認します。
$ kubectl get pods -n <namespace-of-ingress> # Get the ingress controller pods.
NAME READY STATUS RESTARTS AGE
aks-helloworld-one-56c7b8d79d-6zktl 1/1 Running 0 31h
aks-helloworld-two-58bbb47f58-rrcv7 1/1 Running 0 31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q 1/1 Running 0 31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-grzdr 1/1 Running 0 31h
$ # Check logs from the pods.
$ kubectl logs -n ingress-basic nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q
クライアントがイングレス ホスト名または IP アドレスに対して要求を行っていても、イングレス コントローラー ポッドのログにエントリが表示されない場合はどうでしょうか。 この場合、要求がクラスターに到達せず、ユーザーがエラー メッセージを Connection Timed Out
受け取る可能性があります。
もう 1 つの可能性は、Load BalancerやApplication Gatewayなど、イングレス ポッド上のコンポーネントがクラスターに要求を正しくルーティングしていないことです。 これが true の場合は、これらのリソースのバックエンド構成をチェックできます。
エラー メッセージがConnection Timed Out
表示された場合は、AKS ノードに関連付けられているネットワーク セキュリティ グループをチェックします。 また、AKS サブネットをチェックします。 ロード バランサーまたはアプリケーション ゲートウェイから AKS ノードへのトラフィックがブロックされている可能性があります。
イングレス (Nginx イングレスなど) のトラブルシューティング方法の詳細については、「 ingress-nginx トラブルシューティング」を参照してください。
お問い合わせはこちらから
質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。
サードパーティのお問い合わせ窓口に関する免責事項
Microsoft では、このトピックに関する追加情報を見つけるのに役立つサード パーティの連絡先情報を提供しています。 将来予告なしに変更されることがあります。 Microsoft は、第三者の連絡先情報の正確性を保証しません。