Kích hoạt và cấu hình mTLS tự động giữa các service
Linkerd thực hiện mã hóa lưu lượng (mTLS) tự động giữa các Pod ngay khi chúng được inject, không cần cấu hình thủ công trong ứng dụng.
Để đảm bảo mTLS đang hoạt động, ta cần kiểm tra trạng thái của các service và xác minh chứng chỉ.
Trước tiên, hãy inject sidecar vào một service nguồn (client) và một service đích (server) để tạo đường truyền an toàn.
linkerd inject deploy/httpbin | kubectl apply -f -
Kết quả: Deployment httpbin được cập nhật với container sidecar `linkerd-proxy` mới.
Tiếp theo, tạo một deployment client đơn giản để gọi httpbin.
cat
Kết quả: Pod client được tạo với trạng thái Running, chưa có sidecar.
Bây giờ, inject sidecar vào client để kích hoạt mTLS khi nó gọi đến httpbin.
linkerd inject deploy/client | kubectl apply -f -
Kết quả: Pod client được restart và chứa thêm container `linkerd-proxy`.
Để verify mTLS đang hoạt động, sử dụng command `linkerd stat` để kiểm tra số lượng connection an toàn.
linkerd stat deploy/client --all-namespaces
Kết quả: Cột `tPS` (transactions per second) sẽ tăng khi có traffic, và nếu mTLS hoạt động, traffic giữa client và httpbin sẽ được mã hóa tự động.
Cách verify cụ thể hơn là kiểm tra log của proxy để thấy handshake TLS thành công.
kubectl logs -n linkerd -l linkerd.io/control-plane-component=proxy-injector -c linkerd-proxy --tail=50 2>&1 | grep -i "handshake"
Kết quả: Log hiển thị thông báo "TLS handshake completed" hoặc tương tự cho các connection nội bộ.
Cuối cùng, test trực tiếp từ trong Pod client để gọi service đích.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/get
Kết quả: Phản hồi JSON từ httpbin xuất hiện, chứng tỏ lưu lượng đã đi qua proxy và được mã hóa mTLS.
Định tuyến lưu lượng dựa trên version thông qua Service Profile
Service Profile trong Linkerd cho phép định nghĩa cấu trúc của các cuộc gọi HTTP/GRPC và áp dụng logic định tuyến.
Chúng ta sẽ tạo 2 version của service httpbin: v1 (stable) và v2 (canary).
Bước 1: Tạo deployment cho version v2 của httpbin.
kubectl run httpbin-v2 --image=mattmoor/httpbin:latest --port=80
Kết quả: Deployment httpbin-v2 được tạo và chạy song song với httpbin cũ.
Bước 2: Tạo Service Profile để định nghĩa route.
File cấu hình Service Profile sẽ định nghĩa rằng khi gọi đường dẫn `/canary`, traffic sẽ được chuyển hướng sang service `httpbin-v2`.
cat
Kết quả: ServiceProfile được tạo thành công, Linkerd sẽ bắt đầu phân tích và định tuyến lưu lượng dựa trên path.
Để verify, ta sẽ gọi cả hai đường dẫn từ Pod client.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/get
Kết quả mong đợi: Traffic đi đến httpbin (version cũ), vì path `/get` khớp với default-route.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/canary/get
Kết quả mong đợi: Traffic đi đến httpbin-v2 (version mới), vì path `/canary/...` khớp với canary-route trong ServiceProfile.
Kiểm tra lại bằng `linkerd top` để xem distribution của traffic.
linkerd top deploy/client
Kết quả: Bạn sẽ thấy 2 dòng destination khác nhau: `httpbin.svc.cluster.local:80` và `httpbin-v2.svc.cluster.local:80` tương ứng với 2 request trên.
Cấu hình retry policies và timeout cho các cuộc gọi HTTP/GRPC
Để tăng độ tin cậy của hệ thống, Linkerd cho phép cấu hình chính sách retry (thử lại) và timeout (thời gian chờ) trong Service Profile.
Chúng ta sẽ cập nhật Service Profile đã tạo ở phần trước để thêm retry policy cho các lỗi server (5xx) và timeout sau 5 giây.
Sửa Service Profile để bao gồm `retryPolicy` và `timeout`.
cat
Kết quả: ServiceProfile được cập nhật. Linkerd sẽ tự động retry nếu server trả về lỗi 5xx trong vòng 3 lần, mỗi lần chờ tối đa 1s.
Để test timeout, ta sẽ gọi một endpoint giả lập chậm (delay).
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/delay/10
Kết quả mong đợi: Request bị timeout sau khoảng 5 giây (theo cấu hình) và trả về lỗi "Request Timeout" hoặc tương tự, thay vì chờ 10 giây.
Để test retry policy, ta cần một endpoint trả về lỗi 500. httpbin có endpoint `/status/500`.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/status/500
Kết quả mong đợi: Linkerd sẽ tự động retry 3 lần. Nếu server vẫn trả 500, client nhận được lỗi 500 sau khi hết retry. Bạn có thể thấy số lần retry tăng trong log của proxy.
Verify retry bằng cách xem log của proxy trên Pod client.
kubectl logs -l app=client -c linkerd-proxy --tail=50 2>&1 | grep -i "retry"
Kết quả: Log hiển thị thông tin về số lần retry đã thực hiện cho request đó.
Sử dụng Linkerd Dashboard để giám sát lưu lượng nội bộ
Linkerd Dashboard cung cấp giao diện trực quan để theo dõi health, latency, error rate của toàn bộ mesh.
Bước 1: Deploy Linkerd Dashboard (nếu chưa có).
linkerd dashboard
Kết quả: Trình duyệt tự động mở trang Dashboard tại địa chỉ `http://localhost:8084` hoặc yêu cầu xác nhận kết nối.
Bước 2: Nếu không thể mở trực tiếp, hãy expose service dashboard qua port-forward.
kubectl port-forward -n linkerd -l app=linkerd-grafana 3000:3000
Kết quả: Terminal hiển thị thông báo "Forwarding from 127.0.0.1:3000 -> 3000". Bạn truy cập `http://localhost:3000` để xem dashboard.
Trong Dashboard, chuyển sang tab "Routes" để xem chi tiết lưu lượng của Service Profile đã cấu hình.
Chọn namespace `default`, sau đó tìm service `httpbin`.
Click vào service `httpbin` để xem danh sách các Route (Routes).
Kết quả mong đợi: Bạn sẽ thấy 2 route riêng biệt:
- Route `default-route`: Hiển thị traffic đi đến `/get`, `/status/500` (không phải canary).
- Route `canary-route`: Hiển thị traffic đi đến `/canary/...` với destination là `httpbin-v2`.
Quan sát các chỉ số quan trọng:
- tPS: Transactions per second (lượng request/giây).
- Success %: Tỷ lệ thành công (nên > 99% nếu không có lỗi).
- Latency: Thời gian phản hồi (p50, p95, p99).
Để verify timeout đang hoạt động, thực hiện request `/delay/10` từ client và nhìn vào Dashboard trong thời gian thực.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/delay/10
Kết quả trên Dashboard: Route tương ứng sẽ hiển thị màu đỏ (Error rate tăng) và Latency cao, nhưng không vượt quá 5s (do timeout cut-off).
Để verify retry, thực hiện request `/status/500`.
kubectl exec -it deploy/client -- curl -s http://httpbin.svc.cluster.local/status/500
Kết quả trên Dashboard: Route này sẽ có Error rate 100%, nhưng số lượng request vào proxy (Input tPS) sẽ cao hơn số lượng request thực tế gửi lên backend (Output tPS) do cơ chế retry (1 request thực tế = 4 requests trong log: 1 ban đầu + 3 retry).
Tab "Workloads" cho phép xem chi tiết từng Pod. Click vào Pod `client` để xem traffic ra (Outbound) và traffic vào (Inbound) của nó.
Kết quả: Bạn thấy traffic outbound đi đến `httpbin` và `httpbin-v2` với các chỉ số latency và error rate cụ thể cho từng destination.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Service Mesh trên Kubernetes với Linkerd và eBPF
« Phần 2: Triển khai Linkerd cơ bản và kiểm tra hoạt động
Phần 4: Tích hợp eBPF vào Linkerd để tối ưu hiệu năng »