Cilium và eBPF: vì sao thay kube-proxy

K
Kai··5 min read

Part I dựng mạng pod "đủ dùng": kube-proxy chế độ iptables (Bài 12) định tuyến Service, một bridge cni0 + host-local IPAM (Bài 14) nối pod. Nó chạy — nhưng là cách làm cũ, và có giới hạn. Part X nâng cấp toàn bộ tầng mạng sang Cilium dựa eBPF: thay cả kube-proxy lẫn bridge. Bài này là phần lý thuyết — phải hiểu vì sao trước khi migrate (Bài 46). Và để không nói suông, ta soi thẳng cái datapath iptables đang chạy trên cụm — thứ sắp bị thay.

Datapath hiện tại: iptables phình tuyến tính

kube-proxy chế độ iptables (Bài 12) dịch mỗi Service ClusterIP thành một chuỗi rule nat. Đếm trên worker-0:

ssh worker-0 'sudo iptables -t nat -L KUBE-SERVICES | head; sudo iptables -t nat -S | wc -l'
Chain KUBE-SERVICES
KUBE-SVC-...  tcp -- ... 10.32.0.10 ... kube-dns:dns-tcp cluster IP
KUBE-SVC-...  tcp -- ... 10.32.0.90 ... metrics-server:https cluster IP
KUBE-SVC-...  tcp -- ... 10.32.0.1  ... kubernetes:https cluster IP
...
74          # tổng số rule trong bảng nat

Mới vài Service (kube-dns, metrics-server, kubernetes) mà bảng nat đã 74 rule. Vấn đề cốt lõi: iptables xử lý packet bằng cách duyệt chuỗi rule tuần tự — độ phức tạp O(n) theo số rule. Cụm thật hàng nghìn Service → hàng chục nghìn rule → mỗi packet phải đi qua một danh sách dài; cập nhật một Service phải viết lại cả bảng (kube-proxy khóa, tái tạo). Ở quy mô lớn, đây là nút thắt cả về độ trễ lẫn thời gian hội tụ. (Chế độ ipvs đỡ hơn nhưng vẫn là kiến trúc cũ.) Đó là động lực đổi.

eBPF là gì

eBPF (extended Berkeley Packet Filter) là công nghệ trong nhân Linux cho phép chạy chương trình sandbox ngay trong kernel mà không sửa mã nguồn kernel hay nạp module. Tài liệu Cilium gọi nó là "a new Linux kernel technology" enabling "the dynamic insertion of powerful security visibility and control logic within Linux itself." Cụ thể: bạn nạp một đoạn bytecode eBPF, kernel kiểm tra an toàn (verifier — không vòng lặp vô hạn, không truy cập bộ nhớ bậy), rồi gắn nó vào một hook point — ví dụ ngay khi packet vừa tới card mạng (XDP), hay tại socket, tại tc (traffic control). Khi packet chạm hook, chương trình eBPF chạy trong kernel, quyết định ngay: chuyển tiếp, đổi đích (DNAT), thả, hay thu thập số liệu.

Hai điểm khiến eBPF mạnh cho mạng:

  1. Hash map thay vì chuỗi rule. eBPF dùng bản đồ (map) tra cứu O(1) — thay vì duyệt 74 rule, nó tra "ClusterIP này → backend nào" trong một hash map một bước. Số Service tăng không làm chậm mỗi packet.
  2. Bỏ qua phần lớn network stack. Với XDP, eBPF xử lý packet trước khi kernel dựng sk_buff đầy đủ và trước iptables — cắt cả tầng. Tài liệu: visibility/datapath là "programmable ... minimizes overhead."

Kernel của cụm đủ mới để chạy eBPF đầy đủ:

ssh worker-0 'uname -r'      # 6.17.0-1015-aws

Cilium làm gì khác

Cilium là CNI (như bridge ở Bài 14) cộng thay thế kube-proxy (Bài 12) — tất cả trên eBPF. Tài liệu: "open source software for transparently securing the network connectivity between application services." Bốn thứ Cilium đổi so với cách dựng tay của ta:

  • Thay kube-proxy (kube-proxy replacement). Cilium cài chương trình eBPF làm việc của kube-proxy — DNAT ClusterIP → pod backend — bằng hash map trong kernel. Sau migrate, ta gỡ hẳn kube-proxy và 74 rule iptables kia biến mất. Tài liệu: load balancing east-west "fully replacing kube-proxy."
  • Datapath pod thay bridge. Cilium tự lo nối pod (thay cni0 + host-local của Bài 14), định tuyến giữa node bằng eBPF (hoặc tunnel, hoặc native routing — ta sẽ chọn native như Bài 13).
  • Bảo mật theo identity, không theo IP. Đây là điểm tinh tế: IP pod thay đổi xoành xoạch (Bài 25). Cilium gán mỗi nhóm pod (theo label) một identity số, và policy áp theo identity — "Rather than relying on IP addresses that frequently churn ... Cilium operates on service identity." NetworkPolicy (Bài 47) nhờ vậy bền hơn và mở rộng được tới L7 (HTTP path, gRPC method), không chỉ L3/L4.
  • Quan sát được (Hubble). Vì datapath là eBPF, Cilium thấy mọi flow ngay trong kernel → Hubble cho ta xem luồng mạng, drop, policy verdict thời gian thực — thứ iptables không cho.
   TRƯỚC (Part I)                          SAU (Part X, Cilium eBPF)
   ─────────────                           ──────────────────────────
   kube-proxy ── viết 74+ iptables rule    eBPF program tại tc/XDP hook
       │  packet duyệt chuỗi O(n)              │  tra hash map O(1), trong kernel
   cni0 bridge + host-local IPAM           Cilium CNI (eBPF datapath)
   policy theo IP (rời rạc)                policy theo IDENTITY (L3-L7)
   gần như mù (chỉ tcpdump)                Hubble: thấy mọi flow/verdict

Vì sao "kube-proxy-less"

Mục tiêu migrate (Bài 46) là chạy Cilium kube-proxy replacement hoàn toàn — gỡ luôn DaemonSet kube-proxy. Lợi: một datapath duy nhất (eBPF) thay vì hai lớp (iptables của kube-proxy + CNI), ít overhead, hội tụ nhanh, và mở khóa các tính năng L7/observability. Cái giá: phụ thuộc kernel đủ mới (ta có 6.17, thừa) và một CNI phức tạp hơn để vận hành. Với cụm học/throwaway thì đây đúng là lúc thử. Ta sẽ ghim Cilium 1.19 và bật kubeProxyReplacement=true + Hubble.

🧹 Dọn dẹp

Bài lý thuyết — không tạo gì trên cụm (chỉ đọc iptables hiện có). Cụm giữ nguyên: CoreDNS + metrics-server + ebs-csi + snapshot-controller, kube-proxy vẫn đang chạy (sẽ gỡ ở Bài 46). Không có gì để dọn.

Tổng kết

Mạng Part I (kube-proxy iptables + bridge thủ công) chạy được nhưng cũ: iptables xử lý packet O(n) theo số rule (ta đếm được 74 rule chỉ với vài Service), cập nhật phải viết lại bảng — nút thắt ở quy mô lớn. eBPF chạy bytecode sandbox trong kernel tại các hook (XDP/tc/socket), dùng hash map O(1)bỏ qua phần lớn network stack — nhanh và lập trình được (kernel cụm 6.17 thừa sức). Cilium dùng eBPF để: thay kube-proxy (DNAT bằng hash map), thay bridge (datapath pod), bảo mật theo identity thay IP (bền với pod đổi IP, mở tới L7), và cho Hubble quan sát mọi flow. Đích Part X là cụm Cilium kube-proxy-less — gỡ hẳn kube-proxy.

Bài 46 làm thật: cài Cilium 1.19 với kubeProxyReplacement, gỡ DaemonSet kube-proxy + xóa 74 rule iptables, chuyển datapath pod sang Cilium, bật Hubble — rồi kiểm chứng Service vẫn chạy mà không còn một rule iptables nào của kube-proxy.

Related Posts