- Authors
- Name
- 1. Docker ネットワーキングモデル
- 2. Kubernetes ネットワーキングモデルと CNI
- 3. Pod間通信のデバッグ
- 4. Pod-to-Service 通信のデバッグ
- 5. Service DNS 解決の問題
- 6. 外部通信のデバッグ
- 7. Network Policy のデバッグ
- 8. Calico トラブルシューティング
- 9. Cilium トラブルシューティング
- 10. Debug コンテナとエフェメラルコンテナ
- 11. 実践デバッグシナリオ
- 12. デバッグチェックリスト
1. Docker ネットワーキングモデル
コンテナネットワークデバッグの基礎は、Dockerが提供するネットワーキングモデルを正確に理解することから始まります。
1.1 Bridge ネットワーク
Dockerのデフォルトのネットワークドライバです。各コンテナは docker0 ブリッジに接続された仮想イーサネット(veth)インターフェースを割り当てられます。
# ブリッジネットワークの詳細確認
docker network inspect bridge
# コンテナのIPアドレス確認
docker inspect --format '{{.NetworkSettings.IPAddress}}' <container_id>
# vethペア確認
ip link show type veth
# docker0に接続されたインターフェース確認
brctl show docker0
ブリッジネットワークでよく発生する問題は以下の通りです。
- コンテナ間通信不可: 同じブリッジネットワークに接続されているか確認
- 外部通信不可: iptables NAT ルールと IP フォワーディング設定を確認
- ポート競合: ホストポートバインディングの重複を確認
# iptables NATルール確認
sudo iptables -t nat -L -n -v
# IPフォワーディング状態確認
cat /proc/sys/net/ipv4/ip_forward
# ポートバインディング確認
docker port <container_id>
1.2 Host ネットワーク
コンテナがホストのネットワークスタックを直接使用します。ネットワーク分離がないためパフォーマンスは向上しますが、ポート競合のリスクがあります。
# hostモードでコンテナを実行
docker run --network host nginx
# コンテナ内部でネットワークインターフェース確認
docker exec <container_id> ip addr show
# ホストと同じネットワークスタックを使用していることを確認
docker exec <container_id> ss -tlnp
1.3 Overlay ネットワーク
複数のDockerホストにまたがるコンテナ間通信を可能にします。Docker Swarm や外部キーバリューストアが必要です。
# overlayネットワーク作成
docker network create --driver overlay my-overlay
# VXLANトンネル状態確認
ip -d link show type vxlan
# overlayネットワークのピア情報確認
docker network inspect my-overlay --format '{{json .Peers}}'
overlay ネットワークのデバッグ時に注意すべき点は以下の通りです。
- VXLANポート(UDP 4789)がファイアウォールで許可されているか確認
- MTU設定がVXLANオーバーヘッド(50バイト)を考慮しているか確認
- ノード間の時刻同期状態を確認
2. Kubernetes ネットワーキングモデルと CNI
2.1 Kubernetes ネットワーキングの基本原則
Kubernetes ネットワーキングモデルは3つの基本原則に従います。
- すべてのPodはNATなしで他のすべてのPodと通信できなければならない
- すべてのノードはNATなしですべてのPodと通信できなければならない
- PodがI自身のIPとして認識するアドレスが、他のPodから見えるアドレスと同じでなければならない
# クラスタネットワークCIDR確認
kubectl cluster-info dump | grep -m 1 cluster-cidr
# ノードのPod CIDR確認
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'
# 使用中のCNIプラグイン確認
ls /etc/cni/net.d/
cat /etc/cni/net.d/*.conflist
2.2 CNI プラグインの理解
CNI(Container Network Interface)はコンテナのネットワークインターフェースを構成する標準です。
# CNIバイナリの場所確認
ls /opt/cni/bin/
# CNI設定ファイル確認
cat /etc/cni/net.d/10-calico.conflist
# kubeletのCNI関連ログ確認
journalctl -u kubelet | grep -i cni
主要なCNIプラグインの比較は以下の通りです。
| CNI プラグイン | データプレーン | Network Policy | 特徴 |
|---|---|---|---|
| Calico | iptables/eBPF | 対応 | BGPベースのルーティング |
| Cilium | eBPF | 対応 | L7ポリシー、Hubble観測 |
| Flannel | VXLAN/host-gw | 非対応 | シンプルな設定 |
| Weave | VXLAN | 対応 | 自動メッシュネットワーク |
3. Pod間通信のデバッグ
3.1 同一ノード内のPod間通信
# Pod IP確認
kubectl get pods -o wide
# PodからPodへのping テスト
kubectl exec -it <pod-a> -- ping <pod-b-ip>
# 同一ノードのPod間のルート確認
kubectl exec -it <pod-a> -- traceroute <pod-b-ip>
# ノードのvethインターフェース確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- ip link show
3.2 異なるノードのPod間通信
# ノードのルーティングテーブル確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- route -n
# VXLANまたはIPIPトンネル状態確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- ip tunnel show
# tcpdumpでパケットキャプチャ
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \
tcpdump -i any -nn host <target-pod-ip>
# MTU問題確認(Path MTU Discovery)
kubectl exec -it <pod> -- ping -M do -s 1400 <target-pod-ip>
ノード間通信の問題の主な原因は以下の通りです。
- クラウドセキュリティグループでPod CIDRトラフィックがブロックされている
- MTU不一致によるパケットフラグメンテーション
- ノード間のルーティングテーブル不整合
- IPIP/VXLANトンネルインターフェースのダウン
4. Pod-to-Service 通信のデバッグ
4.1 Service の基本動作確認
# ServiceのClusterIPとEndpoints確認
kubectl get svc <service-name> -o wide
kubectl get endpoints <service-name>
# Endpointsの詳細確認
kubectl get endpoints <service-name> -o yaml
# Serviceへの接続テスト
kubectl exec -it <test-pod> -- curl -v http://<service-name>:<port>
# Service selectorにマッチするPod確認
kubectl get pods -l <label-selector>
4.2 kube-proxy と iptables/IPVS ルール
kube-proxy はServiceの仮想IPを実際のPod IPに変換する役割を持ちます。
# kube-proxyモード確認
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
# iptablesモード: Service関連iptablesルール確認
sudo iptables -t nat -L KUBE-SERVICES -n
sudo iptables -t nat -L KUBE-SVC-<hash> -n
sudo iptables -t nat -L KUBE-SEP-<hash> -n
# IPVSモード: 仮想サーバ一覧確認
sudo ipvsadm -Ln
sudo ipvsadm -Ln -t <cluster-ip>:<port>
# kube-proxyログ確認
kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=100
iptablesルールの分析ではチェインの流れを理解する必要があります。
PREROUTING -> KUBE-SERVICES -> KUBE-SVC-xxx -> KUBE-SEP-xxx (DNAT)
# 特定Serviceの完全なiptablesチェイン追跡
SERVICE_IP=$(kubectl get svc <service-name> -o jsonpath='{.spec.clusterIP}')
sudo iptables -t nat -L KUBE-SERVICES -n | grep $SERVICE_IP
# conntrackテーブルでService接続追跡
sudo conntrack -L -d $SERVICE_IP
5. Service DNS 解決の問題
5.1 CoreDNS の動作確認
Kubernetesクラスタ内部のDNSはCoreDNSが担当します。
# CoreDNS Pod状態確認
kubectl get pods -n kube-system -l k8s-app=kube-dns
# CoreDNS設定確認
kubectl get configmap coredns -n kube-system -o yaml
# DNS解決テスト
kubectl exec -it <test-pod> -- nslookup <service-name>
kubectl exec -it <test-pod> -- nslookup <service-name>.<namespace>.svc.cluster.local
# DNS応答時間計測
kubectl exec -it <test-pod> -- dig <service-name>.default.svc.cluster.local +stats
5.2 DNS 問題の診断
# PodのDNS設定確認
kubectl exec -it <pod> -- cat /etc/resolv.conf
# CoreDNSログでエラー確認
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=200
# DNSデバッグ用Pod配置
kubectl run dnsutils --image=gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 \
--restart=Never -- sleep 3600
# 外部ドメイン解決テスト
kubectl exec -it dnsutils -- nslookup google.com
kubectl exec -it dnsutils -- nslookup kubernetes.default
よく発生するDNS問題と解決策は以下の通りです。
- ndots設定:
resolv.confの ndots:5 設定により、短い名前に対して複数回DNSクエリが発生します。FQDN(末尾に.を含む)を使用すれば解決します。 - CoreDNS CrashLoopBackOff: ログを確認し、アップストリームDNSサーバの接続状態を点検します。
- DNSキャッシュ問題: CoreDNS の cache プラグイン設定を確認します。
# ndots問題の確認: クエリ回数比較
kubectl exec -it <pod> -- dig myservice.default.svc.cluster.local +search +showsearch
kubectl exec -it <pod> -- dig myservice.default.svc.cluster.local. +search +showsearch
6. 外部通信のデバッグ
6.1 Ingress / LoadBalancer の問題
# Ingressリソース状態確認
kubectl get ingress -A
kubectl describe ingress <ingress-name>
# Ingress Controllerログ確認
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=100
# LoadBalancer ServiceのExternal IP確認
kubectl get svc -l type=LoadBalancer
# NodePortを通じた外部アクセステスト
curl -v http://<node-ip>:<node-port>
6.2 Egress トラフィックのデバッグ
# Podから外部へのトラフィック確認
kubectl exec -it <pod> -- curl -v https://httpbin.org/ip
# NATゲートウェイとルーティング確認
kubectl exec -it <pod> -- traceroute 8.8.8.8
# SNATルール確認
sudo iptables -t nat -L POSTROUTING -n -v
7. Network Policy のデバッグ
7.1 Network Policy の基本診断
# 適用されたNetwork Policy確認
kubectl get networkpolicy -A
kubectl describe networkpolicy <policy-name> -n <namespace>
# 特定Podに適用されるNetwork Policy確認
kubectl get networkpolicy -n <namespace> -o json | \
jq '.items[] | select(.spec.podSelector.matchLabels | to_entries[] |
.key == "app" and .value == "myapp")'
# Network Policy適用前後の接続テスト
kubectl exec -it <source-pod> -- nc -zv <target-pod-ip> <port>
7.2 Network Policy トラブルシューティングパターン
# すべてのトラフィックを遮断するデフォルトポリシー
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# ポリシー適用後の通信テスト
kubectl exec -it <pod> -- wget -qO- --timeout=2 http://<target-service>
# CNI別Network Policyログ確認
# Calico
kubectl logs -n calico-system -l k8s-app=calico-node --tail=100
# Cilium
kubectl exec -n kube-system <cilium-pod> -- cilium policy get
kubectl exec -n kube-system <cilium-pod> -- cilium endpoint list
8. Calico トラブルシューティング
8.1 Calico 状態確認
# Calicoノードの健全性確認
kubectl get pods -n calico-system
calicoctl node status
# BGPピア状態確認
calicoctl get bgpPeer
calicoctl node status | grep -A 5 "BGP"
# IPプール確認
calicoctl get ippool -o wide
# Calico固有のネットワークポリシー確認
calicoctl get networkpolicy -A
calicoctl get globalnetworkpolicy
8.2 Calico デバッグ
# Felixのログレベル変更(デバッグ時)
calicoctl patch felixconfiguration default \
--patch '{"spec":{"logSeverityScreen":"Debug"}}'
# BIRDルーティングデーモン状態確認
kubectl exec -n calico-system <calico-node-pod> -- birdcl show route
# IP-in-IPトンネル状態確認
kubectl exec -n calico-system <calico-node-pod> -- ip tunnel show
# Calicoがプログラムしたiptablesルール確認
sudo iptables -L -n | grep cali
9. Cilium トラブルシューティング
9.1 Cilium 状態確認
# Ciliumエージェントの詳細状態確認
kubectl exec -n kube-system <cilium-pod> -- cilium status --verbose
# Ciliumエンドポイント一覧
kubectl exec -n kube-system <cilium-pod> -- cilium endpoint list
# BPFマップ状態確認
kubectl exec -n kube-system <cilium-pod> -- cilium bpf lb list
kubectl exec -n kube-system <cilium-pod> -- cilium bpf ct list global
# Hubbleでネットワークフロー観察
hubble observe --namespace <namespace>
hubble observe --pod <pod-name> --protocol TCP
9.2 Cilium デバッグ
# Cilium接続性テスト
kubectl exec -n kube-system <cilium-pod> -- cilium connectivity test
# eBPFプログラム状態確認
kubectl exec -n kube-system <cilium-pod> -- cilium bpf prog list
# ポリシートレーシング
kubectl exec -n kube-system <cilium-pod> -- cilium policy trace \
--src-k8s-pod <namespace>:<src-pod> \
--dst-k8s-pod <namespace>:<dst-pod> \
--dport <port>
# リアルタイムイベントモニタリング
kubectl exec -n kube-system <cilium-pod> -- cilium monitor --type drop
kubectl exec -n kube-system <cilium-pod> -- cilium monitor --type policy-verdict
10. Debug コンテナとエフェメラルコンテナ
10.1 kubectl debug の活用
# 実行中のPodにデバッグコンテナをアタッチ
kubectl debug -it <pod-name> --image=nicolaka/netshoot --target=<container-name>
# ノードレベルのデバッグ
kubectl debug node/<node-name> -it --image=ubuntu
# Podのコピーを作成してデバッグ(原本に影響なし)
kubectl debug <pod-name> -it --copy-to=debug-pod --image=nicolaka/netshoot
# プロセス名前空間を共有するデバッグコンテナ
kubectl debug -it <pod-name> --image=busybox --share-processes
10.2 netshoot を使ったネットワークデバッグ
# netshootコンテナの配置
kubectl run netshoot --image=nicolaka/netshoot --restart=Never -- sleep 3600
# コンテナに入って総合的なネットワーク診断
kubectl exec -it netshoot -- bash
# 内部で実行するコマンド:
# TCP接続テスト
nc -zv <service-ip> <port>
# HTTPリクエストテスト
curl -v http://<service-name>.<namespace>.svc.cluster.local:<port>/health
# DNS検索
dig +short <service-name>.<namespace>.svc.cluster.local
# パケットキャプチャ
tcpdump -i eth0 -nn port 80
# ネットワーク経路追跡
mtr <target-ip>
# SSL/TLS接続確認
openssl s_client -connect <service-ip>:443
11. 実践デバッグシナリオ
シナリオ 1: Pod が Service にアクセスできない場合
# ステップ1: ServiceとEndpoints確認
kubectl get svc <service-name> -o yaml
kubectl get endpoints <service-name>
# ステップ2: Endpointsが空の場合 -> selector確認
kubectl get pods -l <label-selector> --show-labels
# ステップ3: PodがReady状態か確認
kubectl get pods -l <label-selector> -o wide
kubectl describe pod <target-pod> | grep -A 5 "Conditions"
# ステップ4: kube-proxyルール確認
sudo iptables -t nat -L KUBE-SERVICES -n | grep <cluster-ip>
# ステップ5: Pod IPへ直接アクセステスト
kubectl exec -it <source-pod> -- curl -v http://<pod-ip>:<target-port>
シナリオ 2: 間欠的なタイムアウトの発生
# ステップ1: conntrackテーブル飽和確認
sudo sysctl net.netfilter.nf_conntrack_count
sudo sysctl net.netfilter.nf_conntrack_max
# ステップ2: パケットドロップ確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \
netstat -s | grep -i drop
# ステップ3: ネットワークインターフェースエラー確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \
ip -s link show
# ステップ4: TCP再送確認
kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \
netstat -s | grep -i retrans
シナリオ 3: DNS 解決が遅い場合
# ステップ1: DNS応答時間計測
kubectl exec -it <pod> -- dig <service-name>.default.svc.cluster.local +stats | grep "Query time"
# ステップ2: CoreDNS Podリソース使用量確認
kubectl top pods -n kube-system -l k8s-app=kube-dns
# ステップ3: ndots最適化適用
# Pod specに以下を追加:
# dnsConfig:
# options:
# - name: ndots
# value: "2"
# ステップ4: CoreDNSキャッシュヒット率確認
kubectl exec -n kube-system <coredns-pod> -- \
wget -qO- http://localhost:9153/metrics | grep coredns_cache
12. デバッグチェックリスト
ネットワーク問題を体系的にアプローチするためのチェックリストです。
[ ] Pod状態確認(Running、Ready)
[ ] Service Endpoints確認(空でないこと)
[ ] DNS解決確認(nslookup/dig)
[ ] Pod IPへの直接接続テスト
[ ] kube-proxyルール確認(iptables/IPVS)
[ ] Network Policy確認(Ingress/Egressルール)
[ ] CNIプラグイン健全性確認
[ ] ノード間ネットワーク接続確認
[ ] MTU設定確認
[ ] ファイアウォール/セキュリティグループルール確認
[ ] conntrackテーブル状態確認
[ ] CoreDNS状態とログ確認
ネットワークデバッグはレイヤーごとにアプローチするのが最も効果的です。L2(イーサネット)-> L3(IP/ルーティング)-> L4(TCP/UDP)-> L7(HTTP/DNS)の順序で各レイヤーに問題がないか確認すれば、複雑なネットワーク問題も体系的に解決できます。