Khoảng cách về khả năng quan sát trong mạng lưới Microservices
Bạn đang nhìn vào một bảng điều khiển đầy những cảnh báo đỏ. Frontend của bạn đang trả về lỗi 500 Internal Server Error, nhưng log lại mập mờ đến mức gây ức chế: Error: Upstream service failed. Bạn kiểm tra backend, và nó khẳng định mọi thứ vẫn ổn. Đâu đó trong mạng lưới giữa các dịch vụ này, một yêu cầu đang bị hỏng, một header bị thiếu, hoặc một mức timeout 15ms đang gây ra sự sụp đổ dây chuyền.
Đây chính là lúc các bộ công cụ gỡ lỗi tiêu chuẩn thường thất bại. Trong một ứng dụng monolith (đơn khối), bạn chỉ cần đặt một breakpoint. Trong Kubernetes, lưu lượng truy cập len lỏi qua một mạng lưới dày đặc các Service IP, Ingress controller và CNI plugin. Hầu hết các lập trình viên cố gắng giải quyết vấn đề này bằng cách rải rác các câu lệnh console.log hoặc printf vào mã nguồn. Họ build lại image, đẩy lên registry và triển khai lại. Chu kỳ này thường mất từ 10 đến 15 phút cho mỗi lần thử và hiếm khi bắt được các sự cố mạng mang tính tạm thời.
Tại sao các công cụ truyền thống lại không đáp ứng được yêu cầu
Sự ức chế bắt đầu từ việc thiếu khả năng quan sát sâu và hiểu biết về giao thức. Trong khi kubectl logs hiển thị đầu ra của ứng dụng, nó không hiển thị các byte thực tế đang di chuyển trên đường truyền. Bạn có thể thử dùng tcpdump, nhưng nhiều container hiện đại là dạng “distroless” và thiếu các tiện ích gỡ lỗi cơ bản vì lý do bảo mật. Ngay cả khi bạn thu thập được lưu lượng, bạn sẽ nhận được một tệp .pcap nặng tới 2GB. Việc phân tích tệp đó cho các giao thức cấp cao như HTTP/2 hoặc gRPC là một quá trình thủ công và chậm chạp.
Các Service Mesh như Istio hoặc Linkerd cung cấp khả năng quan sát, nhưng chúng đi kèm với một cái giá đắt về tài nguyên. Chúng yêu cầu các sidecar và cấu hình phức tạp. Nếu bạn chưa vận hành một mesh, bạn không nên phải cài đặt nó chỉ để sửa một lỗi duy nhất. Bạn cần một giải pháp mang tính tạm thời (ephemeral), mạnh mẽ và không yêu cầu thay đổi cơ sở hạ tầng của mình.
Làm quen với Kubeshark: Wireshark dành cho Kubernetes
Kubeshark, trước đây được gọi là Mizu, cung cấp một cách sạch sẽ để kiểm tra lưu lượng truy cập. Nó không yêu cầu agent hay sửa đổi tệp YAML. Thay vào đó, nó triển khai các worker pod tạm thời vào các node của bạn. Các worker này sử dụng eBPF (Extended Berkeley Packet Filter) để “ngửi” (sniff) lưu lượng trực tiếp từ giao diện mạng. Khi bạn dừng công cụ, nó sẽ tự dọn dẹp, không để lại dấu vết nào.
Trong môi trường production, đây là một kỹ năng quan trọng. Nó cho phép bạn thấy sự thật khách quan về những gì đang xảy ra trên đường truyền, thay vì dựa vào những gì logic mã nguồn của bạn tuyên bố là đang xảy ra.
Các khả năng chính:
- Hỗ trợ giao thức rộng rãi: Nó giải mã HTTP/1.1, HTTP/2, gRPC, Redis, RabbitMQ và Kafka ngay khi sử dụng.
- Giao diện thời gian thực: Dashboard web mang lại cảm giác trực quan như Chrome DevTools nhưng hoạt động cho toàn bộ cluster của bạn.
- Không can thiệp (Zero Injection): Hoạt động mà không cần sidecar hoặc khởi động lại ứng dụng.
- KFL (Kubeshark Filtering Language): Cho phép bạn xác định chính xác lưu lượng truy cập theo header, mã trạng thái hoặc nội dung payload.
Thực hành: Cài đặt và chạy Kubeshark
Để bắt đầu, bạn sẽ cần Kubeshark CLI. Công cụ này quản lý kết nối giữa máy cục bộ của bạn và cơ sở hạ tầng tạm thời của cluster.
1. Cài đặt
Trên macOS hoặc Linux, Homebrew là cách nhanh nhất:
# Sử dụng Homebrew
brew install kubeshark
# Tải xuống thủ công cho Linux
curl -Lo kubeshark https://github.com/kubeshark/kubeshark/releases/latest/download/kubeshark_$(uname -s | tr '[:upper:]' '[:lower:]')_amd64 && chmod +x kubeshark && sudo mv kubeshark /usr/local/bin/
2. Theo dõi lưu lượng (Tapping)
Lệnh tap là trung tâm của Kubeshark. Nó xác định những pod nào bạn muốn theo dõi. Để xem tất cả lưu lượng trong một namespace cụ thể, hãy chạy:
kubeshark tap -n production-namespace
Nếu bạn cần cô lập một tương tác dịch vụ cụ thể, hãy sử dụng label selector:
kubeshark tap "(app == 'order-service' || app == 'payment-service')"
Sau đó, Kubeshark sẽ triển khai một pod “Hub” và vài pod “Worker”. Nó tự động mở một cửa sổ trình duyệt tại localhost:8899 để hiển thị luồng dữ liệu trực tiếp.
Phân tích giao tiếp giữa các Microservices
Dashboard cung cấp một luồng dữ liệu trực tiếp của mọi yêu cầu. Bạn có thể thấy phương thức (method), đường dẫn (path) và mã trạng thái (status code) trong nháy mắt. Nhấp vào một mục sẽ hiển thị đầy đủ header của yêu cầu và phản hồi, cùng với nội dung body.
Kịch bản: Tìm lỗi 404 ẩn giấu
Gần đây tôi đã hỗ trợ một nhóm có dịch vụ bị lỗi vì không thể tải cấu hình. Log chỉ hiển thị “Config failed to load.” Sử dụng Kubeshark, chúng tôi ngay lập tức phát hiện một yêu cầu GET đến dịch vụ metadata trả về lỗi 404. Hóa ra đó chỉ là một lỗi đánh máy đơn giản trong URL của biến môi trường. Chúng tôi đã tìm ra nguyên nhân gốc rễ trong 30 giây—một công việc vốn đã tiêu tốn hai giờ đồng hồ của các lập trình viên trước đó.
Sử dụng ngôn ngữ lọc (KFL)
Trong một cluster có lưu lượng truy cập cao, luồng dữ liệu có thể gây choáng ngợp. KFL giúp bạn lọc bỏ các nhiễu. Nhập các câu lệnh này vào thanh tìm kiếm để thu hẹp phạm vi:
- Tìm lỗi:
response.status >= 400 - Xác định độ trễ:
item.duration > 500ms - Truy vết một người dùng cụ thể:
request.headers["X-Correlation-Id"] == "abc-123" - Kiểm tra payload JSON:
request.body.user.id == 99
# Tìm các lần đăng nhập thất bại
http and request.method == "POST" and request.path == "/v1/login" and response.status != 200
Gỡ lỗi nâng cao: gRPC và lưu lượng mã hóa
gRPC nổi tiếng là khó gỡ lỗi vì nó sử dụng mã hóa Protobuf dạng nhị phân. Các công cụ tiêu chuẩn chỉ hiển thị những ký tự vô nghĩa không thể đọc được. Kubeshark tự động giải mã các payload nhị phân này thành JSON có thể đọc được. Tính năng này giúp tiết kiệm khối lượng lớn thời gian cho các nhóm đang chuyển dịch từ REST.
Còn về vấn đề mã hóa thì sao? Nếu bạn sử dụng mTLS, việc “ngửi” lưu lượng thường là bất khả thi. Tuy nhiên, Kubeshark tận dụng eBPF để can thiệp vào bộ nhớ tiến trình. Nó thường có thể thu thập dữ liệu ngay trước khi nó được mã hóa hoặc ngay sau khi nó được giải mã, mang lại cho bạn khả năng quan sát ngay cả trong môi trường bảo mật.
Dọn dẹp và các thực hành tốt nhất
Kubeshark được thiết kế để sử dụng tạm thời. Khi bạn hoàn tất, hãy nhấn Ctrl+C trong terminal. Để đảm bảo mọi tài nguyên đã được gỡ bỏ, bạn có thể chạy:
kubeshark clean
Lưu ý về bảo mật
Vì Kubeshark nhìn thấy mọi thứ—bao gồm cả API key và thông tin cá nhân (PII)—bạn phải sử dụng nó một cách có trách nhiệm:
- RBAC: Giới hạn quyền truy cập Kubeshark cho các kỹ sư được ủy quyền. Nó yêu cầu quyền để tạo pod và liệt kê các secret.
- Hiệu năng: Sử dụng hạn chế trong môi trường production có tải cao. Mặc dù eBPF rất hiệu quả, nhưng việc thu thập 10.000 yêu cầu mỗi giây cuối cùng sẽ ảnh hưởng đến CPU của node.
- Ẩn dữ liệu nhạy cảm: Sử dụng cấu hình của Kubeshark để che các trường nhạy cảm như header
Authorizationhoặc số thẻ tín dụng.
Tổng kết
Mạng lưới Kubernetes không nên là một hệ thống không thể xuyên thấu. Thay vì đoán xem tại sao một dịch vụ bị lỗi, Kubeshark cung cấp cho bạn một bản đồ trực quan tức thì về lưu lượng API. Bằng cách thành thạo lệnh tap và KFL cơ bản, bạn có thể cắt giảm Thời gian trung bình để khắc phục sự cố (MTTR) từ hàng giờ xuống còn vài phút. Đây là một công cụ nhẹ, không cần agent, xứng đáng có mặt trong kho vũ khí của mọi kỹ sư DevOps.

