Pod yang menjalankan sidecar OpenVPN gagal menyelesaikan nama dengan corak yang mudah dikenali: nama kluster tergantung, nama jauh menjawab sehingga pod dimulakan semula, dan fail resolver yang anda edit kembali seperti asal. Tiada apa dalam urutan itu merupakan kerosakan terowong. Sebuah pod mempunyai satu fail resolver dan dua dunia penamaan, dan fail itu boleh menyenaraikan pelayan mengikut urutan tetapi tidak boleh menyatakan zon. Pembaikan yang tahan lama ialah resolver yang berjalan di dalam pod dan memiliki pemisahan itu, jadi failnya kekal mudah dan tiada dasar mempunyai sebab untuk menulisnya semula.

Mengapa suntingan yang anda buat sentiasa hilang

Fail itu milik kubelet, bukan milik anda. Di bawah dnsPolicy: ClusterFirst kubelet menjananya untuk menunjuk ke DNS kluster, dan menjananya semula setiap kali kontena bermula. Apa sahaja yang anda ubah melalui kubectl exec hidup dalam lapisan boleh tulis kontena, jadi mula semula, pengusiran atau roll-out membuangnya. Spesifikasi pod masih membawa dasar yang sama, itulah sebabnya fail yang sama kembali.

Menetapkan dnsPolicy: None menghentikan penjanaan semula dan juga membuang penyelesaian kluster. Anda mendapat fail yang anda kawal dan kehilangan nama yang anda perlukan. Pertukaran itu ialah keseluruhan masalah: resolv.conf tidak mempunyai tanggapan zon, hanya pelayan yang perlu dicuba mengikut urutan, jadi ia tidak boleh menghantar cluster.local ke satu alamat dan zon peribadi ke alamat lain.

Jalankan satu resolver dalam pod, pada loopback

Halakan pod ke satu pelayan nama pada loopback, kemudian biarkan kontena CoreDNS yang berkongsi ruang nama rangkaian pod menjawab pada port 53. Tetapkan dasar kepada None, beri pod alamat tunggal itu, dan tambah kontena DNS di sebelah VPN dan aplikasi:

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

Ketiga-tiga kontena berkongsi satu ruang nama rangkaian, jadi 127.0.0.1:53 daripada kontena aplikasi mencapai CoreDNS tanpa perkhidmatan, tanpa port-forward dan tanpa lencongan melalui rangkaian kluster. Melekap Corefile daripada ConfigMap mengekalkannya sebagai input berversi dan bukannya fail yang diedit di tempat. resolv.conf yang dijana kemudian memegang satu pelayan nama dan tiada yang lain, keadaan yang boleh anda fikirkan.

Dua butiran menggigit di sini. Imej rasmi mengikat port 53 sebagai root, dan sesetengah dasar kluster menuntut anda menulisnya secara eksplisit. Setiap kontena dalam pod kini bergantung pada kontena tunggal itu hidup, jadi tambah probe readiness terhadap nama yang tidak berbahaya dan biarkan aplikasi bertolak ansur dengan kegagalan permulaan.

Beri setiap zon peribadi upstreamnya sendiri

Corefile ialah senarai zon, setiap satu menamakan pelayan yang boleh menjawabnya. Satu blok meliputi zon terowong, dan blok tangkap-semua datang terakhir dan mengambil apa sahaja yang tidak dituntut oleh blok eksplisit. Blok tangkap-semua mesti menyasarkan upstream sebenar, jangan sekali-kali kembali ke pod: .:53 { forward . 10.100.0.10 } menggunakan semula resolver kluster kerana ia sudah memajukan nama awam ke resolver nod itu sendiri. Tiada apa lagi dalam pod perlu tahu rangkaian mana sesuatu nama milik.

.:53 {
  errors
  cache 30
  forward . 10.100.0.10
}

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

Baca alamat kluster daripada perkhidmatan kube-dns dalam kube-system dan bukannya menyalinnya daripada artikel, kerana CIDR perkhidmatan berbeza. Alamat terowong datang daripada nilai dhcp-option DNS yang dihantar oleh pelayan OpenVPN, atau daripada pelayan berwibawa untuk zon itu. Jika resolver kluster anda tidak menjawab nama awam, letakkan alamat resolver nod dalam blok tangkap-semua, dibaca pada nod dan bukan di dalam pod.

Jangan halakan blok tangkap-semua ke /etc/resolv.conf, yang merupakan satu baris yang menggoda dan perangkap dalam persediaan yang tepat ini. Di bawah dnsPolicy: None fail pod itu sendiri mengandungi satu-satunya pelayan nama 127.0.0.1, jadi sasaran itu ialah CoreDNS sendiri dan setiap pertanyaan yang tidak sepadan berulang sehingga tamat masa. Blok bernama svc.acme.internal sepadan dengan nama itu dan setiap nama di bawahnya, yang meliputi db.svc.acme.internal dan mengecualikan svc.acme.internal.example.net. Titik di hujung adalah kosmetik, kerana nama zon dinormalkan kepada bentuk yang layak sepenuhnya; sempadan akhiran menentukan di mana pertanyaan mendarat.

Tentukan sama ada pemajuan itu milik resolver kluster

Jika setiap beban kerja dalam ruang nama memerlukan zon terowong, blok pemajuan dalam ConfigMap CoreDNS di bawah kube-system lebih murah daripada sidecar setiap pod. Perubahan itu berskala kluster: ia memerlukan hak pentadbir dan mula semula deployment yang menjadi sandaran semua orang. Hadkan kepada zon itu sahaja, jangan sekali-kali ke akar. Alamat terowong satu beban kerja kemudian menjadi resolver setiap pod untuk zon itu, dan pada hari terowong putus seluruh kluster kehilangan nama itu.

Sidecar menyimpan jejari letupan di dalam satu pod, yang merupakan lalai lebih baik apabila hanya beberapa perkhidmatan memerlukan rangkaian jauh. Apa sahaja yang anda pilih, catat resolver mana yang memiliki zon itu, kerana orang seterusnya yang menyahpepijat tamat masa akan bertanya.

Nama yang masih diselesaikan semasa sambungan masih gagal

Penyelesaian ialah satu daripada dua perkara yang terowong mesti bawa; yang lain ialah laluan balik, dan rangkaian pod menyembunyikannya dengan baik. Jika pelayan OpenVPN sendiri berjalan sebagai pod, peraturan yang anda tambah dalam kontena itu tidak mengawal trafik yang keluar melalui nod. Kegagalan itu sempit: hanya pod pada nod yang juga menjalankan pelayan mendapat jawapan, dan semua yang lain tamat masa.

Menjalankan pelayan dengan hostNetwork: true mengembalikannya ke ruang nama nod, di mana peraturan FORWARD dan terjemahan sumber berkuat kuasa. Terjemahkan kolam klien semasa keluar, jika tidak tiada nod jauh mempunyai laluan balik ke alamat terowong seperti 10.8.0.6. Semak kedua-dua arah sebelum menyentuh Corefile lagi. Terowong yang membawa pertanyaan tetapi bukan jawapannya menghasilkan tamat masa yang sama seperti resolver yang tidak pernah menerima pertanyaan.

Sahkan daripada pod baharu, bukan daripada sesi yang anda baiki

Tanya kedua-dua zon secara eksplisit, kemudian ulangi pertanyaan selepas pod diganti. Konfigurasi yang hanya wujud dalam kontena yang berjalan bukan konfigurasi:

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

Jika pasangan pertama menjawab dan pasangan selepas penggantian tidak, Corefile betul dan spesifikasi pod tidak. Jika kedua-duanya menjawab tetapi aplikasi masih tidak dapat menyambung, berhenti menyahpepijat DNS dan uji laluan TCP dengan nc -vz db.svc.acme.internal 5432 dari dalam kontena. Simpan output dig dalam tiket, kerana itulah artifak yang memisahkan masalah penamaan daripada masalah penghalaan.

Artikel berkaitan