Vấn đề: Khi Image “siêu nhẹ” trở thành rào cản debug
Tưởng tượng container trên Production bỗng dưng báo lỗi Connection Timeout khi gọi sang Database. Bạn định nhảy vào “thám hiểm” bằng lệnh docker exec -it <id> bash nhưng lại nhận về một gáo nước lạnh:
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "bash": executable file not found in $PATH: unknown
Thử với sh, curl, hay ping đều vô vọng. Đây là cái giá của việc dùng Distroless Image hoặc Alpine Linux để tối ưu bảo mật. Chúng quá tinh gọn đến mức không có sẵn bất kỳ công cụ mạng nào để bạn kiểm tra lỗi.
Thay vì tốn 15-20 phút sửa Dockerfile, cài thêm iputils-ping rồi chờ CI/CD build lại Image, có một cách chuyên nghiệp hơn nhiều. Đó chính là sử dụng nsenter.
So sánh các phương pháp debug mạng Docker
Mỗi cách tiếp cận đều có đánh đổi riêng. Dưới đây là bảng so sánh nhanh để bạn dễ hình dung:
- Cài trực tiếp vào Image: Tiện nhưng làm tăng dung lượng Image (thêm khoảng 20-50MB) và tạo lỗ hổng bảo mật nếu hacker chiếm được container.
- Sidecar Container (netshoot): Rất mạnh mẽ với đầy đủ đồ chơi. Tuy nhiên, bạn phải pull thêm Image mới, đôi khi bất khả thi trong môi trường air-gapped (không có internet).
- Sử dụng nsenter: Dùng trực tiếp công cụ của máy Host (như
tcpdump,nmap) để soi nội bộ container. Không cần cài gì vào container, không cần internet.
Tại sao nsenter lại mạnh mẽ đến vậy?
Docker sử dụng Linux Namespaces để cô lập tài nguyên. Mỗi container sở hữu một Network Namespace riêng với bảng định tuyến và firewall tách biệt.
nsenter (Namespace Enter) đóng vai trò như một “cánh cửa thần kỳ”. Nó cho phép bạn đứng ở máy Host nhưng lại nhìn thấy toàn bộ cấu trúc mạng bên trong container. Bạn vẫn dùng được lệnh curl hay tcpdump của máy Host, nhưng đích đến lại là Network Namespace của container đó.
Hướng dẫn debug thực tế với nsenter
Giả sử container webapp_prod đang gặp lỗi kết nối. Hãy thực hiện 3 bước sau:
Bước 1: Tìm PID (Process ID) của container
Vì container bản chất là một tiến trình trên Linux, bạn cần lấy PID của nó bằng lệnh:
docker inspect -f '{{.State.Pid}}' webapp_prod
Giả sử kết quả trả về là 8844.
Bước 2: Truy cập Network Namespace
Tiếp theo, hãy dùng nsenter để “nhập xác” vào container:
sudo nsenter -t 8844 -n
Trong đó -t 8844 là Target PID và -n (Network) nghĩa là chỉ can thiệp vào mạng. Lúc này, nếu bạn gõ ip addr, địa chỉ IP hiển thị sẽ là của container chứ không phải của máy Host.
Bước 3: Thực hiện kiểm tra lỗi
Giờ là lúc bạn sử dụng “vũ khí” của máy Host để kiểm tra container:
- Kiểm tra kết nối DB:
curl -v 10.0.1.5:5432 - Xem các kết nối đang treo:
ss -tpn - Bắt gói tin để tìm nguyên nhân drop:
tcpdump -i eth0 port 80
Mẹo nhỏ: Xử lý dữ liệu JSON cồng kềnh
Khi debug các API phản hồi JSON dài hàng nghìn dòng, việc đọc trên terminal rất mỏi mắt. Mình thường copy nhanh đoạn JSON đó và dùng JSON Formatter để định dạng lại. Việc này giúp mình nhanh chóng phát hiện ra các sai lệch trong cấu trúc dữ liệu mà không cần cài thêm jq lên server.
Các tùy chọn mở rộng của nsenter
Không chỉ có mạng, nsenter còn hỗ trợ can thiệp sâu hơn:
-u(UTS): Xem hoặc sửa hostname container.-m(Mount): Kiểm tra các ổ đĩa được gắn vào container (hữu ích khi debug lỗi quyền ghi file).-p(PID): Xem danh sách các tiến trình đang chạy bên trong container bằng lệnhpscủa máy Host.
Lệnh để vào “toàn bộ” môi trường container (trừ file system): sudo nsenter -t <PID> -n -u -i -p.
Lưu ý về bảo mật và môi trường
nsenter yêu cầu quyền sudo, vì vậy hãy kiểm soát chặt chẽ quyền truy cập SSH vào máy Host. Đối với Docker Desktop trên Mac hoặc Windows, bạn cần truy cập vào máy ảo Linux (Linux VM) trước khi thực hiện các lệnh trên.
Kết luận
Thành thạo nsenter giúp bạn tách biệt rạch ròi giữa vận hành và phát triển. Bạn giữ được Image Production tinh gọn, bảo mật nhưng vẫn nắm trong tay công cụ debug cực mạnh. Lần tới, nếu docker exec báo lỗi thiếu lệnh, đừng vội build lại Image, hãy nhớ đến nsenter.

