Azure Kubernetes Service ノードでの SNAT ポート不足のトラブルシューティング
この記事は、ソース ネットワーク アドレス変換 (SNAT) ポート不足が発生する Azure Kubernetes Service (AKS) ノードを見つけてトラブルシューティングするのに役立ちます。
Note
- Kubernetes ジョブを実行している AKS クラスター内の AKS ノードでの SNAT ポート不足のトラブルシューティングを行うにはジョブが AKS ノードでアクティブに実行されている場合にのみ、次の手順を実行します。
- SNAT ポートと仮想マシンごとの割り当ての詳細については、「SNAT ポートを参照してください。
手順 1: SNAT ポートの枯渇が発生しているノードを見つける
Azure portal からアクティブな SNAT ポート枯渇が発生する AKS ノードの IP アドレスを取得します。
これを行うには、Azure portal で AKS クラスターに移動し、 Diagnose と解決の問題>接続の問題>SNAT 接続とポートの割り当てを選択します。 SNAT 接続と [ポートの割り当て] タブには、SNAT ポート不足が発生している AKS ノードのプライベート IP アドレスが表示されます。
次の
kubectl
コマンドを実行して、AKS クラスターに接続し、ノード IP アドレスを使用してノード名を取得します。kubectl get nodes -o wide | grep <node IP>
手順 2: 送信接続が多い Linux ポッドを見つける
Note
- Tcptracer は、Linux ノードにプレインストールされている BPF コンパイラ コレクション (BCC) ツール の 1 つです。 これにより、TCP 確立された接続 (
connect()
、accept()
、およびclose()
) をトレースできます。 これを使用して、ポッドの送信元 IP アドレスとネットワーク名前空間 (netns) からの高い送信接続を見つけることができます。 - BCC ツールにアクセスするには、 kubectl node-shell only を使用します。
- このセクションの次のコマンドはすべて、BCC ツールがインストールされている Linux ノードでルート ユーザーとして実行されます。
SNAT ポート不足が発生した Linux ノードに、 kubectl node-shell をインストールします:
curl -LO https://github.com/kvaps/kubectl-node-shell/raw/master/kubectl-node_shell chmod +x ./kubectl-node_shell sudo mv ./kubectl-node_shell /usr/local/bin/kubectl-node_shell
SSH を使用して、SNAT ポートの枯渇が発生するノードに接続し、
tcptracer
を使用して TCP で確立された接続をトレースします。kubectl node-shell <node name> cd /usr/share/bcc/tools /usr/share/bcc/tools# python3 tcptracer -t4v
コマンド出力の例を次に示します。
Tracing TCP established connections. Ctrl-C to end. TIME(ns) TYPE PID COMM IP SADDR DADDR SPORT DPORT NETNS 0 connect 18627 curl 4 1.2.3.4 5.6.7.8 53746 80 4026532785 3xxx9 close 18627 curl 4 1.2.3.4 5.6.7.8 53746 80 4026532785 1xxxx4 connect 18629 curl 4 1.2.3.4 9.10.11.12 35686 80 4026532785 2xxxx9 close 18629 curl 4 1.2.3.4 9.10.11.12 35686 80 4026532785 4xxxx5 connect 18631 curl 4 1.2.3.4 9.10.11.12 35688 80 4026532785 4xxxx8 close 18631 curl 4 1.2.3.4 9.10.11.12 35688 80 4026532785 7xxxx3 connect 18633 curl 4 1.2.3.4 13.14.15.16 35690 80 4026532785 9xxxx7 close 18633 curl 4 1.2.3.4 13.14.15.16 35690 80 4026532785
前のコマンド出力をログ ファイルに書き込み、出力を並べ替えて高接続の一覧を確認します。
python3 tcptracer -t4v > log head -n +2 log | tail -n 1 | awk '{print "Count",$6,$10}'; awk '{print $6,$10}' log | sort | uniq -c | sort -nrk 1 | column -t
コマンド出力の例を次に示します。
Count SADDR NETNS 387 1.2.3.4 4026532785 8 11.22.33.44 4026532184 8 55.66.77.88 4026531992
前の出力からの接続が最も多い IP アドレスをポッドにマップします。 動作しない場合は、続行できます。
前の出力からの接続数が最も多い
SADDR
またはNETNS
値をメモし、次の lsns コマンドを実行して PID にマップします。 Lsns は、Linux プロセス ツリーで名前空間を一覧表示し、名前空間を PID にマップする Linux ツールです。lsns -t net
コマンド出力の例を次に示します。
NS TYPE NPROCS PID USER COMMAND 4026532785 net 3 19832 root bash
pstree を使用して、前の PID をコンテナー化されたプロセスにマップします。 Pstree は、読みやすくするためにツリー形式でプロセスを一覧表示する Linux ツールです。
pstree -aps 19832
コマンド出力の例を次に示します。
systemd,1 `-containerd-shim,20946 -namespace k8s.io -id 2xxxf...
コマンド出力のコンテナー化された
-id
の最初の 5 文字に注意してください。 これは、手順 7 で使用します。crictlを使用して、前のコンテナー化された
-id
値を POD ID にマップします。 Crictl は、CRI と互換性のあるコンテナー ランタイム用の CLI を提供します。crictl ps -a
コマンド出力の例を次に示します。
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD 6b5xxxxb fbxxxxx1 6 hours ago Running ubuntu 0 2xxxxxxxxf nginx
POD ID と一致するには、前のコンテナー化された
-id
値の最初の 5 文字を使用します。ノードで実行されているすべてのポッドを取得し、前の POD ID を使用して、コマンド出力からの送信接続が多いポッドと一致させます。
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=<nodename>
手順 3: アプリケーションによって行われたすべての送信ネットワーク接続を見つける
次のいずれかのコマンドを使用して、 Step 2 で高い送信接続を持つと識別されたポッドに対して実行します。
-
kubectl exec -it <pod name> -n <namespace> /bin/bash
-
kubectl exec -it <pod name> -n <namespace> /bin/sh
-
次のコマンドを実行して、netstat コマンド ライン ツールをポッドにインストールします。 Netstat は、管理者専用のネットワーク トラブルシューティング ツールです。
Debian、Ubuntu、または Linux Mint の場合
apt update apt install net-tools
RHEL、CentOS、Fedora、AlmaLinux、または Rocky Linux の場合
yum update yum install net-tools
Gentoo Linux 上
emerge -a sys-apps/net-tools
Alpine Linux 上
apk add net-tools
Arch Linux 上
pacman -S net-tools
OpenSUSE の場合
zypper install net-tools
netstat がポッドにインストールされたら、次のコマンドを実行します。
netstat -ptn | grep -i established
コマンド出力の例を次に示します。
tcp 0 0 10.x.x.x:xxxx 20.x.x.x:443 ESTABLISHED xxxxx3/telnet
コマンド出力では、ローカル アドレスはポッドの IP アドレス、外部アドレスはアプリケーションが接続する IP です。 ESTABLISHED
状態のパブリック IP 接続は、SNAT を利用する接続です。 パブリック IP アドレスへの ESTABLISHED
状態の接続のみをカウントし、 ESTABLISHED
状態のプライベート IP アドレスへの接続は無視してください。
ノードで実行されている他のすべてのポッドについて、このセクションの手順を繰り返します。 パブリック IP アドレスへの ESTABLISHED
状態の接続が最も多いポッドは、ノードで SNAT ポート枯渇の原因となるアプリケーションをホストします。 アプリケーション開発者と協力して、 Design 接続効率の高いアプリケーションで説明されている推奨事項を使用して、ネットワーク パフォーマンスを向上させるためにアプリケーションを調整します。 推奨事項を実装した後、SNAT ポートの枯渇が少ないことを確認します。
お問い合わせはこちらから
質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。