Kubernetes のトラブルシューティング
このページでは、Kubernetes のセットアップ、ネットワーク、デプロイに関するいくつかの一般的な問題について説明します。
ヒント
ドキュメント リポジトリに PR を して FAQ 項目を提案。
このページは、次のカテゴリに分割されます。
一般的な質問
Windows 操作方法 Kubernetes が正常に完了したことを知っていますか?
kubelet、kube-proxy、および (ネットワーク ソリューションとして Flannel を選択した場合)、ノードで実行されている flanneld host-agent プロセスが表示されます。 これに加えて、Windows ノードは Kubernetes クラスターに "準備完了" として表示されます。
このすべてをバックグラウンドで実行するように構成できますか?
Kubernetes バージョン 1.11 以降では、kubelet & kube-proxy をネイティブ Windows サービスとして実行できます。 また、 nssm.exe などの代替サービス マネージャーを常に使用して、これらのプロセス (flanneld、kubelet、kube-proxy) をバックグラウンドで常に実行することもできます。
一般的なネットワーク エラー
ロード バランサーがクラスター ノード間で一貫性のない状態で配置される
Windows では、kube-proxy はクラスター内のすべての Kubernetes サービスに対して HNS ロード バランサーを作成します。 (既定の) kube-proxy 構成では、多数の (通常は 100 以上の) ロード バランサーを含むクラスター内のノードで、使用可能なエフェメラル TCP ポート (動的ポート範囲など) が不足する可能性があります。動的ポート範囲は、既定ではポート 49152 から 65535 をカバーします。 これは、(DSR 以外の) ロード バランサーごとに各ノードで予約されているポートの数が多いためです。 この問題は、次のような kube-proxy のエラーによって現れる可能性があります。
Policy creation failed: hcnCreateLoadBalancer failed in Win32: The specified port already exists.
ユーザーは、 CollectLogs.ps1 スクリプトを実行し、 *portrange.txt
ファイルを参照することで、この問題を特定できます。
また、 CollectLogs.ps1
は HNS 割り当てロジックを模倣して、一時的な TCP ポート範囲でポート プールの割り当ての可用性をテストし、 reservedports.txt
の成功/失敗を報告します。 このスクリプトは、64 個の TCP エフェメラル ポートの 10 個の範囲を予約し (HNS 動作をエミュレートするため)、予約の成功と失敗をカウントしてから、割り当てられたポート範囲を解放します。 成功数が 10 未満の場合は、エフェメラル プールの空き領域が不足しています。 また、約 64 ブロックのポート予約が使用できる数のヒューリスティックな概要も、 reservedports.txt
で生成されます。
この問題を解決するには、いくつかの手順を実行できます。
- 永続的なソリューションの場合は、kube-proxy 負荷分散を DSR モードに設定する必要があります。 DSR モードは完全に実装され、Windows Server Insider ビルド 18945 以降でのみ使用できます。
- 回避策として、ユーザーは、
netsh int ipv4 set dynamicportrange TCP <start_port> <port_count>
などのコマンドを使用して、一時的なポートの既定の Windows 構成を増やすこともできます。 警告: 既定の動的ポート範囲をオーバーライドすると、ホスト上の他のプロセス/サービスが非一時的な範囲の使用可能な TCP ポートに依存する可能性があるため、この範囲は慎重に選択する必要があります。 - 累積的な更新プログラムの KB4551853 (およびすべての新しい累積的な更新プログラム) に含まれるインテリジェントなポート プール共有を使用して、DSR モード以外のロード バランサーのスケーラビリティが強化されています。
HostPort の発行が機能しない
HostPort 機能を使用するには、CNI プラグインが v0.8.6 リリース以降であり、CNI 構成ファイルに portMappings
機能が設定されていることを確認してください。
"capabilities": {
"portMappings": true
}
"hnsCall failed in Win32: The wrong diskette is in the drive" (Win32 で hnsCall が失敗しました:間違ったディスケットがドライブに含まれています) などのエラーが表示されます。
このエラーは、HNS オブジェクトにカスタム変更を加えたり、古い HNS オブジェクトを破棄せずに HNS に変更を加える新しい Windows Update をインストールしたりするときに発生する可能性があります。 これは、更新プログラムの前に以前に作成された HNS オブジェクトが、現在インストールされている HNS バージョンと互換性を持たなかったことを示します。
Windows Server 2019 (以前) では、ユーザーは HNS.data ファイルを削除することで HNS オブジェクトを削除できます
Stop-Service HNS
rm C:\ProgramData\Microsoft\Windows\HNS\HNS.data
Start-Service HNS
ユーザーは、互換性のない HNS エンドポイントまたはネットワークを直接削除できる必要があります。
hnsdiag list endpoints
hnsdiag delete endpoints <id>
hnsdiag list networks
hnsdiag delete networks <id>
Restart-Service HNS
Windows Server バージョン 1903 のユーザーは、次のレジストリの場所に移動し、ネットワーク名 ( vxlan0
や cbr0
など) で始まるすべての NIC を削除できます。
\\Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vmsmp\parameters\NicList
Azure 上の Flannel host-gw デプロイ上のコンテナーがインターネットに到達できない
Azure でホスト gw モードで Flannel をデプロイする場合、パケットは Azure 物理ホスト vSwitch を経由する必要があります。 ユーザーは、ノード 割り当てられたサブネットごとに ユーザー定義ルートの種類が "仮想アプライアンス" であるプログラムを作成する必要があります。 これは、Azure portal ( ここの例を参照) または Azure CLI az
使用して行うことができます。 IP 10.0.0.4 とそれぞれのポッド サブネット 10.244.0.0/24 を持つノードに対して az コマンドを使用して、"MyRoute" という名前の UDR の例を次に示します。
az network route-table create --resource-group <my_resource_group> --name BridgeRoute
az network route-table route create --resource-group <my_resource_group> --address-prefix 10.244.0.0/24 --route-table-name BridgeRoute --name MyRoute --next-hop-type VirtualAppliance --next-hop-ip-address 10.0.0.4
ヒント
自分で他のクラウド プロバイダーから Azure または IaaS VM に Kubernetes をデプロイする場合は、代わりに overlay networking
を使用することもできます。
Windows ポッドで外部リソースに ping を実行できない
現在、Windows ポッドには ICMP プロトコル用にプログラムされた送信規則はありません。 ただし、TCP/UDP はサポートされています。 クラスター外のリソースへの接続を示す場合は、 ping <IP>
対応する curl <IP>
コマンドに置き換えてください。
それでも問題が解決する場合は、 cni.conf のネットワーク構成に注意が必要です。 この静的ファイルはいつでも編集できます。構成は、新しく作成されたすべての Kubernetes リソースに適用されます。
なぜですか?
Kubernetes ネットワーク要件 ( Kbernetes モデルを参照) の 1 つは、内部的に NAT なしでクラスター通信を行う場合です。 この要件を満たすために、送信 NAT を発生させたくないすべての通信に対して ExceptionList があります。 ただし、これは、クエリを実行しようとしている外部 IP を ExceptionList から除外する必要があることを意味します。 その場合にのみ、Windows ポッドから送信されたトラフィックは、外部からの応答を受信するために SNAT に正しく送信されます。 この点に関して、 cni.conf
の ExceptionList は次のようになります。
"ExceptionList": [
"10.244.0.0/16", # Cluster subnet
"10.96.0.0/12", # Service subnet
"10.127.130.0/24" # Management (host) subnet
]
Windows ノードが NodePort サービスにアクセスできない
ノード自体からのローカル NodePort アクセスが失敗する可能性があります。 これは、累積的な更新プログラムのKB4571748 (またはそれ以降) で対処されている既知の機能ギャップです。 NodePort アクセスは、他のノードまたは外部クライアントから機能します。
ポッドをスケールダウンした後、Windows ノードが NodePorts のルーティングを停止する
設計上の制限により、NodePort 転送を機能させるには、Windows ノードで少なくとも 1 つのポッドが実行されている必要があります。
しばらくすると、コンテナーの vNIC と HNS エンドポイントが削除されます
この問題は、 hostname-override
パラメーターが kube-proxy に渡されない場合に発生する可能性があります。 これを解決するには、ユーザーは次のようにホスト名を kube-proxy に渡す必要があります。
C:\k\kube-proxy.exe --hostname-override=$(hostname)
Flannel (vxlan) モードでは、ノードの再参加後にポッドに接続の問題が発生しています
以前に削除されたノードがクラスターに再参加するたびに、flannelD は新しいポッド サブネットをノードに割り当てようとします。 ユーザーは、次のパスで古いポッド サブネット構成ファイルを削除する必要があります。
Remove-Item C:\k\SourceVip.json
Remove-Item C:\k\SourceVipRequest.json
Kubernetes を起動した後、Flanneld は "Waiting for the Network to created" (ネットワークが作成されるのを待っている) で停止します
この問題は、 Flannel v0.12.0 (以降) で対処する必要があります。 以前のバージョンの Flanneld を使用している場合は、フランネル ネットワークの管理 IP が設定されていないような既知の競合状態が発生する可能性があります。 回避策は、単に FlannelD を手動で再起動することです。
PS C:> [Environment]::SetEnvironmentVariable("NODE_NAME", "<Windows_Worker_Hostname>")
PS C:> C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface=<Windows_Worker_Node_IP> --ip-masq=1 --kube-subnet-mgr=1
/run/flannel/subnet.env がないため、Windows ポッドを起動できません
これは、Flannel が正しく起動しなかったことを示します。 flanneld.exeを再起動するか、Kubernetes マスターの /run/flannel/subnet.env
から手動でファイルをコピーして Windows ワーカー ノードの C:\run\flannel\subnet.env
し、 FLANNEL_SUBNET
行を割り当てられたサブネットに変更することができます。 たとえば、ノード サブネット 10.244.4.1/24 が割り当てられている場合は、次のようになります。
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.4.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=true
多くの場合、最初に調査する必要があるこのエラーを引き起こす可能性のある別の問題があります。 このファイル flanneld.exe
生成できるようにすることをお勧めします。
vSphere で実行されている Kubernetes クラスターでホスト間のポッド間接続が切断される
vSphere と Flannel の両方がオーバーレイ ネットワーク用にポート 4789 (既定の VXLAN ポート) を予約しているため、パケットがインターセプトされる可能性があります。 オーバーレイ ネットワークに vSphere を使用する場合は、4789 を解放するために別のポートを使用するように構成する必要があります。
エンドポイント/IP がリークしている
現在、エンドポイントがリークする原因となる既知の問題が 2 つあります。
- 最初の known の問題 は、Kubernetes バージョン 1.11 の問題です。 Kubernetes バージョン 1.11.0 - 1.11.2 は使用しないでください。
- エンドポイント リークの原因となる可能性がある 2 つ目の問題は エンドポイントのストレージにおけるコンカレンシーの問題です。 修正プログラムを受け取る場合は、Docker EE 18.09 以降を使用する必要があります。
"network: failed to allocate for range" (ネットワーク: 範囲の割り当てに失敗しました) エラーが原因でポッドを起動できない
これは、ノードの IP アドレス空間が使い切っていることを示します。 が発生したエンドポイントをクリーンアップするには影響を受けるノード上のリソースを移行し、次のコマンドを実行します。
c:\k\stop.ps1
Get-HNSEndpoint | Remove-HNSEndpoint
Remove-Item -Recurse c:\var
Windows ノードがサービス IP を使用してサービスにアクセスできない
これは、Windows 上の現在のネットワーク スタックの既知の制限です。 ただし、Windows podsサービス IP にアクセスできます。
Kubelet の起動時にネットワーク アダプターが見つかりません
Windows ネットワーク スタックには、Kubernetes ネットワークを機能させるために仮想アダプターが必要です。 次のコマンドで (管理シェルで) 結果が返されない場合、Kubelet が機能するために必要な前提条件である HNS ネットワークの作成は失敗しました。
Get-HnsNetwork | ? Name -ieq "cbr0"
Get-HnsNetwork | ? Name -ieq "vxlan0"
Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*"
多くの場合、ホストのネットワーク アダプターが "イーサネット" でない場合は、start.ps1 スクリプトの InterfaceName パラメーターを変更する必要があります。 それ以外の場合は、 start-kubelet.ps1
スクリプトの出力を参照して、仮想ネットワークの作成中にエラーがあるかどうかを確認します。
私はまだ問題が発生しています。 どうすればよいですか。
ネットワークまたはホストに追加の制限が設けられているため、ノード間の特定の種類の通信が妨げる場合があります。 次のことを確認してください。
- 選択したネットワーク トポロジが適切に構成されている (
l2bridge
またはoverlay
) - ポッドから送信されたように見えるトラフィックは許可されます
- Web サービスをデプロイする場合、HTTP トラフィックは許可されます
- 異なるプロトコル (ICMP と TCP/UDP) のパケットがドロップされない
ヒント
その他のセルフヘルプ リソースについては、Windows 対応の Kubernetes ネットワークトラブルシューティング ガイドもあります。
Windows の一般的なエラー
Kubernetes ポッドが "ContainerCreating" でスタックしている
この問題には多くの原因が考えられますが、最も一般的なものの 1 つは、一時停止イメージが正しく構成されていないことです。 これは、次の問題の大まかな症状です。
デプロイ時に Docker コンテナーが再起動し続ける
一時停止イメージが OS バージョンと互換性があることを確認します。 Kubernetes では、OS とコンテナーの両方に一致する OS バージョン番号があることを前提としています。 Insider ビルドなどの Windows の実験用ビルドを使用している場合は、それに応じてイメージを調整する必要があります。 イメージについては、Microsoft の Docker リポジトリ を参照してください。
一般的な Kubernetes マスター エラー
Kubernetes マスターのデバッグは、(可能性の高い順に) 3 つの主要なカテゴリに分類されます。
- Kubernetes システム コンテナーに問題があります。
kubelet
の実行方法に問題があります。- システムに問題があります。
kubectl get pods -n kube-system
実行して、Kubernetes によって作成されているポッドを確認します。これにより、クラッシュしている特定のポッドや正常に起動していないポッドに関する分析情報が得られる場合があります。 次に、 docker ps -a
実行して、これらのポッドをバックアップするすべての生コンテナーを確認します。 最後に、問題の原因と考えられるコンテナーで docker logs [ID]
を実行し、プロセスの生出力を確認します。
で API サーバーに接続できない https://[address]:[port]
多くの場合、このエラーは証明書の問題を示します。 構成ファイルが正しく生成されていること、その中の IP アドレスがホストの IP アドレスと一致していること、および API サーバーによってマウントされているディレクトリにコピーされていることを確認します。
この構成ファイルを見つけるのに適した場所は次のとおりです。
~/kube/kubelet/
$HOME/.kube/config
/etc/kubernetes/admin.conf
それ以外の場合は、API サーバーのマニフェスト ファイルを参照してマウント ポイントを確認します。