อาการ
$ kubectl exec -it pod-a -- ping pod-b-ip
PING 10.244.2.5: 56 data bytes
^C
--- 10.244.2.5 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss
ping ไม่เข้า — แต่ลอง:
$ kubectl exec -it pod-a -- curl http://pod-b:8080/
{"status": "ok"}
HTTP ใช้ได้! ทำไม ping ไม่ได้แต่ HTTP ผ่าน?
สาเหตุที่พบบ่อย
1. CNI plugin block ICMP
CNI บางตัว (เช่น Cilium, Calico ที่ตั้ง strict policy) — block ICMP โดย default แต่อนุญาต TCP/UDP บางตัวผ่าน
ตรวจสอบ:
# ดู CNI ที่ใช้
kubectl get pods -n kube-system | grep -E "calico|cilium|flannel|weave"
2. NetworkPolicy block ICMP
Manifest ที่ allow protocol: TCP อย่างเดียวจะ implicit deny ICMP:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-except-http
spec:
podSelector:
matchLabels:
app: pod-b
ingress:
- from:
- podSelector:
matchLabels:
app: pod-a
ports:
- protocol: TCP
port: 8080
policy นี้ — TCP 8080 ผ่าน, ICMP block หมด
ตรวจสอบ:
kubectl get networkpolicy --all-namespaces
kubectl describe networkpolicy <name> -n <ns>
3. Container image ไม่มี ping command
alpine image base ไม่มี ping ต้องลงเอง:
$ kubectl exec -it pod-a -- ping
sh: ping: not found
ลองเช็ค:
kubectl exec -it pod-a -- which ping
ถ้าไม่มี — ใช้ tool อื่นแทน:
# nc (netcat) ทดสอบ TCP
kubectl exec -it pod-a -- nc -zv pod-b-ip 8080
# wget
kubectl exec -it pod-a -- wget -O- http://pod-b:8080
4. Pod ไม่มี privilege ส่ง raw socket
ICMP ใช้ raw socket — บาง pod รันด้วย user ที่ไม่ใช่ root + ไม่มี CAP_NET_RAW capability ส่ง ping ไม่ได้
ตรวจสอบ securityContext:
kubectl get pod pod-a -o yaml | grep -A 5 securityContext
ถ้าเป็นแบบนี้:
securityContext:
runAsUser: 1000
capabilities:
drop: ["ALL"]
→ ping ไม่ได้แน่นอน (และดีแล้ว — production ควรเป็นแบบนี้)
5. CoreDNS / DNS ปัญหา
$ kubectl exec -it pod-a -- ping pod-b
ping: bad address 'pod-b'
= DNS resolve ไม่ได้ ดู NSLookup / DNS Debug
6. iptables / ipvs rule ผิดปกติ
ตรวจ rule บน node ที่ pod อยู่:
# หา node ของ pod
kubectl get pod pod-b -o wide
# SSH เข้า node แล้ว
sudo iptables -L -n -v | grep -i drop
sudo iptables -t nat -L -n
CNI ใหม่ (Cilium) ใช้ eBPF แทน iptables — ตรวจด้วย:
cilium connectivity test
Debug Flow ที่แนะนำ
Step 1: ทดสอบด้วย tool ที่ไม่ใช้ ICMP
# TCP ทดสอบ port
kubectl exec -it pod-a -- sh -c "nc -zv pod-b 8080"
# DNS ทดสอบ
kubectl exec -it pod-a -- nslookup pod-b
ถ้าทั้งหมดผ่าน → ไม่มีปัญหา network จริง — ICMP block อย่างเดียว
Step 2: ใช้ debug pod
ถ้า image production ไม่มี tool — spin pod ใหม่ที่มี:
kubectl run -it --rm debug --image=nicolaka/netshoot --restart=Never -- bash
netshoot มี: ping, curl, nc, dig, tcpdump, mtr, nslookup, ปอด tool ทุกตัว
# ใน debug pod
ping pod-b.default.svc.cluster.local
curl -v http://pod-b.default.svc.cluster.local:8080
mtr pod-b.default.svc.cluster.local
Step 3: ถ้าจริงๆ network down — ตรวจที่ node
# SSH เข้า node ที่ pod-a อยู่
NODE=$(kubectl get pod pod-a -o jsonpath='{.spec.nodeName}')
# ตรวจ pod's IP routable มั้ย
ssh $NODE
ip route
ping <pod-b-ip> # จาก node
ถ้า node ตรงๆ ก็ ping ไม่เจอ — CNI overlay มีปัญหา
# ตรวจ CNI pod
kubectl get pods -n kube-system -l k8s-app=calico-node
kubectl logs -n kube-system <calico-pod> --previous
Step 4: ดู NetworkPolicy ที่อาจ block
kubectl get networkpolicy --all-namespaces
ลอง delete ชั่วคราว (dev cluster เท่านั้น!) เพื่อ confirm:
kubectl delete networkpolicy deny-all-except-http -n default
# ลอง ping อีกที
ถ้าทำงานได้ → policy block อยู่ — เพิ่ม rule ICMP:
ingress:
- from:
- podSelector:
matchLabels:
app: pod-a
ports:
- protocol: TCP
port: 8080
- from:
- podSelector: {}
# ICMP ไม่มี protocol ใน NetworkPolicy ปกติ ต้องใช้ Cilium / Calico extended
หมายเหตุ: Standard Kubernetes NetworkPolicy v1 รองรับแค่ TCP/UDP/SCTP — ไม่มี ICMP ต้องใช้ Cilium policy หรือ Calico GlobalNetworkPolicy
ตัวอย่าง Calico policy ที่อนุญาต ICMP:
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-icmp
spec:
selector: app == 'pod-b'
ingress:
- action: Allow
protocol: ICMP
เครื่องมือที่ควรมีใน toolbox
| Tool | ใช้ทำอะไร |
|---|---|
| ping | ICMP echo |
| nc -zv | TCP/UDP port check |
| nslookup / dig | DNS query |
| curl -v | HTTP request + verbose |
| mtr | traceroute + ping continuous |
| tcpdump | sniff packet (ต้อง privileged) |
| iperf3 | throughput test |
netshoot image รวมไว้หมด — ตั้งเป็น debug pod ประจำ
เช็คลิสต์ TLDR
1. ลองด้วย nc / curl ก่อน — ไม่ใช่แค่ ping
2. เช็คว่า image มี ping มั้ย (ใช้ netshoot ถ้าไม่มี)
3. ดู NetworkPolicy block ICMP มั้ย
4. ดู securityContext มี CAP_NET_RAW มั้ย
5. ดู CNI plugin (Calico / Cilium) policy
6. SSH เข้า node ทดสอบ ping ตรงๆ
7. ตรวจ CNI pod logs
สรุป
อาการ "ping ไม่ติด แต่ HTTP ใช้ได้" เกือบทั้งหมดไม่ใช่ปัญหา network จริง — เป็น policy block ICMP
อย่าใช้ ping เป็นเครื่องมือ debug หลักใน Kubernetes — nc กับ curl บอกอะไรได้ตรงกว่า
ตั้ง debug pod (netshoot) ไว้ใน cluster ตอนต้องการ debug — เร็วกว่าการลงเครื่องมือใน image production