Kubernetesネットワーキング問題のデバッグ:必須テクニック

ポッド接続、サービス、DNS、ネットワークポリシー、IngressルーティングにわたるKubernetesネットワーキング問題をデバッグします。

Kubernetesネットワーキング問題のデバッグ:必須テクニック

Kubernetesネットワーキングの問題は、通常、タイムアウト、Connection refused、DNS障害、空のServiceエンドポイント、または不正なIngress応答として現れます。迅速に修正するには、パスをトレースします:送信元ポッド、宛先ポッド、Service、DNS、NetworkPolicy、そしてIngressまたはロードバランサーです。

このガイドでは、トラフィックがどこで停止するかを明らかにする実用的なチェック手順とkubectlコマンドを提供します。

Kubernetesネットワーキングの基礎を理解する

デバッグに入る前に、Kubernetesのコアとなるネットワーキングの概念を把握することが重要です:

  • ポッドネットワーキング: 各ポッドは独自の一意のIPアドレスを取得します。同じノード内のポッドは直接通信できます。異なるノード上のポッドは仮想ネットワーク(CNIプラグイン)を介して通信します。
  • サービス: サービスは、ポッドのセットに対して安定したIPアドレスとDNS名を提供します。これらは抽象化レイヤーとして機能し、他のポッドや外部クライアントが個々のポッドIPを知らなくてもアプリケーションバックエンドにアクセスできるようにします。
  • DNS: Kubernetes DNS(通常はCoreDNS)は、Service名をクラスターIPに解決し、サービスディスカバリを可能にします。
  • ネットワークポリシー: これらのリソースは、CNIプラグインが適用するときにポッドトラフィックを制御します。NetworkPolicyをサポートしていないクラスターはオブジェクトを受け入れますが、ルールを適用しない場合があります。
  • Ingress: Ingressコントローラーは、クラスター内のサービスへの外部アクセスを管理し、通常はHTTPおよびHTTPSを扱います。ルーティング、ロードバランシング、SSL終端を提供します。

一般的なネットワーキング問題とデバッグ戦略

1. ポッド間通信障害

ポッドが同じ名前空間内であっても相互に通信できない場合、それはネットワーキング問題の主要な指標です。

症状:

  • 接続タイムアウトまたは拒否を示すアプリケーションエラー。
  • あるポッドから別のポッドへのcurlまたはpingコマンドが失敗する。

デバッグ手順:

  1. ポッドIPの確認: 送信元と宛先の両方のポッドに有効なIPアドレスがあることを確認します。kubectl exec <pod-name> -- ip addrを使用します。
  2. ネットワーク接続の確認(ポッド内): 送信元ポッドから、宛先ポッドのIPアドレスにpingを試みます。これが失敗する場合、問題はCNIプラグインまたはノードネットワーキングにある可能性があります。
    kubectl exec <source-pod-name> -- ping <destination-pod-ip>
    
  3. ネットワークポリシーの検査: ネットワークポリシーは一般的な原因です。ポッド間のトラフィックを誤ってブロックしているポリシーがないか確認します。
    kubectl get networkpolicies -n <namespace>
    
    podSelectoringress/egressルールを調べて、許可または拒否されるトラフィックを理解します。ポッドがingressポリシーによって選択されると、明示的に許可されたingressトラフィックのみが許可されます。
  4. CNIプラグインのステータス: コンテナネットワークインターフェース(CNI)プラグイン(例:Calico、Flannel、Cilium)がすべてのノードで正しく実行されていることを確認します。CNIデーモンセットポッドのログを確認します。
    kubectl get pods -n kube-system -l k8s-app=<cni-plugin-label>
    kubectl logs <cni-plugin-pod-name> -n kube-system
    

2. サービスディスカバリの問題

ポッドがDNS名またはクラスターIPで他のサービスに到達できない場合、Kubernetes DNSまたはServiceオブジェクトの設定に問題があることを示します。

症状:

  • Name or service not knownのようなアプリケーションエラー。
  • ポッド内のnslookupまたはdigコマンドがサービス名を解決できない。

デバッグ手順:

  1. DNS解決の確認: ポッドから、既知のサービスのDNS解決をテストします。
    kubectl exec <pod-name> -- nslookup <service-name>.<namespace>.svc.cluster.local
    
    これが失敗する場合、CoreDNSポッドのエラーを確認します。
    kubectl get pods -n kube-system -l k8s-app=kube-dns
    kubectl logs <coredns-pod-name> -n kube-system
    
  2. Serviceオブジェクトの確認: Serviceオブジェクトが正しく設定され、正常なポッドを指すエンドポイントがあることを確認します。
    kubectl get service <service-name> -n <namespace> -o yaml
    kubectl get endpoints <service-name> -n <namespace>
    
    endpointsの出力には、サービスをバックアップするポッドのIPアドレスがリストされている必要があります。
  3. ポッドのReadiness Probe: ポッドがReadiness Probeに合格していない場合、それらはServiceのエンドポイントに追加されません。Readiness Probeの設定とポッドログに問題がないか確認します。

3. Ingressコントローラーの問題

サービスへの外部アクセスは、IngressリソースとIngressコントローラーによって管理されます。ここでの問題により、アプリケーションがクラスターの外部からアクセスできなくなる可能性があります。

症状:

  • 外部URLを介してアプリケーションにアクセスする際の502 Bad Gateway404 Not Found、または503 Service Unavailableエラー。
  • Ingressコントローラーのログに、バックエンドサービスに関連するエラーが表示される。

デバッグ手順:

  1. Ingressコントローラーポッドの確認: Ingressコントローラーポッド(例:Nginx Ingress、Traefik)が実行され、正常であることを確認します。
    kubectl get pods -l app.kubernetes.io/component=controller # 使用しているIngressコントローラーに基づいてラベルを調整
    kubectl logs <ingress-controller-pod-name> -n <ingress-namespace>
    
  2. Ingressリソースの確認: Ingressリソースの設定を確認します。
    kubectl get ingress <ingress-name> -n <namespace> -o yaml
    
    rulesセクションがホスト名とパスを適切なservice.nameservice.portにマッピングしていることを確認します。
  3. Serviceとエンドポイントの確認: サービスディスカバリと同様に、Ingressが指すバックエンドサービスが正しく設定され、正常なエンドポイントがあることを確認します。
    kubectl get service <backend-service-name> -n <namespace>
    kubectl get endpoints <backend-service-name> -n <namespace>
    
  4. ファイアウォールとロードバランサー: クラスターの外部からアクセスする場合、外部ファイアウォールやクラウドプロバイダーのロードバランサーが、Ingressコントローラーのサービス(多くの場合LoadBalancerタイプのサービス)にトラフィックを転送するように正しく設定されていることを確認します。

4. ネットワークポリシーの適用

ネットワークポリシーは強力ですが、誤って設定すると接続の問題の原因になる可能性があります。これらは最小権限の原則で動作します。ポリシーが明示的にトラフィックを許可しない場合、それは拒否されます。

デバッグ手順:

  1. 適用されたポリシーの特定: 問題のポッドに影響を与えるネットワークポリシーを特定します。
    kubectl get networkpolicy -n <namespace>
    
  2. ポリシーセレクターの検査: 関連する各NetworkPolicyのpodSelectorを注意深く調べます。このセレクターは、ポリシーが適用されるポッドを決定します。ポッドが複数のポリシーによって選択されている場合、許可されるトラフィックはそれらのポリシールールの和集合であり、最も制限の厳しい単一のルールではありません。
  3. Ingress/Egressルールの確認: ネットワークポリシーのingressおよびegressセクションを分析します。ポッドAからポッドBへの接続を確立しようとしている場合、以下を確認する必要があります:
    • ポッドBに適用されるネットワークポリシーが、ポッドAからのingressトラフィックを許可している(またはポッドAを含むより広いラベルセレクター)。
    • ポッドAに適用されるネットワークポリシーが、ポッドBへのegressトラフィックを許可している(またはポッドBを含むより広いラベルセレクター)。
  4. 全許可ポリシーでのテスト: 一時的なトラブルシューティング手順として、特定のポッドまたは名前空間へのすべてのトラフィックを許可するネットワークポリシーを作成し、接続が復元されるかどうかを確認できます。これにより、問題が実際にネットワークポリシーにあるかどうかを切り分けるのに役立ちます。
    # 例:ラベルapp=my-appを持つポッドへのすべてのingressとegressを許可
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-for-my-app
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: my-app
      policyTypes:
      - Ingress
      - Egress
      ingress:
        - {}
      egress:
        - {}
    
    警告: このallow-allポリシーは一時的なデバッグにのみ使用してください。テストが終了したらすぐに削除してください。

必須ツールとコマンド

  • kubectl exec:ポッド内でコマンドを実行します(例:pingcurlnslookup)。
  • kubectl logs:ポッドのログを表示します。特にコントロールプレーンコンポーネントやネットワークプラグインに役立ちます。
  • kubectl describe:ポッド、サービス、ingress、ネットワークポリシーに関する詳細情報を取得します。これにより、ステータスやイベントが明らかになることがよくあります。
  • kubectl get:リソースとその基本ステータスを一覧表示します。
  • tcpdump:強力なコマンドラインパケットアナライザー。ポッド内またはノード上で実行してネットワークトラフィックをキャプチャできます。
    # 例:ポッド内のeth0インターフェースでポート80のトラフィックをキャプチャ
    kubectl exec <pod-name> -- tcpdump -i eth0 -nn port 80
    

まとめ

Kubernetesネットワーキングを内部から外部に向かってデバッグします。最初にポッドIP接続を証明し、次にServiceエンドポイント、DNS、NetworkPolicy、最後にIngressまたは外部ロードバランサーの動作を確認します。この順序により、Serviceに準備完了のエンドポイントがないときにIngressの症状を追いかけることを防げます。