Ảnh container có thể mang mọi tệp nhị phân và tệp cấu hình OpenVPN cần thiết mà vẫn thất bại ở lần gọi mạng đầu tiên. Lỗi nêu /dev/net/tun vì ứng dụng đã yêu cầu nhân một giao diện TUN và container không có nút thiết bị lẫn khả năng tạo ra nó. Đó là hai quyền riêng biệt, và sửa một cái để cái kia đúng nguyên chỗ cũ.

Tách chúng cần một lệnh cho mỗi cái. Thông báo lỗi sau đó cho bạn biết bạn thực sự đang đứng ở ranh giới nào.

Nút thiết bị và khả năng là hai cánh cửa

Nút thiết bị là một đối tượng của hệ thống tệp, nên container phải nhìn thấy nó trong không gian tên gắn kết của chính nó. Khả năng là một quyền, nên tiến trình cần CAP_NET_ADMIN trong không gian tên nơi giao diện sẽ được tạo. Chuyển thiết bị qua mà không có khả năng cho bạn một nút mở được và một ioctl thất bại. Cấp khả năng mà không có thiết bị khiến ứng dụng không mở được gì cả, vì thế hai thứ thường xuất hiện cùng nhau trong các ví dụ.

Cài đặt devices của Docker ánh xạ thiết bị của máy chủ vào container, còn cap_add điều chỉnh tập khả năng. Một bind mount cùng đường dẫn đưa tệp vào tầm nhìn mà không áp dụng ngữ nghĩa truy cập thiết bị.

Tái tạo nó bên ngoài tệp Compose

Trước khi sửa dịch vụ, hãy kiểm tra máy chủ có thiết bị và một container trần có thể tạo giao diện. Lệnh dưới đây cố ý tối giản, và mục đích duy nhất của nó là tách vấn đề máy chủ khỏi vấn đề compose. Nếu nó thất bại, không thay đổi compose nào giúp được.

ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun:/dev/net/tun alpine sh -c 'apk add -q iproute2 && ip tuntap add dev tun9 mode tun && ip link show tun9'

Thiếu nút trên máy chủ nghĩa là mô-đun tun không khả dụng, đây là cách sửa phía máy chủ chứ không phải phía container. Một nút tồn tại nhưng không mở được bên trong container cho thấy vấn đề truy cập thiết bị, và thông báo sẽ nói permission denied chứ không phải no such file. Thứ tự của hai thất bại đó chính là toàn bộ chẩn đoán. Ghi lại bạn đã thấy cái nào trước khi đổi bất kỳ cờ nào.

Các lỗi sau TUN là những vấn đề khác

Ngay khi giao diện xuất hiện, thất bại tiếp theo có chủ khác. Lỗi xác thực nghĩa là đường hầm đã đến máy chủ và thông tin đăng nhập bị từ chối, nên thay đổi khả năng sẽ không giúp. Một đường hầm được thiết lập trong khi ứng dụng vẫn thất bại cho thấy vấn đề tuyến, chuyển tiếp, phân giải DNS bên trong container hoặc bố cục mạng của chính container. Mỗi thứ đó là một câu hỏi mạng thông thường mà quyền TUN không trả lời được. Lặp lại bài kiểm tra ban đầu sau mỗi thay đổi giúp các thất bại không hòa thành một ấn tượng duy nhất.

Sao chép mọi cài đặt từ một ví dụ đang chạy là cách một bản sửa tối giản trở thành định nghĩa dịch vụ khó đọc. Chỉ mang theo những gì triển khai này cần và ghi lại lý do mỗi thứ có mặt.

Xác minh giao diện bên trong container

Kiểm tra giao diện và tập khả năng từ bên trong container đang chạy chứ không phải từ máy chủ. Các lệnh dưới đây cho thấy nút thiết bị, danh sách khả năng và liệu có thể tạo giao diện hay không. Chạy chúng trong cùng container chạy ứng dụng khách, và cài công cụ nếu ảnh tối giản.

ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9

Một khả năng có trong bounding set nhưng vắng trong effective set hành xử khác với khả năng chưa từng được cấp, và capsh hiển thị cả hai. Nếu nút tồn tại và khả năng có ở đó mà việc tạo vẫn thất bại, môi trường thực thi đang áp đặt thứ khác, chẳng hạn hồ sơ seccomp hoặc chính sách AppArmor hạn chế thao tác. Đó là ranh giới thứ ba, được môi trường thực thi ghi nhận chứ không phải ứng dụng.

Ghi lại các cờ của container, ảnh và lỗi chính xác của từng lần thử. Người đọc ghi chú đó tiếp theo có thể nói cánh cửa nào đã đóng mà không phải lặp lại toàn bộ cuộc điều tra.

Bài viết liên quan