Vì sao pod GKE không tới được máy chủ nội bộ qua VPN
Node tới được mạng nội bộ, pod thì không. Các ngoại lệ masquerade của GKE để địa chỉ pod không được dịch cho đích 10.x.
Ping chạy được từ node và thất bại từ pod, và không có gì tới được phía nội bộ. Đường hầm và tuyến đều ổn; địa chỉ nguồn trên dây thì không. Điều phân biệt hai trường hợp này là gói tin tự nhận mình là gì khi rời khỏi cụm, và GKE có ý kiến về điều đó. Cơ chế là một danh sách ngoại lệ masquerade, và đọc nó chỉ cần một lệnh.
Đọc danh sách đang có hiệu lực trước khi đổi bất cứ thứ gì
GKE cung cấp một agent quyết định, theo từng dải đích, liệu lưu lượng của pod có được ghi lại thành địa chỉ node khi đi ra hay không. Cấu hình đi kèm của nó nêu ba khối RFC1918, 10.0.0.0/8, 172.16.0.0/12 và 192.168.0.0/16, là các đích được miễn trừ. Vì vậy mọi thứ bạn gửi từ pod tới máy chủ 10.x nội bộ đều rời node với địa chỉ của chính pod vẫn còn gắn. Lưu lượng của chính node không bị ghi lại, và đó chính là lý do ping của node chạy được.
Hãy đọc cấu hình dự kiến và các quy tắc đã cài, vì chúng có thể không khớp nhau. kubectl -n kube-system get configmap ip-masq-agent -o yaml cho thấy agent được báo điều gì, và kubectl -n kube-system get pods -l k8s-app=ip-masq-agent cho thấy có gì đang chạy để áp dụng nó. Trên một node, iptables-save | grep -i masq cho thấy các quy tắc thực sự tồn tại trong nhân. Khi ConfigMap nói một đằng và quy tắc nói một nẻo, đối tượng đáng ngờ là agent chứ không phải mạng.
Xác nhận địa chỉ nguồn bằng một lần bắt gói
Hãy bắt gói trước khi đổi danh sách. Bộ lọc trên một đích duy nhất giữ đầu ra dễ đọc: tcpdump -ni any host 10.20.30.40.
So sánh điều đó với những gì phía bên kia báo cáo. Một lần bắt gói tại chỗ cho thấy địa chỉ pod và không có phản hồi sẽ khép vòng lặp: danh sách ngoại lệ giải thích sự bất đối xứng mà không có lỗi đường hầm nào. Hai quan sát về một địa chỉ nguồn là đủ để thôi đoán mò về CNI.
Thu hẹp ngoại lệ về CIDR của pod
Bản sửa được hỗ trợ thu hẹp ngoại lệ thay vì loại bỏ nó: giữ CIDR của pod được miễn trừ và bỏ phần còn lại của không gian 10.x. Danh sách đó nằm trong ConfigMap của agent dưới nonMasqueradeCIDRs, và thay đổi nó là một lần sửa rồi triển khai. Thay mục rộng bằng dải pod thực tế của cụm, giữ các khối riêng tư khác nếu lưu lượng trong cụm vẫn cần, và để resyncInterval yên trừ khi bạn có lý do. Áp dụng, xác nhận pod của agent đã khởi động lại và xác nhận quy tắc trong nhân đã thay đổi.
Đây là thay đổi toàn cụm với bán kính ảnh hưởng thực. Sau khi áp dụng, lưu lượng trước đây giữ nguồn pod giờ đến với địa chỉ đã được ghi lại thành node, nên mọi thứ dựa vào những địa chỉ pod đó sẽ thấy một người gửi khác. Nạn nhân là log, danh sách cho phép và quy tắc tường lửa nội bộ nêu địa chỉ pod, và chúng hỏng một cách âm thầm. Hãy công bố thay đổi này như một thay đổi hành vi, không phải một bản sửa lỗi.
Trong cụm có nhiều pool node, hãy kiểm tra agent có được lập lịch trên các node nơi pod bị ảnh hưởng thực sự chạy hay không. Pool không có DaemonSet giữ quy tắc cũ của nó, và không gì trong ConfigMap cho thấy điều đó.
Phương án thay thế và cái giá của nó
Lựa chọn còn lại giữ nguyên địa chỉ pod và dạy tuyến về chúng. CIDR của pod đi vào bộ chọn lưu lượng của Cloud VPN, và phía nội bộ cần một tuyến quay về cho nó để phản hồi biết đi đâu. Điều đó bảo toàn danh tính pod, thứ mà một số mô hình bảo mật muốn, và nó mở rộng cả phạm vi định tuyến lẫn phạm vi tường lửa mà phía bên kia phải chấp nhận.
Sự đánh đổi là khả năng đọc so với phạm vi. Dịch địa chỉ khiến phía nội bộ thấy một địa chỉ cho mỗi node, dễ đưa vào danh sách cho phép và che đi pod nào gửi gì. Không dịch thì địa chỉ pod được giữ từ đầu đến cuối, tốt hơn cho việc quy trách nhiệm và tệ hơn cho mọi thiết bị trên đường đi phải học một dải mới. Không lựa chọn nào là lỗi của Docker hay CNI; cả hai đều là quyết định định tuyến kèm hóa đơn vận hành. Hãy chọn cái mà đội của bạn trả được, và viết ra lý do.
Kiểm chứng và hoàn tác
Chạy lại đúng lần bắt gói đó. Nếu lần bắt gói ở mức node vẫn in ra địa chỉ pod sau khi bạn sửa, nghĩa là quy tắc chưa bao giờ thay đổi, bất kể ConfigMap nói gì. Dây là sự thật; phần còn lại là suy đoán.
Sau đó kiểm tra chiều ngược lại, vì một nửa các thay đổi này chỉ được kiểm chứng ở chiều đi. Xác nhận phản hồi tới được node hoặc pod đã gửi yêu cầu, và xác nhận ứng dụng đã hoàn tất chứ không chỉ nhận được SYN. Một lần bắt gói cho thấy yêu cầu mà không có phản hồi là vấn đề định tuyến ở phía bên kia, không phải vấn đề masquerade ở phía này.
Hoàn tác là ConfigMap trước đó, áp dụng theo cùng cách, với cùng xác nhận rằng agent đã khởi động lại và quy tắc đã thay đổi. Hãy lưu địa chỉ nguồn trước và sau cho một yêu cầu đã biết trong hồ sơ thay đổi, vì chính dòng đó chứng minh thay đổi đã làm đúng như bạn nói. Hướng dẫn agent masquerade IP của GKE ghi lại các giá trị mặc định và trường ConfigMap. Nếu địa chỉ nguồn không đổi sau khi triển khai, agent không chạy trên node đó và không bản sửa YAML nào khắc phục được.