AKS クラスターでホストされているアプリへの接続に関する問題のトラブルシューティング
現在の動的クラウド環境では、最適なパフォーマンスとユーザー エクスペリエンスを維持するために、Azure Kubernetes Service (AKS) クラスターでホストされているアプリケーションへのシームレスな接続を確保することが重要です。 この記事では、アプリケーション側の問題、ネットワーク ポリシー、ネットワーク セキュリティ グループ (NSG) ルールなど、さまざまな要因によって発生する接続の問題をトラブルシューティングして解決する方法について説明します。
Note
AKS API サーバーに接続しようとしたときの一般的な問題のトラブルシューティングについては、「 API サーバーに関するクラスター接続の問題のトラブルシューティングの基本を参照してください。
前提条件
クライアント URL (cURL) ツール、または同様のコマンド ライン ツール。
パッケージを処理するための apt-get コマンドライン ツール。
TCP 接続用の Netcat (
nc
) コマンドライン ツール。Kubernetes kubectl ツール、またはクラスターに接続するための同様のツール。 Azure CLI を使用して kubectl をインストールするには、az aks install-cli コマンドを実行します。
考慮すべき要素
このセクションでは、AKS クラスターでホストされているアプリケーションに接続しようとしたときに問題が発生した場合に実行するトラブルシューティング手順について説明します。
どのネットワーク シナリオでも、管理者はトラブルシューティング時に次の重要な要素を考慮する必要があります。
要求のソースと送信先は何ですか?
ソースと宛先の間のホップは何ですか?
要求/応答フローとは
次のような追加のセキュリティ 層が上にあるホップ:
- ファイアウォール
- ネットワーク セキュリティ グループ (NSG)
- ネットワーク ポリシー
各コンポーネントを確認するときは、HTTP 応答コードを取得して分析。 これらのコードは、問題の性質を特定するのに役立ち、アプリケーションが HTTP 要求に応答するシナリオで特に役立ちます。
他のトラブルシューティング手順で決定的な結果が得られない場合は、クライアントとサーバーからパケット キャプチャを実行します。 パケット キャプチャは、クライアントとサーバーの間に HTTP 以外のトラフィックが関係している場合にも役立ちます。 AKS 環境のパケット キャプチャを収集する方法の詳細については、データ収集ガイドの次の記事を参照してください。
HTTP 応答コードを取得し、パケット キャプチャを取得する方法を知ることで、ネットワーク接続の問題のトラブルシューティングが簡単になります。
AKS 上のアプリケーションの基本的なネットワーク フロー
一般に、アプリケーションが Azure Load Balancer サービスの種類を使用して公開されている場合、それらにアクセスするための要求フローは次のようになります。
ポッド>> AKS ノード>> AKS ロード バランサーの IP アドレス>>クライアント >> DNS 名
他にも、追加のコンポーネントが関係する可能性がある状況があります。 例えば次が挙げられます。
- アプリケーション ルーティング アドオン機能を使用したマネージド NGINX イングレスが有効になります。
- アプリケーション ゲートウェイは、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
または Running
状態ではない場合、または何度も再起動した場合は、 kubectl describe
出力を確認します。 このイベントにより、ポッドを起動できない問題が明らかになります。 または、ポッドが起動した場合、ポッド内のアプリケーションが失敗し、ポッドが再起動された可能性があります。 それに応じてポッドのトラブルシューティングを行い 適切な状態になっていることを確認します。
ポッドが実行されている場合は、ポッド内にあるコンテナーのログを確認することもできます。 次の一連の kubectl logs コマンドを実行します。
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 && apt-get install netcat-traditional -y
# After the packages are installed, test the connectivity to the application pod:
curl -Iv http://<pod-ip-address>:<port>
他のプロトコルでリッスンするアプリケーションの場合は、netcat ツールのようなテスト ポッド内に関連するツールをインストールし、次のコマンドを実行してアプリケーション ポッドへの接続を確認できます。
# After the packages are installed, test the connectivity to the application pod using netcat/nc command:
nc -z -v <pod-ip-address> <port>
ポッドをトラブルシューティングするその他のコマンドについては、ポッドの実行 Debug に関するを参照してください。
手順 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 アドレスを指していない場合は、ポッドとサービスの Labels
と Selectors
を確認します。
サービス内のエンドポイントは正しいですか? その場合は、サービスにアクセスし、アプリケーションに到達できるかどうかを確認します。
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 && apt-get install netcat-traditional -y
# After the packages are installed, test the connectivity to the service:
curl -Iv http://<service-ip-address>:<port>
他のプロトコルでリッスンするアプリケーションの場合は、netcat ツールのようなテスト ポッド内に関連するツールをインストールし、次のコマンドを実行してアプリケーション ポッドへの接続を確認できます。
# After the packages are installed, test the connectivity to the application pod using netcat/nc command:
nc -z -v <pod-ip-address> <port>
前のコマンドで適切な応答が返されない場合は、サービス イベントでエラーがないか確認します。
LoadBalancer サービスにアクセスする
LoadBalancer
サービスの場合は、クラスターの外部からロード バランサーの IP アドレスにアクセスできます。
curl -Iv http://<service-ip-address>:<port>
他のプロトコルでリッスンするアプリケーションの場合は、netcat ツールのようなテスト ポッド内に関連するツールをインストールし、次のコマンドを実行してアプリケーション ポッドへの接続を確認できます。
nc -z -v <pod-ip-address> <port>
LoadBalancer
サービスの IP アドレスから正しい応答が返されますか? そうでない場合は、次の手順に従います。
サービスのイベントを確認します。
AKS ノードと AKS サブネットに関連付けられているネットワーク セキュリティ グループ (NSG) で、サービス ポートでの受信トラフィックが許可されていることを確認します。
サービスをトラブルシューティングするためのその他のコマンドについては、 Debug サービスを参照してください。
サービスの代わりにイングレスを使用するシナリオ
Ingress
リソースを使用してアプリケーションが公開されるシナリオでは、トラフィック フローは次の進行状況のようになります。
クラスター >> サービスまたはポッド内のイングレス コントローラー ポッド>>ロード バランサーまたはアプリケーション ゲートウェイの IP アドレス>> DNS 名>>クライアント
ここでは、トラブルシューティングのインサイド アウト アプローチを適用することもできます。 詳細については、イングレス kubernetes リソースとイングレス コントローラーの詳細を確認することもできます。
$ 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 などのイングレス ポッド上のコンポーネントが、要求をクラスターに正しくルーティングしていないことです。 これが当てはまる場合は、これらのリソースのバックエンド構成を確認できます。
Connection Timed Out
エラー メッセージが表示された場合は、AKS ノードに関連付けられているネットワーク セキュリティ グループを確認します。 また、AKS サブネットを確認します。 ロード バランサーまたはアプリケーション ゲートウェイから AKS ノードへのトラフィックがブロックされている可能性があります。
イングレスのトラブルシューティング方法 (Nginx イングレスなど) の詳細については、 ingress-nginx のトラブルシューティングを参照してください。
お問い合わせはこちらから
質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。
サードパーティのお問い合わせ窓口に関する免責事項
サードパーティのお問い合わせ窓口に関する情報は、ユーザーの便宜のために提供されているものであり、 この連絡先情報は、予告なしに変更される可能性があります。 マイクロソフトは、掲載されている情報に対して、いかなる責任も負わないものとします。