Một container không kết nối được tới bất cứ thứ gì sau VPN doanh nghiệp thường sống trong một không gian tên mạng khác với đường hầm. Các tuyến, máy chủ DNS và dấu tường lửa của máy khách trên host thuộc về ngăn xếp của host; container mạng cầu nối có ngăn xếp riêng. Riêng sự thật này giải thích phần lớn báo cáo đến tay nhóm nền tảng, và cũng là lý do «VPN hỏng» và «Docker vượt qua VPN» có thể cùng sai một lúc. Hai cấu hình rất khác nhau ẩn sau một triệu chứng, vì vậy hãy xác định bạn đang có cái nào trước khi đổi bất kỳ cài đặt nào.

Tìm ra không gian tên nào sở hữu đường hầm

Trên Docker Desktop cho macOS hoặc Windows, container chạy bên trong một máy ảo Linux. Máy khách VPN cài trên máy tính tạo một đường hầm trong hệ điều hành máy tính, và máy ảo không bao giờ thấy nó. Không cấu hình container nào sửa được điều đó, vì giao diện mà container cần hoàn toàn không tồn tại trong không gian tên mạng của nó.

Trên host Linux, đường hầm sống trong không gian tên của host, và container cầu nối thường đến được nó qua bảng định tuyến của host với NAT nguồn được áp dụng khi ra ngoài. Khi tuyến đó thất bại, nguyên nhân thường là chính sách chuyển tiếp, lọc tuyến ngược hoặc một mạng con chồng lấn chứ không phải tuyến bị thiếu. Xác nhận bạn đang ở thế giới nào trước khi đọc tiếp:

docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5

Sự khác biệt giữa hai bảng định tuyến đó là toàn bộ vấn đề trên một màn hình. Nếu chế độ xem của host có giao diện đường hầm còn chế độ xem của cầu nối thì không, bạn đang nhìn vào sự cô lập không gian tên, và mọi thứ còn lại là lựa chọn cách vượt qua nó.

Mạng host là một phép thử, không phải thiết kế

Chạy container với mạng host, điều mà Docker ghi nhận là chia sẻ không gian tên mạng của host, khiến nó thừa hưởng trực tiếp giao diện đường hầm và các tuyến của nó. Nếu cùng yêu cầu đó sau đó thành công, lý thuyết tuyến được xác nhận và lỗi là cô lập không gian tên, không phải thông tin đăng nhập, DNS hay quy tắc truy cập.

docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health

Hãy giữ nó như chẩn đoán. Mạng host từ bỏ việc công bố cổng và phần lớn sự cô lập mà bạn muốn từ một container, và trên Docker Desktop «host» nghĩa là máy ảo, không phải máy tính, nên thành công hay thất bại ở đó có thể đánh lừa bạn nếu quên mình đang nhắm tới host nào.

Một thiết bị tun và các đặc quyền đi kèm

Máy khách VPN bên trong container cần một thiết bị đường hầm và quyền cấu hình nó. Cách tắt phổ biến là --privileged, cấp mọi thiết bị và nới lỏng chính sách bảo mật trên toàn container. Đó là nhiều hơn mức công việc này yêu cầu, và khó biện minh trong một buổi đánh giá.

sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client

Dạng hẹp hơn ánh xạ nút thiết bị duy nhất và chỉ thêm khả năng quản trị mạng. Nạp mô-đun trên host trước để nút tồn tại. Nếu container khởi động và máy khách báo không mở được thiết bị đường hầm, hãy kiểm tra ánh xạ trước khi nghi ngờ hồ sơ, vì lỗi đó thường theo nghĩa đen.

Thiết kế này cũng có nghĩa máy khách chạy theo từng container. Đó là câu trả lời đúng khi mỗi khối lượng công việc cần đường hầm riêng, và là câu trả lời sai khi bạn chỉ muốn đường hầm của host hiển thị, điều mà nhóm nền tảng có lẽ đã giả định bạn đang làm.

NAT của cầu nối thay đổi nguồn mà VPN thấy

Với cầu nối mặc định, lưu lượng ra của container được dịch sang địa chỉ của host. Vì vậy sau VPN, phía doanh nghiệp thấy địa chỉ đường hầm của host chứ không phải của container, các quy tắc truy cập theo nguồn hành xử như thể host đã gửi yêu cầu, và hai container trở nên không phân biệt được với máy chủ VPN.

macvlan hoặc ipvlan thay vào đó cấp cho container một địa chỉ LAN, giúp phát hiện trong LAN và khiến container trông như một ngang hàng trên phân đoạn. Nó cũng bỏ qua hoàn toàn đường hầm của host, nên container như vậy sẽ không đến được các tiền tố chỉ-VPN trừ khi VPN cũng truy cập được từ LAN đó.

Cả hai dạng đều hợp lệ; chúng trả lời các yêu cầu khác nhau. Nếu yêu cầu là «container này phải đến được một dịch vụ chỉ-VPN», bạn chọn giữa định tuyến qua host và kết thúc đường hầm bên trong container. Hãy ghi lại lựa chọn đó trước khi triển khai, không phải sau yêu cầu thất bại đầu tiên. Dù chọn gì, hãy ghi lại địa chỉ nguồn mà đầu xa sẽ thấy, vì đó chính là thứ các quy tắc truy cập và nhật ký của nó sẽ hiển thị. Một thiết kế không nêu được địa chỉ đó là chưa hoàn chỉnh.

DNS đi theo daemon, không phải đường hầm

Container nhận cấu hình bộ phân giải khi khởi động, được sao chép từ daemon hoặc từ ảnh. Các địa chỉ mà VPN đẩy sau khi kết nối đến quá muộn cho bản sao đó, và chúng được đẩy tới bộ phân giải của host chứ không vào container.

Đặt bộ phân giải một cách rõ ràng cho dịch vụ, hoặc trỏ nó tới một bộ phân giải nội bộ truy cập được qua đường hầm. Một container phân giải tên riêng thành địa chỉ công cộng thường dùng bộ phân giải công cộng, không phải chịu tuyến hỏng, và bản sửa thuộc về tệp compose hoặc cấu hình daemon.

Lập luận tương tự áp dụng cho câu hỏi địa chỉ ra. Nếu mỗi container phải xuất hiện từ một địa chỉ VPN khác nhau, một đường hầm host không thể cung cấp điều đó vì NAT gộp chúng thành một nguồn. Các dạng khả thi là một máy khách trong không gian tên của từng container hoặc một sidecar sở hữu đường hầm và chia sẻ ngăn xếp của nó, và cả hai đều thay đổi cách ứng dụng được định địa chỉ.

Danh sách kiểm tra trước khi đóng phiếu: xác định không gian tên sở hữu đường hầm, chứng minh tuyến bằng mạng host, chỉ ánh xạ thiết bị tun cần thiết, nhớ địa chỉ nguồn sau NAT, đặt bộ phân giải rõ ràng và coi địa chỉ ra theo từng container là quyết định kiến trúc chứ không phải cờ.

Bài viết liên quan