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 സേവനയും, port-forward-ും, ക്ലസ്റ്റർ നെറ്റ്വർക്ക് ചുറ്റിയും ഇല്ലാതെ CoreDNS-ൽ എത്തുന്നു. ConfigMap-ൽ നിന്ന് Corefile മൗണ്ട് ചെയ്യുന്നത് അതിനെ സ്ഥലത്ത് എഡിറ്റ് ചെയ്യുന്ന ഫയലിനു പകരം പതിപ്പുസംസ്കരണം ചെയ്യപ്പെട്ട ഇൻപുട്ടായി നിർത്തുന്നു. സൃഷ്ടിപ്പിച്ച resolv.conf അപ്പോൾ ഒരു നെയിംസെർവറും അതിനപുറം ഒന്നും വഹിക്കുന്നില്ല, അതിനെക്കുറിച്ച് യുക്തികൾ ചെയ്യാവുന്ന ഒരു അവസ്ഥയാണ് അത്.
ഇവിടെ രണ്ട് കാര്യങ്ങൾ കടിക്കുന്നു. ഔദ്യോഗിക ഇമേജ് പോർട്ട് 53 root ആയി ബന്ധിക്കുന്നു, ചില ക്ലസ്റ്റർ നയങ്ങൾ അത് വ്യക്തമായി എഴുതാൻ നിർബന്ധിക്കുന്നു. ഇപ്പോൾ പോഡിലെ ഓരോ കണ്ടെയ്നറും ആ ഒരു കണ്ടെയ്നർ പ്രവർത്തിക്കുന്നതിനെ ആശ്രയിക്കുന്നു, അതിനാൽ ഹാനികരമില്ലാത്ത നാമത്തിനെത്തിരെ readiness പ്രോബ് ചേർക്കുക, ആപ്ലിക്കേഷനെ സ്റ്റാർട്ടപ്പ് പരാജയങ്ങൾ സഹിക്കാൻ അനുവദിക്കുക.
ഓരോ സ്വകാര്യ മേഖലയ്ക്കും അതിന്റേതായ upstream നൽകുക
Corefile എന്നത് മേഖലകളുടെ പട്ടിയാണ്, ഓരോന്നും അതിന് മറുപടി നൽകാവുന്ന സെർവറിന് പേരു നൽകുന്നു. ഒരു ബ്ലോക്ക് ടണൽ മേഖലയെ ഉൾക്കൊള്ളുന്നു, എല്ലാം പിടിക്കുന്ന ബ്ലോക്ക് അവസാനത്തിൽ വരുന്നു, ഒരു വ്യക്തമായ ബ്ലോക്കും ആവശ്യപ്പെടുത്താത്തതെല്ലാം എടുക്കുന്നു. എല്ലാം പിടിക്കുന്ന ബ്ലോക്ക് യഥാർത്ഥമായ upstream-ലേക്ക് ലക്ഷ്യമിടേണ്ടത്, ഒരിക്കലും പോഡിലേക്ക് തിരികെ പോകരുതുത്: .:53 { forward . 10.100.0.10 } ക്ലസ്റ്റർ റിസോൾവറെ വീണ്ടും ഉപയോഗിക്കുന്നു, കാരണം ആ റിസോൾവർ ഇതിനകം പൊതുനാമങ്ങൾ നോഡിന്റെ സ്വന്ത റിസോൾവറുകളിലേക്ക് കൈമാറുന്നു. പോഡിലെ മറ്റൊന്നിനും ഒരു നാമം ഏത് നെറ്റ്വർക്ക് പെടുന്നു എന്ന് അറിയേണ്ടതില്ല.
.: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 മൂല്യത്തിൽ നിന്നോ ആ മേഖലയുടെ അധികാര സെർവറിൽ നിന്നോ വരുന്നു. നിങ്ങളുടെ ക്ലസ്റ്റർ റിസോൾവർ പൊതുനാമങ്ങൾക്ക് മറുപടി നൽകുന്നില്ലെങ്കിൽ, നോഡിന്റെ റിസോൾവർ വിലാസം എല്ലാം പിടിക്കുന്ന ബ്ലോക്കിൽ ഇടുക, അത് നോഡിൽ വായിച്ചതായിരിക്കണം, പോഡിനുള്ളില്ല.
എല്ലാം പിടിക്കുന്ന ബ്ലോക്ക് /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-ൽ ഒരു ഫോർവർഡിംഗ് ബ്ലോക്ക് ഓരോ പോഡിനും ഒരു സൈഡ്കാറിനെക്കാൾ ചെലവുകുറവാണ്. ആ മാറ്റം ക്ലസ്റ്റർ തലത്തിലാണ്: അതിന് അഡ്മിനിസ്റ്റ്റ്റർ അവകാശങ്ങളും, എല്ലാവരും ആശ്രയിക്കുന്ന ഒരു ഡിപ്ലോയ്മെണ്റ്റിന്റെ പുനരാരംഭവും വേണം. അതിനെ ആ ഒരു മേഖലയിലേക്ക് പരിമിതമാക്കുക, ഒരിക്കലും മൂലത്തേക്ക് അല്ല. ഒരു വർക്ക്ലോഡിന്റെ ടണൽ വിലാസം അപ്പോൾ ആ മേഖലയ്ക്ക് ഓരോ പോഡിന്റെയും റിസോൾവറാകുന്നു, ടണൽ വീഴുന്ന ദിവസം മുഴുവൻ ക്ലസ്റ്ററും നാമം നഷ്ടപ്പെടുന്നു.
സൈഡ്കാർ സ്ഫോടന ആരം ഒരു പോഡിനുള്ളിൽ നിർത്തുന്നു, കുറഞ്ഞ സേവനങ്ങൾക്ക് മാത്രം ദൂര നെറ്റ്വർക്ക് വേണ്ടിവരുമ്പോൾ അതാണ് മികച്ച സ്ഥിരമൂല്യം. എന്ത് തിരഞ്ഞെടുത്താലും, ഏത് റിസോൾവർ മേഖല സ്വന്തമാക്കുന്നു എന്ന് എഴുതിവയ്ക്കുക, കാരണം അടുത്തതായി timeout ഡീബഗ് ചെയ്യുന്ന ആള് അത് ചോദിക്കും.
ബന്ധങ്ങൾ ഇപ്പോഴും പരാജയപ്പെടുമ്പോൾ പരിഹരിക്കുന്ന നാമങ്ങൾ
പരിഹാരം ടണൽ വഹിക്കേണ്ട രണ്ട് കാര്യങ്ങളിൽ ഒന്നാണ്; മറ്റൊന്ന് മടക്കപ്പാതയാണ്, പോഡ് നെറ്റ്വർക്ക് അത് നന്നായി മറയ്ക്കുന്നു. OpenVPN സെർവർ തന്നെ ഒരു പോഡായി പ്രവർത്തിക്കുന്നുവെങ്കിൽ, ആ കണ്ടെയ്നറിൽ നിങ്ങൾ ചേർക്കുന്ന നിയമങ്ങൾ നോഡിലൂടെ പുറത്തുപോകുന്ന ട്രാഫ്ഫിക്കാ നിയന്ത്രണം ചെയ്യുന്നില്ല. ആ പരാജയം ഇടുങ്ങിയതാണ്: സെർവർ പ്രവർത്തിപ്പിച്ച നോഡിലെ പോഡുകള് മാത്രം മറുപടി ലഭിച്ചു, ബാക്കിയെല്ലാം സമയപരിധി കഴിഞ്ഞു.
സെർവറിനെ hostNetwork: true-മായി പ്രവർത്തിപ്പിക്കുന്നത് അതിനെ നോഡിന്റെ നാമസ്ഥലത്തിലേക്ക് തിരികെ കൊണ്ടുവരുന്നു, അവിടെ FORWARD നിയമവും സ്രോതസ്സ് വിവർത്തനവും പ്രവർത്തിക്കുന്നു. പുറത്തുപോകുമ്പോൾ ക്ലൈയന്റ് പൂൾ വിവർത്തനം ചെയ്യുക, അല്ലെങ്കിൽ 10.8.0.6 പോലെ ഒരു ടണൽ വിലാസത്തിലേക്ക് തിരികെയുള്ള വഴി ഒരു ദൂര നോഡിനും ഉണ്ടാകില്ല. Corefile വീണ്ടും സ്പർശിക്കുന്നതിന് മുമ്പ് രണ്ട് ദിശകളും പരിശോധിക്കുക. ക്വറി വഹിച്ചു മറുപടി വഹിക്കാത്ത ടണൽ, ക്വറി ഒരിക്കലും ലഭിക്കാത്ത റിസോൾവറിനെപ്പോലെ അതേ 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 ഔട്ടുപ്പുട് ടിക്കറ്റിൽ സൂക്ഷിക്കുക, കാരണം നാമപ്രശ്നത്തെ റൂട്ടിംഗ് പ്രശ്നത്തിൽ നിന്ന് വേർത്തിരിക്കുന്ന കലാസൃഷ്ടി അതാണ്.