Cấu hình Cilium Hubble để thu thập lưu lượng mạng thời gian thực
Bước đầu tiên là kích hoạt tính năng Hubble trong cluster Kubernetes để bắt đầu thu thập các gói tin mạng (packet) và kết nối (connection) ở lớp eBPF.
Chúng ta cần chỉnh sửa file cấu hình `cilium-config.yaml` để bật `hubble-relay` và `hubble-ui`, đồng thời bật chế độ ghi log chi tiết cho Hubble.
Sửa file `/etc/cilium/cilium-config.yaml` (hoặc file tương đương trong cluster của bạn) với nội dung sau:
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
metrics:
enabled:
- "dns"
- "drop"
- "tcp"
- "flow"
- "port-distribution"
- "policy"
monitor:
aggregation: high
flow-logs:
enabled: true
Kết quả mong đợi: Cilium Agent sẽ khởi động lại các pod và bắt đầu thu thập flow logs từ các endpoint eBPF. Bạn sẽ thấy các dòng log "Hubble relay" và "Hubble UI" trong `kubectl logs`.
Để verify kết quả, chạy lệnh sau để kiểm tra trạng thái của Hubble:
kubectl get pods -n kube-system | grep hubble
Kết quả phải hiển thị các pod `hubble-relay` và `hubble-ui` ở trạng thái `Running`.
Triển khai Hubble Relay và UI để trực quan hóa luồng dữ liệu
Sau khi bật Hubble, chúng ta cần expose dịch vụ này để truy cập từ ngoài cluster. Hubble Relay đóng vai trò proxy để Hubble UI có thể truy cập an toàn vào các agent Cilium.
Áp dụng cấu hình vừa chỉnh sửa và expose service cho Hubble Relay:
kubectl apply -f /etc/cilium/cilium-config.yaml
kubectl expose deployment hubble-relay -n kube-system --type=LoadBalancer --target-port=4245
Kết quả mong đợi: Service `hubble-relay` được tạo và cấp địa chỉ IP công cộng (nếu dùng cloud) hoặc IP nội bộ (nếu dùng k3s/minikube).
Để truy cập giao diện Hubble UI, chúng ta cần port-forward hoặc expose service UI. Dưới đây là cách expose cả Hubble UI:
kubectl expose deployment hubble-ui -n kube-system --type=LoadBalancer --target-port=8080
Kết quả mong đợi: Bạn sẽ có 2 service mới. Truy cập vào địa chỉ IP của service `hubble-ui` trên trình duyệt để xem dashboard trực quan hóa lưu lượng mạng.
Verify kết quả bằng cách xem luồng kết nối thời gian thực:
kubectl port-forward svc/hubble-ui -n kube-system 8080:8080 &
kubectl port-forward svc/hubble-relay -n kube-system 4245:4245 &
curl http://localhost:8080
Kết quả: Trình duyệt mở ra dashboard Hubble, hiển thị các dòng kết nối (flows) giữa các pod trong cluster.
Tích hợp Prometheus và Grafana để giám sát metric eBPF
Hubble tự động xuất các metric dưới dạng Prometheus format. Chúng ta cần cấu hình Prometheus để scrape các metric này từ Hubble Relay.
Tạo file cấu hình Prometheus để thêm target vào Hubble Relay. File này thường đặt tại `/etc/prometheus/prometheus.yml`:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'hubble-relay'
static_configs:
- targets:
- 'hubble-relay.kube-system.svc.cluster.local:4245'
metrics_path: /metrics
Kết quả mong đợi: Prometheus sẽ bắt đầu scrape metric từ endpoint `/metrics` của Hubble Relay mỗi 15 giây.
Tiếp theo, cấu hình datasource trong Grafana để kết nối với Prometheus. Giả sử bạn đã có Grafana chạy, tạo file `/etc/grafana/provisioning/datasources/prometheus.yml`:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus-server:9090
isDefault: true
editable: true
Kết quả mong đợi: Grafana tự động reload và hiển thị datasource Prometheus mới trong menu "Connections" -> "Data Sources".
Để verify, import dashboard chính thức của Cilium vào Grafana. Dashboard ID là 14753.
kubectl exec -it grafana-pod-name -- grafana-cli plugins install grafana-piechart-panel
curl -X POST http://admin:admin@grafana:3000/api/dashboards/import \
-H "Content-Type: application/json" \
-d '{"dashboard":{"uid":"cilium-hubble","title":"Cilium Hubble","version":1},"orgId":1,"inputs":[{"name":"Prometheus","pluginId":"prometheus","type":"datasource","value":"Prometheus"}]}'
Kết quả: Dashboard "Cilium Hubble" xuất hiện trong Grafana, hiển thị các biểu đồ như "Flows per second", "DNS Queries", "TCP Retransmissions".
Cấu hình Jaeger hoặc Zipkin để phân tích distributed tracing
Để phân tích chi tiết luồng đi của một request (distributed tracing), chúng ta cần tích hợp Hubble với backend tracing như Jaeger. Hubble có thể xuất trace data dưới dạng OpenTelemetry hoặc Jaeger Thrift.
Triển khai Jaeger vào cluster Kubernetes. Tạo file `jaeger-all-in-one.yaml` tại `/etc/jaeger/jaeger-all-in-one.yaml`:
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
namespace: observability
labels:
app: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one:1.50
ports:
- containerPort: 16686
name: query
- containerPort: 14268
name: collector
env:
- name: COLLECTOR_ZKSPAN_ENABLED
value: "true"
- name: COLLECTOR_OTLP_ENABLED
value: "true"
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-query
namespace: observability
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 16686
name: query
selector:
app: jaeger
Kết quả mong đợi: Pod Jaeger chạy và Service `jaeger-query` được tạo. Bạn có thể truy cập UI của Jaeger qua port-forward.
Bây giờ, cấu hình Cilium Hubble để gửi trace data vào Jaeger. Sửa lại file `/etc/cilium/cilium-config.yaml` thêm phần `tracing`:
hubble:
tracing:
enabled: true
type: jaeger
endpoint: jaeger-query.observability.svc.cluster.local:14268
sampler:
type: const
arg: 1.0
Kết quả mong đợi: Hubble Relay sẽ bắt đầu gửi các span (mảnh dữ liệu trace) đến Jaeger collector. Lưu ý: `sampler: 1.0` có nghĩa là ghi lại 100% các request (chỉ dùng cho test, trong production nên giảm xuống).
Để verify kết quả, tạo một request HTTP giữa 2 pod và kiểm tra trace trong Jaeger:
kubectl port-forward svc/jaeger-query -n observability 16686:80 &
curl http://localhost:16686
Thực hiện request test (ví dụ từ pod A đến pod B) và sau đó vào giao diện Jaeger, chọn service và tìm trace ID tương ứng. Bạn sẽ thấy các span eBPF hiển thị thời gian xử lý tại các điểm khác nhau trong service mesh.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Secure Service Mesh với eBPF, Cilium và Policy Engine
« Phần 5: Bảo mật lớp ứng dụng (L7) và quản lý lưu lượng HTTP/gRPC
Phần 7: Tối ưu hiệu năng và Troubleshooting nâng cao cho Service Mesh »