OpenVPN sidecar иштеткен поддор аттарды чечүүдө таанымал үлгү менен ийгиликсиз болушат: кластер аттары илинип калат, алыскы аттар под кайра жанганга чейин жооп берет, жана сиз өңдөгөн resolver файлы мурунку абалга кайтат. Бул ыраатта туннелдин бузулушу жок. Поддо бир resolver файлы жана эки аттар дүйнөсү бар, файл серверлерди ирети менен тизмелей алат, бирок зоналарды билдире албайт. Туруктуу чечим — поддун ичинде иштеген жана бөлүштүрүүнү ээлеген resolver, ошондо файл жөнөкөй бойдон калат жана эч бир саясаттын аны кайра жазууга себеби жок.

Сиз жасаган өзгөртүү эмне үчүн дайыма жоголот

Файл kubelet-ке таандык, сизге эмес. dnsPolicy: ClusterFirst астында kubelet аны кластер DNS-ине көрсөтүү үчүн түзөт жана контейнер башталган сайын кайра түзөт. kubectl exec аркылуу өзгөрткөнүңүз контейнердин жазууга боло турган катмарында жашайт, ошондуктан кайра жандыруу, чыгаруу же rollout аны таштайт. Под спецификациясы али да ошол эле саясатты алып жүрөт, ошондуктан ошол эле файл кайтат.

dnsPolicy: None коюу кайра түзүүнү токтотот жана кластер чечүүсүн да алып салат. Сиз көзөмөлдөгөн файлды аласыз жана керектүү аттардан ажырайсыз. Бул алмашуу — бүткүл маселе: resolv.conf зона түшүнүгүн билбейт, ирети менен сыноого тийиш серверлерди гана билет, ошондуктан cluster.local-ти бир дарекке, ал жеке зонаны башка дарекке жөнөтө албайт.

Поддо бир resolver иштетиңиз, loopback-те

Подду loopback-теги бир аттар серверине багыттаңыз, андан кийин поддун тармактык аттар мейкиндигин бөлүшкөн CoreDNS контейнерине 53 портунда жооп берүүгө уруксат бериңиз. Саясатты None-ке коюңуз, подго ошол бир даректи бериңиз жана DNS контейнерин VPN менен колдонмонун жанына кошуңуз:

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

Үч контейнер тең бир тармактык аттар мейкиндигин бөлүшөт, ошондуктан колдонмо контейнеринен 127.0.0.1:53 кызматсыз, port-forward-суз жана кластер желиси менен айланып өтпөй CoreDNS-ке жетет. Corefile-ды ConfigMap-тан mount кылу аны ордунда өңдөлүүчү файл эмес, версияланган киргизүү катары сактайт. Түзүлгөн resolv.conf андан кийин бир аттар серверин жана башка эч нерсени кармабайт, бул жөнүндө ойлонсо боло турган абал.

Бул жерде эки деталь тиштеп алат. Расмий образ 53 портун root катары байланыштырат, ал кээ бир кластер саясаттары аны ачык жазууга мажбурлайт. Поддогу ар бир контейнер эми ошол бир контейнердин иштешине коз каранды, ошондуктан зыянсыз атка каршы readiness probe кошуңуз жана колдонмого баштоо каталарын көтөрүүгө жол бериңиз.

Ар бир жеке зонага өз upstream-ин бериңиз

Corefile — зоналардын тизмеси, алардын ар бири ага жооп бере ала турган серверди атайт. Бир блок туннелдик зонаны камтыйт, ал баарын кармаган блок акыркы болуп келет жана эч бир ачык блок талап кылбаган нерсенин баарын алат. Баарын кармаган блок чыныгы upstream-ке багытталуусу керек, эч качан подго кайтпашы керек: .:53 { forward . 10.100.0.10 } кластер resolver-ин кайра пайдаланат, анткени ал resolver коомдук аттарды түйүндүн өз resolver-лерине жөнөтөт. Поддо башка эч нерсе аттын кайсы тармакка таандыгын билүүгө муктаж эмес.

.:53 {
  errors
  cache 30
  forward . 10.100.0.10
}

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

Кластер дарегин kube-system ичиндеги kube-dns кызматынан окуңуз, макаладан көчүрүүнүн ордуна, анткени кызмат CIDR-лери ар башка. Туннел дареги OpenVPN сервери жөнөткөн dhcp-option DNS маанисинен же ошол зонанын ыйгарым укуктуу серверинен келет. Эгер кластер resolver-иңиз коомдук аттарга жооп бербесе, түйүндүн resolver дарегин баарын кармаган блокко коюңуз, аны түйүндө окуп, поддун ичинде эмес.

Баарын кармаган блокту /etc/resolv.conf-ке багыттабаңыз, бул азгырткан бир сап жана дал ушул конфигурацияда тузак. dnsPolicy: None астында поддун өз файлында жалгыз аттар сервери 127.0.0.1 бар, ошондуктан бул нышана CoreDNS өзү жана дал келбеген ар бир сурамо мөөнөтү бүткөнчө кайталанат. svc.acme.internal аттуу блок ошол атка жана анын астындагы ар бир атка дал келет, бул db.svc.acme.internal-ди камтыйт жана svc.acme.internal.example.net-ды чыгарат. Акыркы чекит көрүнүштүк, анткени зона аттары толук квалификацияланган формага нормалдаштырылат; суффикс чеги сурамонун кайда түшөрүн чечет.

Жөнөтүү кластер resolver-ине таандыкпы же жокпу чечиңиз

Эгер аттар мейкиндигиндеги ар бир жумуш жүктөмүнө туннел зонасы керек болсо, kube-system астындагы CoreDNS ConfigMap-теги жөнөтүү блогу ар бир подго sidecar-дан арзан. Бул өзгөртүү кластер масштабында: ал администратор укуктарын жана баары көз каранды болгон deployment-ти кайра жандырууну талап кылат. Аны ошол бир зона менен чектеңиз, эч качан тамыр менен эмес. Бир жумуш жүктөмүнүн туннел дареги андан кийин зона үчүн ар бир поддун resolver-и болот, ал туннел кулаган күнү бүткүл кластер аттан ажырайт.

Sidecar жарылуу радиусун бир поддун ичинде кармайт, бул алыскы тармак бир аз гана кызматка керек болгондо жакшы демейки. Кайсысын тандасаңыз да, зонага кайсы resolver ээ екенин жазыңыз, анткени timeout-ту кийинки реттеген адам сурайт.

Байланыштар али да ийгиликсиз болгондо чечилүүчү аттар

Чечүү — туннел көтөрүүгө тийиш эки нерсенин бири; экинчиси кайтуу жолу, жана под желиси аны жакшы жашырат. Эгер OpenVPN серверинин өзү под катары иштесе, ошол контейнерге кошкон эрежелер түйүн аркылуу чыгат трафикти башкарбайт. Бул бузулуш тар: серверди да иштеткен түйүндөгү поддор гана жооп алышты, калганынын баары мөөнөтү бүттү.

Серверди hostNetwork: true менен иштетүү аны түйүндүн аттар мейкиндигине кайтарат, анда FORWARD эрежеси жана башталкы которуу эффективдүү болот. Клиент пулун чыгууда которуңуз, болбосо эч бир алыскы түйүндүн 10.8.0.6 сыяктуу туннел дарегине кайтуу маршруту болбойт. Corefile-га кайра тийүүдөн мурун эки багытты текшериңиз. Сурамону алып, жоопту албаган туннел сурамону эч качан албаган resolver менен дал ошол эле timeout пайда кылат.

Жаңы поддон текшериңиз, оңдогон сессияңыздан эмес

Эки зонадан тең ачык сураңыз, андан кийин под алмаштырылгандан кийин сурамону кайталаңыз. Тек иштеп жаткан контейнерде гана бар конфигурация конфигурация эмес:

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

Эгер биринчи жуп жооп берсе, ал алмаштыруудан кийинки жуп бербесе, Corefile туура, ал под спецификациясы туура эмес. Эгер экөө тең жооп берип, бирок колдонмо али да туташа албаса, DNS-ти реттееди токтотуп, контейнердин ичинен nc -vz db.svc.acme.internal 5432 менен TCP жолун текшериңиз. dig чыгышын тикетте сактаңыз, анткени ал аттык маселени маршруттоо маселесинен ажырата турган артефакт.

Тектеш макалалар