Kubernetes пен OpenVPN sidecar арасында DNS-ті қалай бөлуге болады
Sidecar подына екі аттар әлемі қажет. Бір loopback resolver-ді кластер мен туннельге бағыттаңыз және өңделген resolv.conf-қа тәуелділікті тоқтатыңыз.
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 шығысын тикетте сақтаңыз, өйткені ол ат мәселесін маршруттау мәселесінен ажырататын артефакт.