May berdeng tunnel ang laptop mo, sinasabi ng client log na naipush ang mga ruta, at ang tanging address na sumasagot ay ang tunnel IP ng mismong VPN server. Namamatay ang mga ping sa kabila nito kahit ano pa ang target, ClusterIP man, address ng ibang pod o pampublikong hostname. Ang kombinasyong iyon ay diagnostic, hindi malabo: gumagana ang decapsulation, at hindi ang ikalawang hop.

Naabutan ko ito sa isang Debian node na nagpapatakbo ng OpenVPN image na inilagay ng chart, at ang tunnel ang madaling bahagi. Nakuha ng kliyente ang 10.8.0.x lease, sumagot ang 10.8.0.1, at nag-timeout ang 10.96.0.10, ang cluster DNS service. Walang mukhang may sakit sa server log, at iyon ang dahilan kung bakit nagsisimula ang mga tao na muling isulat ang iptables rules na hindi naman nila kailangang hawakan.

Ang VPN pod ay isang router, at sulit sabihin ito nang tuwiran. Dumarating ang mga naka-encrypt na packet, binubuksan sa sariling network namespace ng pod, at pagkatapos ay kailangang lumabas sa ibang interface. Tinatanggihan ng Linux ang ikalawang hakbang na iyon maliban kung naka-enable ang forwarding sa loob ng mismong namespace na iyon.

Ano ang naaabot at hindi naaabot ng kliyente

Ang address na sumasagot ay pag-aari ng dulo ng tunnel, at hawak ito ng VPN process nang lokal, kaya wala talagang kinalaman ang forwarding. Ang lahat ng iba pa, kasama ang ibang pod, service VIP o internet, ay nangangailangan na ilipat ng kernel ang packet mula tun0 patungong eth0. Kapag tinanggihan ang paglipat na iyon, ang sintomas ay pantay na katahimikan at hindi pagtanggi, dahil walang gumagawa ng ICMP error pabalik sa tunnel. Nakakakuha ka ng timeout, hindi mga mensaheng hindi maabot, at iyon ang palatandaan na walang sinumang nagru-route talaga.

Dalawang minuto ng klasipikasyon ang nagpapaliit sa layer. Kung nabigo ang mga DNS name habang nagtagumpay ang hilaw na ping sa IP ng serbisyo, ang problema ay nasa tubo ng DNS, hindi sa forwarding. Kung nag-timeout ang bawat destinasyon sa kabila ng peer address, kasama ang hubad na IP, magsimula sa namespace.

Basahin ang setting sa loob ng namespace

Bawat pod ay may sariling network namespace, at ang net.ipv4.ip_forward ay sysctl kada namespace. Ang pagbabago nito sa node ay walang sinasabi tungkol sa container, at ito ay maaasahang paraan ng paggugol ng hapon sa maling makina.

kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0

Kinukumpirma ng zero ang diagnosis. Hindi rin namamana ang value mula sa runtime configuration ng node: nagsisimula ito sa default ng image tuwing may ginagawang container. Kaya ang ayos na inilapat sa kamay gamit ang kubectl exec ... sysctl -w ay nawawala sa susunod na restart at bumabalik bilang depektong mukhang paminsan-minsan.

I-enable ito para mapanatili ito ng manifest

Ang matibay na opsyon ay isang init container na tumatakbo sa parehong pod sandbox at nagsusulat ng value bago magsimula ang VPN container. Nagbabahagi ng network namespace ang mga container sa isang pod, kaya napupunta ang setting sa pangunahing container.

initContainers:
- name: enable-forwarding
  image: busybox:1.36
  command: ["sysctl", "-w", "net.ipv4.ip_forward=1"]
  securityContext:
    privileged: true

Ang privileged: true na iyon ang linyang tinututulan ng mga reviewer, at tama sila. Ang pagsulat ng sysctl ay nangangailangan ng pribilehiyo o makitid na kakayahan, at ang cluster na nagpapatakbo ng restricted Pod Security Standard ay maaaring tumanggi nang ganap sa pribilehiyadong init container. Kung tatanggihan ng admission ang pod, malalaman mo sa paggawa, na kahit papaano ay tapat at madaling basahin.

Ang mas malinis na alternatibo ay ang listahan ng securityContext.sysctls sa antas ng pod, na nagpapahintulot sa kubelet na maglapat ng namespaced sysctl nang hindi nagbibigay ng pribilehiyo sa anumang container. Sinasaklaw lamang nito ang mga pangalan sa allowlist ng cluster. Kung ang net.ipv4.ip_forward ay nasa listahang iyon ay nakadepende sa kung paano na-configure ang kubelet, at ang pod na humihingi ng sysctl sa labas nito ay tinatanggihan sa admission o natigil sa CreateContainerConfigError habang sinusubukan muli ang sandbox. Suriin ang allowlist bago ipalagay na sira ang field.

Bago ka magtayo ng alinman sa dalawang paraan nang manu-mano, tingnan kung inilalabas na ng chart ang switch, kadalasan bilang isang bagay na tulad ng ipForwardInitContainer: true. Ang paggamit ng value ng chart ay nagpapanatiling maliit ang override file mo at nakakalampas sa susunod na upgrade, na hindi nagagawa ng manual na patch sa Deployment.

Ang ikalawang kalahati: daan pabalik at patakaran

Kailangan ang naka-enable na forwarding, hindi sapat. Kung gumagamit ang mga kliyente ng pribadong pool na walang ruta ang cluster network, hindi mahanap ng mga sagot ang daan pabalik sa tunnel, at kailangang i-masquerade ng pod ang trapik na iyon patungo sa destinasyon nito.

Nasa ibabaw nito ang patakaran. Ang mga NetworkPolicy object at cloud firewall rule ay sinusuri laban sa source address na dala ng packet pagkatapos ng translation, kaya ang rule na isinulat para sa pool ng kliyente ay maaaring tumigil sa pagtutugma nang tahimik kapag naka-enable ang masquerading.

Kapag kailangan lamang ng mga kliyente na maabot ang mga serbisyo sa loob ng cluster, ang pagtatapos ng VPN sa VIP ng serbisyo ay mas maliit na disenyo kaysa sa pagru-route papasok sa pod network. Pinapanatili rin nito ang pool ng kliyente sa labas ng routing table ng CNI.

Ihiwalay ang nabigong hop mula sa kliyente

Magtrabaho paluwas at huminto sa unang tahimik na hakbang. Magsimula sa VPN peer, pagkatapos subukan ang address ng ilang pod, pagkatapos ang VIP ng serbisyo, at pagkatapos lamang ang pampublikong destinasyon. Bawat tagumpay ay naglilipat ng hangganan ng isang hop, at bawat kabiguan ay pinangalanan ang layer na dapat suriin. Pagkatapos ng anumang rollout, pumasok gamit ang exec at basahin muli ang sysctl, dahil ang pinalitang pod ay nagsisimula sa default ng image at ang ayos na hindi kailanman nasa manifest ay wala na.

Ang dokumentasyon ng Kubernetes tungkol sa paggamit ng sysctl sa isang cluster ay naglilista kung aling mga pangalan ang maitatakda sa pamamagitan ng security context ng pod, at iyon ang unang lugar na titingnan kapag tinanggihan ng admission ang pagbabago.

Kaugnay na mga artikulo