Den berbare datamaskinen din viser ein grøn tunnel, klientloggen melder at ruter vart pusha, og den einaste adressa som svarar, er VPN-tenaren si eiga tunnel-IP. Ping vidare døyr uansett kva du siktar på, anten det er ein ClusterIP, adressa til ein annan pod eller eit offentleg vertsnamn. Den kombinasjonen er diagnostisk og ikkje vag: dekapsulering verkar, og det andre hoppet gjer det ikkje.

Eg møtte dette på ein Debian-node som køyrde eit chart-installert OpenVPN-image, og tunnelen var den enkle delen. Klienten fekk ein 10.8.0.x-lease, 10.8.0.1 svara, og 10.96.0.10, DNS-tenesta til klynga, tima ut. Ingenting i tenarloggen såg sjukt ut, og det er nettopp derfor folk byrjar å skrive om iptables-reglar dei aldri trong å røre.

Ein VPN-pod er ein ruter, og det er verdt å seie rett ut. Krypterte pakkar kjem inn, blir pakka ut i poden sitt eige nettverksnamespace og må deretter ut gjennom eit anna grensesnitt. Linux nektar det andre trinnet med mindre videresending er slått på inne i nettopp det namespace-et.

Kva klienten kan og ikkje kan nå

Adressa som svarar, høyrer til endepunktet til tunnelen, og VPN-prosessen eig ho lokalt, så videresending er ikkje involvert i det heile. Alt anna, inkludert ein annan pod, ein teneste-VIP eller internett, treng at kjernen flyttar ein pakke frå tun0 til eth0. Når den flyttinga blir nekta, er symptomet einsarta stillheit og ikkje ei avvising, fordi ingenting genererer ein ICMP-feil tilbake nedover tunnelen. Du får tidsavbrot, ikkje uoppnåelege-meldingar, og det er teiknet på at ingen ruter i det heile.

To minutt klassifisering snevrar inn laget. Viss DNS-namn feilar medan rå ping mot ein teneste-IP lukkast, er problemet DNS-røyrlegging, ikkje videresending. Viss kvar destinasjon utanfor peer-adressa timar ut, også ein bar IP, start ved namespace-et.

Les innstillinga inne i namespace-et

Kvar pod får sitt eige nettverksnamespace, og net.ipv4.ip_forward er ein sysctl per namespace. Å endre han på noden fortel deg ingenting om containeren, og det er ein påliteleg måte å bruke ein ettermiddag på feil maskin.

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

Ein null stadfester diagnosen. Verdien blir heller ikkje arva frå køyretidskonfigurasjonen til noden: han startar frå imaget sin standard kvar gong ein container blir oppretta. Ei retting brukt manuelt med kubectl exec ... sysctl -w forsvinn derfor ved neste omstart og kjem tilbake som ein feil som verkar periodisk.

Slå det på slik at manifestet held på det

Det varige alternativet er ein init-container som køyrer i same pod-sandbox og skriv verdien før VPN-containeren startar. Containarar i ein pod deler nettverksnamespace, så innstillinga følgjer med inn i hovudcontaineren.

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

Nettopp privileged: true er linja meldarane protesterer mot, og dei har rett. Å skrive ein sysctl krev anten privilegium eller ein smalt avgrensa evne, og ei klynge som køyrer den restriktive Pod Security Standard kan avvise ein privilegert init-container heilt. Viss admission avviser poden, får du vite det ved opprettinga, noko som i det minste er ærleg og lett å lese.

Det reinare alternativet er securityContext.sysctls-lista på pod-nivå, som lèt kubelet bruke namespacede sysctlar utan å gi privilegium til nokon container. Ho dekkjer berre namn på allowlista til klynga. Om net.ipv4.ip_forward står på den lista, avheng av korleis kubelet vart konfigurert, og ein pod som ber om ein sysctl utanfor ho, blir avvist ved admission eller heng i CreateContainerConfigError medan sandboxen blir prøvd på nytt. Sjekk allowlista før du går ut frå at feltet er øydelagt.

Før du byggjer nokon av tilnærmingane for hand, sjå om chartet allereie eksponerer brytaren, ofte som noko i retning av ipForwardInitContainer: true. Å bruke chartverdien held overstyringsfila di lita og overlever neste oppgradering, noko handpatching av Deployment-endringar ikkje gjer.

Den andre halvdelen: returveg og policy

Videresending på er naudsynt, ikkje tilstrekkeleg. Viss klientar brukar ein privat pool som klyngenettet ikkje har rute til, finn ikkje svar vegen tilbake i tunnelen, og poden må maskere den trafikken mot destinasjonen sin.

Policy ligg oppå. NetworkPolicy-objekt og skybrannmurreglar blir vurderte mot kildeadressa ein pakke ber etter omsetjing, så ein regel skriven for klientpoolen kan stille slutte å passe når maskering er slått på.

Når klientar berre treng å nå tenester inne i klynga, er det ein mindre konstruksjon å la VPN-en terminere på tenesta sin VIP enn å rute inn i podnettet. Det held også klientpoolen heilt utanfor rutetabellen til CNI-en.

Isolere det feilande hoppet frå klienten

Arbeid utover og stopp ved det første stille trinnet. Start med VPN-peeren, prøv deretter adressa til ein eller annan pod, så ein teneste-VIP, og først etter det ein offentleg destinasjon. Kvar suksess flyttar grensa eitt hopp, og kvar feil namngir laget som er verdt å undersøkje. Etter kvar utrulling går du inn og les sysctlen på nytt, fordi ein erstatta pod startar frå imaget sin standard, og ei retting som aldri var i manifestet, er allereie borte.

Kubernetes-dokumentasjonen om å bruke sysctls i ei klynge listar kva namn som kan setjast gjennom sikkerheitskonteksten til poden, og det er det første staden å sjå når admission avviser endringa.

Relaterte artiklar