Pod-ar som køyrer ein OpenVPN-sidecar feilar i namneoppslag med eit gjenkjenneleg mønster: klyngenamn heng, fjernnamn svarar til pod-en blir starta på nytt, og resolver-fila du redigerte går tilbake. Ingenting i den sekvensen er ein tunnelfeil. Ein pod har éi resolver-fil og to navneverder, og fila kan liste serverar i rekkjefølgje men ikkje uttrykkje soner. Den varige løysinga er ein resolver som køyrer inne i pod-en og eig delinga, slik at fila blir enkel og ingen policy har grunn til å skrive henne på nytt.

Kvifor endringa du gjorde stadig forsvinn

Fila høyrer til kubelet, ikkje deg. Under dnsPolicy: ClusterFirst genererer kubelet henne for å peike på klynge-DNS, og genererer henne på nytt kvar gong ein container startar. Alt du endrar via kubectl exec lever i det skrivbare laget til containeren, så omstart, utkasting eller rollout kastar det. Pod-spesifikasjonen ber framleis same policy, og difor kjem same fila tilbake.

Å setje dnsPolicy: None stoppar regenereringa og fjernar òg klyngeoppslaget. Du får ei fil du kontrollerer og mistar namna du trong. Det bytet er heile problemet: resolv.conf har ikkje omgrep om soner, berre serverar som blir prøvde i rekkjefølgje, så han kan ikkje sende cluster.local til éin adresse og ei privat sone til ei anna.

Køyr éin resolver i pod-en, på loopback

Pek pod-en mot éin namneservar på loopback, og la deretter ein CoreDNS-container som deler nettverksnamnerommet til pod-en svare på port 53. Set policyen til None, gi pod-en den eine adressa, og legg til DNS-containeren ved sida av VPN-en og applikasjonen:

spec:
  dnsPolicy: None
  dnsConfig:
    nameservers:
      - 127.0.0.1
    options:
      - name: ndots
        value: "5"
  containers:
    - name: dns
      image: coredns/coredns
      args: ["-conf", "/etc/coredns/Corefile"]
      volumeMounts:
        - {name: corefile, mountPath: /etc/coredns, readOnly: true}
    - name: vpn
      image: your-openvpn-client-image
    - name: app
      image: your-app-image
  volumes:
    - name: corefile
      configMap:
        name: split-dns-corefile

Alle tre containerane deler eitt nettverksnamnerom, så 127.0.0.1:53 frå applikasjonscontaineren når CoreDNS utan teneste, utan port-forward og utan omveg gjennom klyngenettet. Å montere Corefile frå ein ConfigMap held henne som versjonert input i staden for ei fil som blir redigert på staden. Den genererte resolv.conf held då éin namneservar og ingenting anna, ein tilstand du kan resonnere om.

To detaljar bit her. Det offisielle imaget bind port 53 som root, og enkelte klyngepolicyar krev at du skriv det eksplisitt. Kvar container i pod-en er no avhengig av at den eine containeren køyrer, så legg til ein readiness-probe mot eit ufarleg namn og la applikasjonen tole oppstartsfeil.

Gi kvar privat sone sin eigen upstream

Ein Corefile er ei liste over soner, kvar nemner serveren som kan svare på henne. Éin blokk dekkjer tunnel-sona, og catch-all-blokka kjem sist og tek alt ingen eksplisitt blokk har kravd. Catch-all må peike på ein ekte upstream, aldri tilbake til pod-en: .:53 { forward . 10.100.0.10 } brukar klynge-resolveren om att fordi han alt videresender offentlege namn til resolverane til noden sjølv. Ingenting anna i pod-en treng å vite kva nettverk eit namn høyrer til.

.:53 {
  errors
  cache 30
  forward . 10.100.0.10
}

svc.acme.internal:53 {
  errors
  cache 30
  forward . 192.168.240.1
}

Les klyngeadressa frå kube-dns-tenesta i kube-system i staden for å kopiere ei frå ein artikkel, fordi teneste-CIDR-ane varierer. Tunneladressa kjem frå dhcp-option DNS-verdien OpenVPN-serveren sender, eller frå den autoritative serveren for sona. Viss klynge-resolveren din ikkje svarar på offentlege namn, legg resolveradressa til noden i catch-all-blokka, lesen på noden og ikkje inne i pod-en.

Ikkje peik catch-all mot /etc/resolv.conf, som er den freistande einlinjaren og ei felle i nett dette oppsettet. Under dnsPolicy: None inneheld fila til pod-en sjølv den einaste namneservaren 127.0.0.1, så målet er CoreDNS sjølv og kvar spørjing som ikkje passar blir gjenteken til ho går ut på tid. Ei blokk kalla svc.acme.internal passar det namnet og kvart namn under det, som dekkjer db.svc.acme.internal og utelèt svc.acme.internal.example.net. Punktumet til slutt er kosmetisk, fordi sonenamn blir normaliserte til fullt kvalifisert form; suffiksgrensa avgjer kvar ei spørjing landar.

Avgjer om videresendinga høyrer til klynge-resolveren

Viss kvar arbeidslast i namnerommet treng tunnel-sona, er ei videresendingsblokk i CoreDNS ConfigMap under kube-system billegare enn ein sidecar per pod. Den endringa er på klyngenivå: ho krev administratortilgang og omstart av ein deployment alle er avhengige av. Avgrense henne til den eine sona, aldri til rota. Tunneladressa til éin arbeidslast blir då resolveren for kvar pod for sona, og dagen tunnelen fell mistar heile klynga namnet.

Sidecaren held eksplosjonsradiusen inne i éin pod, som er ein betre standard når berre nokre få tenester treng fjernnettet. Uansett kva du vel, noter kva resolver som eig sona, fordi neste person som feilsøkjer ein timeout vil spørje.

Namn som blir løyste medan tilkoplingar framleis feilar

Oppslag er éin av to ting tunnelen må bere; den andre er returvegen, og pod-nettet skjuler han godt. Viss OpenVPN-serveren sjølv køyrer som ein pod, styrer ikkje reglane du legg til i den containeren trafikken som går ut via noden. Feilen er smal: berre pod-ane på noden som òg køyrde serveren fekk svar, og alt anna gjekk ut på tid.

Å køyre serveren med hostNetwork: true set han tilbake i namnerommet til noden, der ein FORWARD-regel og kjeldeomsetting verkar. Set om klientpoolen på veg ut, elles har ingen ekstern node ein rute tilbake til ei tunneladresse som 10.8.0.6. Sjekk båe retningar før du rører Corefile igjen. Ein tunnel som ber spørjinga men ikkje svaret gir nøyaktig same timeout som ein resolver som aldri fekk spørjinga.

Verifiser frå ein ny pod, ikkje frå økta du reparerte

Spør begge sonene eksplisitt, og gjenta deretter spørjinga etter at pod-en er bytt ut. Ein konfigurasjon som berre finst i ein køyrande container er ikkje ein konfigurasjon:

kubectl exec -it deploy/app -- dig @127.0.0.1 kubernetes.default.svc.cluster.local +short
kubectl exec -it deploy/app -- dig @127.0.0.1 db.svc.acme.internal +short
kubectl delete pod -l app=your-app
kubectl wait --for=condition=Ready pod -l app=your-app --timeout=90s
kubectl exec -it deploy/app -- dig @127.0.0.1 db.svc.acme.internal +short

Viss det første paret svarar og paret etter utskiftinga ikkje gjer det, er Corefile rett og pod-spesifikasjonen ikkje. Viss begge svarar og applikasjonen framleis ikkje får samband, slutt å feilsøkje DNS og test TCP-vegen med nc -vz db.svc.acme.internal 5432 frå innsida av containeren. Ta vare på dig-utdata i saka, fordi det er artefakten som skil eit namneproblem frå eit ruteproblem.

Relaterte artiklar