Là người thích viết và chia sẻ cũng là người thích đọc các bài kiến thức, thói quen đã giúp tôi rất nhiều để thêm góc nhìn/kinh nghiệm trong công việc. Mọi người theo dõi cũng thấy các tác giả trên DevOps VietNam chia sẻ rất hữu ích, tôi đọc và học hỏi có thể thấy sự tâm huyết và những kinh nghiệm thực tế giá trị.
Trình đến đâu nói đến đấy, tôi cũng xin chia sẻ một trong những kinh nghiệm có thể nói là tới giới hạn của tôi về kubernetes, cũng chẳng che dấu gì. Điều này sẽ giúp cho anh em tiết kiệm thời gian nếu như gặp phải vấn đề về networking trong kubernetes.

Trong sự nghiệp, tôi cũng debug nhiều cluster Kubernetes, từ staging nhỏ đến production vài trăm Pod. Có một pattern lặp lại gần như chắc chắn, mọi người thường blame overlay network (VXLAN/Geneve) nhưng thực tế phần lớn latency spike đến từ nf_conntrack, cụ thể là table full hoặc hash collision làm Kernel lookup chậm và drop packet khó nhận ra.
Overlay network hiếm khi làm P99 latency tăng gấp 3, gấp 5 lần
Overlay thêm encapsulation -> đúng, có overhead. VXLAN, Geneve tăng header size, thêm lookup, throughput giảm 5-15% là bình thường.
Nhưng nếu chỉ là overlay overhead, baseline latency chỉ tăng nhẹ và ổn định, không spike dựng đứng.
Khi P99 tăng đột ngột theo dạng vọt lên – rơi xuống, cluster thường đang gặp bottleneck ở nf_conntrack, không phải network overlay.
Conntrack hoạt động thế nào?
Để NAT, Load Balancer và Service routing, Kubernetes dựa vào iptables/nftables. Kernel phải track connection state trong nf_conntrack table.
Lookup key =
(src_ip, src_port, dst_ip, dst_port, protocol)
Nếu table thoáng -> lookup O(1).
Nếu table gần full hoặc hash bucket quá hẹp:
- collision
- Kernel phải scan bucket linked-list
- tăng latency theo bậc
- drop packet trong im lặng
Không có log rõ ràng, không có alert mặc định -> dễ đổ lỗi nhầm overlay.
Khi nào conntrack full?
Case 1: Replica scale nhiều nhưng nf_conntrack_max vẫn default
Ubuntu/Containerd trên nhiều distro default:
net.netfilter.nf_conntrack_max = 262144
Với cluster vài nghìn Pod -> con số này không đủ.
Case 2: Traffic spike và conntrack giữ entry quá lâu
Spike 2 phút nhưng conntrack entry timeout 60 phút -> table vẫn đầy.
Case 3: Long-lived TCP như gRPC / HTTP/2 giữ slot liên tục
Connection ít nhưng không expire -> waste capacity.
Case 4: UDP-heavy workload (DNS, metric agent, telemetry)
UDP không ESTABLISHED -> churn table nhanh hơn TCP.
Hash collision: Nguyên nhân làm latency tăng kiểu dựng đứng
Ngay cả khi conntrack_count chưa full, hashsize nhỏ khiến nhiều flow chung bucket. Ví dụ bucket distribution:
| Bucket | Entry count |
|---|---|
| #1234 | 3.244 |
| #512 | 2 |
| #8700 | 0 |
Một bucket 3.244 entry = MỖI LOOKUP phải scan. Chỉ cần vài ms thêm ở Kernel -> P99 nhảy điên cuồng.
Latency spike kiểu “cắm ngược cây tre lên chart” là dấu hiệu hash collision.
Cách detect conntrack bottleneck
Check usage
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
If count / max > 0.7 -> Critical.
Check drop
dmesg | grep -i conntrack
grep nf_conntrack /var/log/kern.log
Chỉ cần một dòng “table full” = bottleneck confirmed.
Check hash distribution
conntrack -S
Bucket lệch mạnh = hash collision.
Fix thực tế
1. Tăng conntrack_max theo Pod x connection per Pod
Ví dụ cluster vài trăm Pod (khoảng 500 Pod):
sysctl -w net.netfilter.nf_conntrack_max=500000
Rule sizing dễ áp dụng:
nf_conntrack_max ≈ pods × avg_conn_per_pod × 1.5
2. Tăng hashsize để giảm collision
echo 524288 > /sys/module/nf_conntrack/parameters/hashsize
Set trong sysctl.d hoặc KubeletExtraArgs để apply qua node restart.
3. Dùng IPVS mode với autoscale conntrack
--conntrack-min=131072
--conntrack-max-per-core=32768
4. Shorten idle timeout nếu workload short-lived
net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
net.netfilter.nf_conntrack_tcp_timeout_established=600
Evict nhanh entry cũ -> tránh nghẽn table.
5. Theo dõi real-time
watch -n1 'conntrack -S'
Nếu bucket spike -> latency P99 sẽ tăng sau 2-10s.
Kết luận
Với kinh nghiệm của tôi thì các vấn đề lỗi mạng trong Kubernetes hiếm khi nằm ở Overhead cố định của Overlay Network. Mà thường (chắc phải tới 90%) các Latency Spike đột ngột, khó giải thích và không theo quy luật đều bắt nguồn từ saturation của nf_conntrack table trong Kernel Connection Tracking.
nf_conntrack full và Hash Collision chính là gót chân Achilles của Kube-proxy/Iptables, gây ra Drop Packet thầm lặng và tăng P99 non-linear. Đây là một Bottleneck mà mọi SRE vận hành Production Cluster đều phải nắm vững.
Nên là thay vì tốn thời gian debug CNI, hãy áp dụng thử quy tắc sizing: Tăng nf_conntrack_max, tăng hashsize, và thiết lập Timeout hợp lý nhé 😀








