Kubernetes અને OpenVPN સાઇડકાર વચે DNS કેવી રીતે વિભાજિત કરવું
સાઇડકાર પોડને બે નામવિશ્વની જરૂર છે. એક લૂપબેક રિઝોલ્વરને ક્લસ્ટર અને ટનલ તરફ નિર્દેશ કરો, અને સંપાદિત resolv.conf પર આધાર રાખવાનું બંધ કરો.
OpenVPN સાઇડકાર ચલાવતા પોડ નામ-ઉકેલમાં ઓળખી કશીતેવી રીતે નિષ્ફળ જાય છે: ક્લસ્ટરના નામ અટકી જાય છે, દૂરના નામ પોડ ફરી શરૂ કરાય ત્યાં સુધી જવાબ આપે છે, અને તમે સંપાદિત કરેલી રિઝોલ્વર ફાઇલ પાછી ફરે છે. એ ક્રમમાં કંઈ પણ ટનલની ખામી નથી. પોડમાં એક રિઝોલ્વર ફાઇલ અને બે નામવિશ્વની હોય છે, અને ફાઇલ સર્વરોને ક્રમમાં સૂચિબદ્ધ કરી શકે પણ ઝોન વ્યક્ત કરી શકતી નથી. ટકાઉ ઉકેલ એ રિઝોલ્વર છે જે પોડની અંદર ચાલે છે અને વિભાજનનો માલિક છે, તેથી ફાઇલ સાદી રહે છે અને કોઈ નીતિને તેને ફરી લખવાનું કારણ મળતું નથી.
તમે કરેલો ફેરફાર કેમ વારંવાર અદૃશ્ય થાય છે
ફાઇલ kubeletની છે, તમારી નહીં. dnsPolicy: ClusterFirst હેઠળ kubelet તેને ક્લસ્ટર DNS તરફ નિર્દેશ કરવા માટે બનાવે છે અને દર વખતે કન્ટેનર શરૂ થાય ત્યારે તેને ફરી બનાવે છે. kubectl exec દ્વારા તમે જે પણ બદલો છો તે કન્ટેનરના લખી શકાય તેવા સ્તરમાં જીવે છે, તેથી પુનઃપ્રારંભ, બહિષ્કાર અથવા રોલઆઉટ તેને ફેંકી દે છે. પોડ સ્પેક્સ હજી પણ એ જ નીતિ ધરાવે છે, એટલે જ એ જ ફાઇલ પાછી આવે છે.
dnsPolicy: None સેટ કરવાથી પુનઃનિર્માણ અટકે છે અને ક્લસ્ટર ઉકેલ પણ દૂર થાય છે. તમને નિયંત્રિત ફાઇલ મળે છે અને જરૂરી નામો ગુમાવો છો. આ અદલાબદલી એ જ આખી સમસ્યા છે: resolv.conf ને ઝોનની કલ્પના નથી, ફક્ત ક્રમમાં અજમાવવાના સર્વરોની, તેથી તે cluster.local ને એક સરનામે અને ખાનગી ઝોનને બીજા સરનામે મોકલી શકતું નથી.
પોડમાં એક રિઝોલ્વર ચલાવો, લૂપબેક પર
પોડને લૂપબેક પરના એક જ નેમસર્વર તરફ નિર્દેશ કરો, પછી પોડનું નેટવર્ક નામસ્થાન શેર કરતા CoreDNS કન્ટેનરને પોર્ટ 53 પર જવાબ આપવા દો. નીતિને None પર સેટ કરો, પોડને એ એક સરનામું આપો, અને VPN અને એપ્લિકેશનની બાજુમાં DNS કન્ટેનર ઉમેરો:
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 સેવા વિના, પોર્ટ-ફોરવર્ડ વિના અને ક્લસ્ટર નેટવર્કમાંથી ચક્કર વિના CoreDNS સુધી પહોંચે છે. ConfigMapમાંથી Corefile માઉન્ટ કરવાથી તે સ્થળ પર સંપાદિત ફાઇલને બદલે સંસ્કરણિત ઇનપુટ રહે છે. પછી જનરેટ થયેલ resolv.conf એક નેમસર્વર અને બીજું કંઈ ધરાવતું નથી, જે એવી સ્થિતિ છે જેના વિશે તમે તર્ક કરી શકો છો.
અહીં બે વિગતો ડંખે છે. અધિકૃત ઇમેજ પોર્ટ 53ને root તરીકે બાંધે છે, અને કેટલીક ક્લસ્ટર નીતિઓ તમને તે સ્પષ્ટ લખવાની ફરજ પાડે છે. પોડનું દરેક કન્ટેનર હવે એ એક કન્ટેનર ચાલુ હોવા પર આધાર રાખે છે, તેથી નિરુપદ્રવી નામ સામે readiness પ્રોબ ઉમેરો અને એપ્લિકેશનને શરૂઆતની નિષ્ફળતાઓ સહન કરવા દો.
દરેક ખાનગી ઝોનને તેનું પોતાનું upstream આપો
Corefile ઝોનની યાદી છે, દરેક તેને જવાબ આપી શકે તેવા સર્વરનું નામ આપે છે. એક બ્લોક ટનલ ઝોનને આવરી લે છે, અને બધું પકડતો બ્લોક છેલ્લે આવે છે અને જે કોઈ સ્પષ્ટ બ્લોકે દાવો નથી કર્યો તે બધું લે છે. બધું પકડતો બ્લોકે વાસ્તવિક upstream તરફ નિશાનું ટાકવું જોઇએ, ક્યારેય પોડ તરફ પાછું નહીં: .:53 { forward . 10.100.0.10 } ક્લસ્ટર રિઝોલ્વરનો ફરી ઉપયોગ કરે છે કારણે તે રિઝોલ્વર પહેલેજ જાહેર નામોને nodeના પોતાના રિઝોલ્વર તરફ મોકલે છે. પોડમાં બીજું કંઈને જાણવાની જરૂર નથી કે નામ કયા નેટવર્કનું છે.
.: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 કિંમતમાંથી આવે છે, અથવા તે ઝોન માટેના સત્તાધિકારી સર્વરમાંથી. જો તમારું ક્લસ્ટર રિઝોલ્વર જાહેર નામોનો જવાબ આપતું ન હોય, તો nodeના રિઝોલ્વરનું સરનામું બધું પકડતા બ્લોકમાં મૂકો, જે node પર વાંચવાનું છે, પોડની અંદર નહીં.
બધું પકડતા બ્લોકને /etc/resolv.conf તરફ નિર્દેશ ન કરો, જે લાલચજનક એક-લીટી છે અને આ ચોક્કસ સેટઅપમાં જાળ છે. dnsPolicy: None હેઠળ પોડની પોતાની ફાઇલમાં એકમાત્ર નેમસર્વર 127.0.0.1 છે, તેથી એ લક્ષ CoreDNS પોતે જ છે અને દરેક ન મળતી ક્વેરી સમયસીમા સુધી પુનરાવર્તિત થાય છે. svc.acme.internal નામનો બ્લોક એ નામ અને તેની નીચેના દરેક નામ સાથે મેળ ખાય છે, જે db.svc.acme.internal ને આવરી લે છે અને svc.acme.internal.example.net ને બાકાત કરે છે. અંતિમ બિંદુ દેખાવાનું છે, કારણે ઝોન નામો સંપૂર્ણ લાયકાતવાળા સ્વરૂપમાં સામાન્ય થાય છે; પ્રત્યયની સીમા નક્કી કરે છે કે ક્વેરી કયાં ઉતરે છે.
નક્કી કરો કે ફોરવર્ડ ક્લસ્ટર રિઝોલ્વરમાં હોવો જોઇએ કે નહીં
જો નામસ્થાનના દરેક વર્કલોડને ટનલ ઝોન જોઈએ, તો kube-system હેઠળ CoreDNS ConfigMapમાં ફોરવર્ડ બ્લોક દરેક પોડ માટે સાઇડકાર કરતાં સસ્તું છે. એ ફેરફાર ક્લસ્ટર-સ્તરીય છે: તેને એડમિનિસ્ટ્રેટર અધિકારો અને એવા ડિપ્લોયમેન્ટનું પુનઃપ્રારંભ જોઈએ જેના પર બધા આધાર રાખે છે. તેને એ એક જ ઝોન સુધી મર્યાદિત રાખો, ક્યારેય મૂળ સુધી નહીં. એક વર્કલોડનું ટનલ સરનામું પછી ઝોન માટે દરેક પોડનું રિઝોલ્વર બની જાય છે, અને જિસ દિવસે ટનલ પડે છે તે દિવસે આખું ક્લસ્ટર નામ ગુમાવે છે.
સાઇડકાર વિસ્ફોટ ત્રિજ્યાને એક પોડમાં રાખે છે, જે ત્યારે સારૂં સ્મેન મૂલ્ય હોય છે જ્યારે ફક્ત થોડીક સેવાઓને દૂરનું નેટવર્ક જોઈએ. તમે ગમે તે પસંદ કરો, લખો કે કયું રિઝોલ્વર ઝોનનું માલિક છે, કારણે આગળની વ્યક્તિ જે ટાઇમઆઉટ ડિબગ કરશે તે પૂસશે.
નામ જે ઉકેલાય છે જ્યારે કનેક્શન હજી નિષ્ફળ જાય છે
ઉકેલ એ બે વસ્તુઓમાંથી એક છે જે ટનલે વહન કરવી પડે; બીજી છે પરત માર્ગ, અને પોડ નેટવર્ક તેને સારી રીતે છુપાવે છે. જો OpenVPN સર્વર પોતે પોડ તરીકે ચાલે છે, તો તે કન્ટેનરમાં ઉમેરેલા નિયમો node દ્વારા બહાર જતા ટ્રાફિકને નિયંત્રિત નથી કરતા. એ નિષ્ફળતા સંકડી છે: ફક્ત તે node પરના પોડ કે જે સર્વર પણ ચલાવતા હતા તેમને જવાબ મળ્યા, અને બાકી બધું સમયસીમા ગયું.
સર્વરને hostNetwork: true સાથે ચલાવવું તેને nodeના નામસ્થાનમાં પાછું લાવે છે, જ્યાં FORWARD નિયમ અને સ્રોત અનુવાદ અસર કરે છે. બહાર જતી વખતે ક્લાઇન્ટ પૂલનું અનુવાદ કરો, નહીં તો કોઈ દૂરના node પાસે 10.8.0.6 જેવા ટનલ સરનામા સુધી પાછો માર્ગ નહીં હોય. Corefileને ફરી સ્પર્શ કરતા પહેલાં બન્ને દિશાઓ તપાસો. જે ટનલ ક્વેરી વહન કરે પણ જવાબ નહીં, તે તે જ ટાઇમઆઉટ ઉત્પન્ન કરે છે જે રિઝોલ્વરને ક્વેરી ક્યારેય મળી ન હોય તેવા થાય છે.
નવા પોડમાંથી ચકાસો, તમે સુધારેલા સત્રમાંથી નહીં
બન્ને ઝોનને સ્પષ્ટ પૂસો, પછી પોડ બદલાયા પછી ક્વેરીનું પુનરાવર્તન કરો. ફક્ત ચાલતા કન્ટેનરમાં જ અસ્તિત્વ ધરાવતું રૂપરેખાંકન રૂપરેખાંકન નથી:
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 આઉટપુટ ટિકિટમાં રાખો, કારણે તે જ એ કલાકૃતિ છે જે નામની સમસ્યાને રાઉટિંગની સમસ્યાથી અલગ કરે છે.