Bên trong một container sau VPN doanh nghiệp, DNS phân giải được, trang đăng nhập tải được, một endpoint kiểm tra sức khỏe trả lời, rồi một yêu cầu HTTPS treo cho đến khi hết thời gian. Dựng lại image và đổi biến proxy không thay đổi gì, vì phần hỏng không nằm trong image. Client xác thực qua một đường truyền và chuyển dữ liệu lớn qua đường khác, và chỉ đường thứ hai bị hỏng.

Hai đường truyền, một triệu chứng khó hiểu

Một client doanh nghiệp dựa trên TLS thường xác thực qua một kết nối TLS thông thường, rồi thương lượng một kênh dữ liệu thứ hai dựa trên UDP cho phiên. Khi nhánh thứ hai đó hoạt động, thông lượng và độ trễ được cải thiện. Khi nó bị lọc hoặc không vừa với đường đi, mọi thứ trước khi truyền dữ liệu lớn đều thành công và bản thân việc truyền dừng lại, đúng như mẫu ở trên.

Container không thay đổi việc thương lượng đó; nó thay đổi đường đi của các gói bên ngoài. Máy chủ biên dịch luồng của container, nên các datagram UDP rời đi từ một cổng nguồn khác với socket cục bộ của client và quay về qua một mục dịch địa chỉ hết hạn với bộ đếm thời gian ngắn hơn nhiều so với một luồng TCP đã thiết lập. Nếu tunnel chạy trên máy chủ mà hỏng trong container, hãy so sánh hai luồng đó trước khi đổ lỗi cho ứng dụng. So sánh đó phân định nhiều hơn mọi lần dựng lại image.

Quyết định bằng thí nghiệm, không bằng cảm tính

Thí nghiệm rẻ nhất là tắt kênh dữ liệu UDP và lặp lại yêu cầu. Dùng client dòng lệnh thay cho lớp bọc đồ họa, để cờ thực sự được áp dụng: openconnect vpn.example.net --user=you --interface=tun0 --no-dtls. Nếu yêu cầu từng treo nay hoàn tất, nhánh DTLS chính là vấn đề và phần còn lại là nhiễu.

Xác nhận kết quả theo cả hai chiều từ cùng một container, một yêu cầu lớn có cờ và một yêu cầu không có. Thay đổi hành vi đi theo cờ là bằng chứng; một trang cuối cùng tải được thì không.

Nếu cờ khắc phục được, hãy quyết định vì sao

Ba điều kiện tạo ra cùng một triệu chứng và cần những phản ứng khác nhau. Đường đi có thể lọc UDP hoàn toàn, khiến cờ trở thành câu trả lời vĩnh viễn đúng cho mạng đó. Đường đi có thể cho phép UDP nhưng bỏ các datagram lớn, điều này chỉ ra MTU chứ không phải lọc. Hoặc đường đi có thể mất gói đủ nhiều để nhánh UDP chạy kém hơn TCP, đó là quyết định về dung lượng chứ không phải về khả năng kết nối.

Phân biệt chúng trước khi ghi lại một cách xử lý tạm. Lọc vẫn tồn tại ở mọi kích thước gói, vấn đề MTU chỉ xuất hiện trên một ngưỡng, và mất gói biểu hiện thành truyền lại và độ trễ biến động chứ không phải treo sạch. Mỗi phép thử thu hẹp nguyên nhân mà không đổi cấu hình client.

Kiểm tra kích thước gói trước khi giữ cách xử lý tạm

Nếu nguyên nhân là kích thước, giao diện tunnel nhận những gói mà đường đi không chở được, và vấn đề quay lại trên mọi đường truyền ngay khi tải trọng lớn lên. So sánh các giao diện: ip link show tun0 trên máy chủ, rồi docker network inspect bridge để đọc MTU được ghi trong tùy chọn mạng. Một bridge container vẫn ở 1500 byte dưới một tunnel chở ít hơn là phát hiện thường gặp.

Dò lên từ một kích thước tốt đã biết bằng phép thử cấm phân mảnh bên trong tunnel, rồi hạ MTU của mạng container hoặc siết TCP MSS trên tunnel. Mỗi cách sửa thường làm đường UDP dùng được trở lại và bỏ được nhu cầu về cờ, đó là kết quả tốt hơn khi lọc không phải nguyên nhân.

Quyết định điều bạn sẵn sàng đánh đổi

Khi kênh dữ liệu bị tắt, tunnel chở tải trọng của nó bên trong một kết nối TCP. Trên đường sạch thì chỉ chậm hơn; trên đường mất gói, một segment mất làm trễ mọi thứ phía sau và việc truyền lại bên ngoài tranh chấp với bên trong. Sự đánh đổi đó hợp với phát triển tương tác và các lời gọi API nhỏ, và không hợp với truyền dữ liệu lớn hay phiên dài qua liên kết di động.

Dù bạn chọn phương án nào, hãy ghi lại tunnel cuối cùng đã dùng đường truyền nào và vì sao. Một container âm thầm phụ thuộc vào cờ mà ai đó thêm vào nhiều tháng trước chính là sự cố tiếp theo, và người gỡ lỗi sẽ không biết cờ đó là cách xử lý tạm cho việc lọc hay tàn dư của một thí nghiệm MTU.

Bài viết liên quan