Cấu hình và cài đặt Cilium qua Helm
Bước đầu tiên là chuẩn bị repository của Cilium để có thể pull các chart mới nhất và định nghĩa các tham số cấu hình cần thiết cho môi trường sản xuất.
Chúng ta cần thêm repository chính thức của Cilium vào Helm client để truy cập các file chart đã được đóng gói sẵn.
Thực hiện lệnh sau để thêm repo và cập nhật danh sách chart:
helm repo add cilium https://helm.cilium.io/
helm repo update
Kết quả mong đợi: Lệnh chạy thành công, không có lỗi, và hiển thị thông báo "helm repo added" cùng với việc update các chart mới nhất.
Để tối ưu hóa hiệu năng và chuẩn bị cho các phần sau của series (Istio, Hubble), chúng ta cần tạo một file cấu hình YAML riêng biệt thay vì gõ nhiều flag trên dòng lệnh.
Tạo file cấu hình tại đường dẫn /tmp/cilium-values.yaml với nội dung đầy đủ dưới đây. File này sẽ bật tính năng eBPF, kích hoạt Hubble (nền tảng quan sát mạng), và cấu hình IPAM để quản lý địa chỉ IP cho Pod.
cat > /tmp/cilium-values.yaml
Kết quả mong đợi: File /tmp/cilium-values.yaml được tạo thành công với toàn bộ nội dung cấu hình.
Sau khi có file cấu hình, ta tiến hành cài đặt Cilium vào namespace cilium của cluster. Namespace này sẽ chứa tất cả các component của Cilium như agent, hubble-relay, hubble-ui.
Thực hiện lệnh cài đặt Helm với tham số giá trị từ file vừa tạo:
helm install cilium cilium/cilium \
--namespace cilium \
--create-namespace \
--values /tmp/cilium-values.yaml \
--wait \
--timeout 5m
Kết quả mong đợi: Lệnh chạy và chờ cho đến khi tất cả Pod của Cilium chuyển sang trạng thái Running. Nếu thành công, terminal sẽ hiển thị thông báo "NAME: cilium" và "STATUS: deployed".
Verify: Kiểm tra trạng thái cài đặt
Để xác nhận Cilium đã được cài đặt đúng và hoạt động, ta kiểm tra trạng thái của các Pod trong namespace cilium.
kubectl get pods -n cilium -o wide
Kết quả mong đợi: Danh sách các Pod bao gồm cilium-xxxxx, hubble-relay-xxxxx, hubble-ui-xxxxx đều có trạng thái Running và RESTARTS bằng 0.
Thêm vào đó, kiểm tra trạng thái node để đảm bảo Cilium đã gắn (attach) vào node thành công:
kubectl get nodes -o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[-1].status
Kết quả mong đợi: Tất cả các node đều có trạng thái Ready.
Kích hoạt và cấu hình Hubble cho quan sát mạng
Hubble là công cụ quan sát mạng (network observability) đi kèm với Cilium, cho phép xem chi tiết luồng giao tiếp (flow) giữa các Pod, DNS query, và các gói tin bị drop.
Trong bước này, chúng ta sẽ kiểm tra xem các service của Hubble đã được expose đúng cách chưa để có thể truy cập UI hoặc truy xuất metric.
Liệt kê các Service trong namespace cilium để xác định endpoint của Hubble UI và Relay:
kubectl get svc -n cilium
Kết quả mong đợi: Xuất hiện các service hubble-ui (thường expose port 80 hoặc 8080) và hubble-relay. Các service này phải có trạng thái ClusterIP.
Để có thể truy cập giao diện Hubble UI từ máy client (local), chúng ta cần tạo một tunnel kết nối từ local machine vào service hubble-ui đang chạy trong cluster.
Sử dụng lệnh port-forward để map port 8080 của service hubble-ui về port 8080 của máy local:
kubectl port-forward svc/hubble-ui 8080:8080 -n cilium
Kết quả mong đợi: Terminal hiển thị thông báo "Forwarding from 127.0.0.1:8080 -> 8080". Lúc này, mở trình duyệt web và truy cập http://localhost:8080, bạn sẽ thấy giao diện Hubble UI. Lưu ý: Cần giữ nguyên terminal này đang chạy để duy trì kết nối.
Verify: Kiểm tra luồng dữ liệu (Flow)
Sau khi Hubble UI đã truy cập được, ta cần tạo một luồng dữ liệu mẫu để kiểm tra khả năng thu thập thông tin.
Chạy một Pod đơn giản để tạo traffic DNS hoặc TCP (sẽ làm chi tiết ở phần tiếp theo), nhưng ngay lúc này ta có thể kiểm tra xem Hubble có đang nhận packet không bằng cách xem logs của hubble-relay:
kubectl logs -n cilium -l name=hubble-relay | grep -i "flow"
Kết quả mong đợi: Nếu có traffic đi qua cluster, bạn sẽ thấy các dòng log chứa thông tin về source IP, destination IP, protocol (TCP/UDP), và action (Allow/Drop) được in ra liên tục.
Cấu hình Network Policy (L3/L4) bằng Cilium
Khác với Kubernetes NetworkPolicy (chỉ hỗ trợ L3/L4 cơ bản), Cilium Network Policy cho phép định nghĩa chính sách chi tiết hơn dựa trên L7 (HTTP methods, paths) và các label đặc thù của Cilium.
Trong phần này, chúng ta sẽ tạo một policy cơ bản ở mức L3/L4 để hạn chế truy cập vào một Pod, minh họa cho việc quản lý lưu lượng nội bộ.
Trước tiên, tạo một ứng dụng mẫu gồm 2 Pod: một Pod "frontend" và một Pod "backend". Ta sẽ dùng Deployment để triển khai nhanh 2 service này trong namespace default.
cat > /tmp/app-deploy.yaml
Kết quả mong đợi: File /tmp/app-deploy.yaml được tạo thành công.
Áp dụng file cấu hình vừa tạo để triển khai 2 Pod backend và frontend vào cluster:
kubectl apply -f /tmp/app-deploy.yaml
Kết quả mong đợi: Cả 2 Deployment được tạo và Pod tương ứng chuyển sang trạng thái Running.
Bây giờ, ta sẽ tạo một CiliumNetworkPolicy để chỉ cho phép Pod "frontend" truy cập vào Pod "backend" trên port 80 (HTTP). Mọi traffic từ nguồn khác sẽ bị chặn.
Tạo file policy tại đường dẫn /tmp/cilium-network-policy.yaml:
cat > /tmp/cilium-network-policy.yaml
Kết quả mong đợi: File policy được tạo thành công với cấu trúc rõ ràng: endpointSelector chỉ đích đến (backend) và ingress định nghĩa nguồn (frontend) và cổng (80).
Áp dụng chính sách network policy vào cluster:
kubectl apply -f /tmp/cilium-network-policy.yaml
Kết quả mong đợi: Lệnh trả về CiliumNetworkPolicy "allow-frontend-to-backend" created.
Verify: Kiểm tra hiệu lực của Policy
Để xác minh policy đang hoạt động, ta cần thực hiện 2 test case: một từ frontend (phải thành công) và một từ pod khác hoặc external (phải thất bại).
Đầu tiên, xác nhận Pod frontend có thể truy cập backend:
POD_FRONTEND=$(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}')
kubectl exec $POD_FRONTEND -- wget -qO- http://backend.default.svc.cluster.local:80
Kết quả mong đợi: Lệnh wget trả về nội dung HTML của trang mặc định httpd (bắt đầu bằng ). Điều này chứng tỏ traffic từ frontend được cho phép.
Tiếp theo, kiểm tra xem policy có chặn traffic từ bên ngoài hoặc từ Pod không thuộc nhóm frontend không. Ta sẽ tạo một Pod "attacker" ngẫu nhiên để thử:
kubectl run attacker --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://backend.default.svc.cluster.local:80
Kết quả mong đợi: Lệnh wget sẽ treo (timeout) hoặc báo lỗi Connection refused hoặc Connection timed out. Điều này chứng tỏ Cilium đã chặn traffic từ Pod không có label "app: frontend".
Lưu ý: Nếu bạn dùng terminal để test, hãy nhấn Ctrl+C để thoát lệnh timeout.
Kiểm tra hoạt động tổng thể và kết nối Pod
Sau khi đã cài đặt CNI, bật Hubble và áp dụng Network Policy, bước cuối cùng là xác minh toàn bộ hệ thống kết nối Pod-to-Pod hoạt động trơn tru và được bảo vệ đúng ý muốn.
Chúng ta sẽ sử dụng lệnh cilium connectivity (nếu đã cài cilium-cli) hoặc dùng lệnh kubectl kết hợp với curl để test.
Đầu tiên, kiểm tra xem Cilium có đang theo dõi đúng số lượng Pod trong cluster không:
kubectl get pods -A -o wide | grep -v cilium | wc -l
Kết quả mong đợi: Số lượng Pod (loại trừ các Pod của Cilium) khớp với số Pod bạn đã tạo (frontend, backend, attacker nếu còn tồn tại).
Để xem chi tiết các kết nối đang được Cilium quản lý (bao gồm cả những kết nối bị drop), ta sử dụng lệnh của Cilium (nếu đã cài cilium-cli) hoặc xem logs của hubble-relay như đã làm ở phần Hubble.
Tuy nhiên, cách đơn giản nhất để verify trực tiếp từ Kubernetes là dùng kubectl describe trên Pod backend để xem Cilium đã áp dụng policy chưa:
kubectl get ciliumnetworkpolicy -o yaml
Kết quả mong đợi: Xuất hiện nội dung YAML của policy "allow-frontend-to-backend" với trạng thái Ready (nếu có) và các trường endpointSelector khớp với Pod backend.
Thực hiện test connectivity cuối cùng: Tạo một Pod mới "client" và cố gắng connect đến "backend". Policy hiện tại sẽ chặn nó vì client không nằm trong danh sách cho phép.
kubectl run client --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://backend.default.svc.cluster.local:80
Kết quả mong đợi: Kết nối bị chặn (timeout hoặc connection refused). Đây là dấu hiệu cho thấy Cilium Network Policy đang hoạt động chính xác theo thiết kế Zero Trust cơ bản.
Để mở lại quyền truy cập cho Pod "client" (mô phỏng việc cập nhật policy), ta sẽ mở rộng policy ban đầu:
kubectl edit ciliumnetworkpolicy allow-frontend-to-backend
Sửa file config trong editor: thêm block fromEndpoints mới cho label app: client vào phần ingress. Lưu và thoát.
Thực hiện lại lệnh wget từ Pod client:
kubectl run client --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://backend.default.svc.cluster.local:80
Kết quả mong đợi: Lần này lệnh wget thành công và trả về nội dung HTML. Điều này xác nhận Cilium đã cập nhật policy và cho phép traffic mới ngay lập tức.
Để kết thúc phần này, hãy đảm bảo bạn có thể truy cập Hubble UI (qua port-forward) và thấy các dòng flow mới nhất tương ứng với các test vừa làm (từ frontend, từ client sau khi update policy).
kubectl logs -n cilium -l name=hubble-relay --tail=20
Kết quả mong đợi: Logs hiển thị các dòng flow với srcIdentity và dstIdentity tương ứng với các Pod frontend, client, backend và verdict là Allow cho các kết nối thành công.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Service Mesh nội bộ an toàn với Istio, Cilium và eBPF trên Kubernetes để quản lý lưu lượng mạng, bảo mật và quan sát chi tiết
« Phần 1: Chuẩn bị môi trường Kubernetes và công cụ cần thiết
Phần 3: Tích hợp Istio với Cilium và bật mTLS tự động »