Menyiapkan NodeLocal DNSCache


Halaman ini menjelaskan cara meningkatkan latensi pencarian DNS di cluster Google Kubernetes Engine (GKE) menggunakan NodeLocal DNSCache.

Untuk cluster GKE Autopilot, NodeLocal DNSCache diaktifkan secara default dan tidak dapat diganti.

Arsitektur

NodeLocal DNSCache adalah add-on GKE yang dapat Anda jalankan selain kube-dns.

GKE mengimplementasikan NodeLocal DNSCache sebagai DaemonSet yang menjalankan cache DNS pada setiap node di cluster Anda.

Saat Pod membuat permintaan DNS, permintaan tersebut akan ditujukan ke cache DNS yang berjalan di node yang sama dengan Pod. Jika cache tidak dapat menyelesaikan permintaan DNS, cache akan meneruskan permintaan ke salah satu tempat berikut berdasarkan tujuan kueri:

  • kube-dns: semua kueri untuk domain DNS cluster (cluster.local) akan diteruskan ke kube-dns. Pod node-local-dns menggunakan Layanan kube-dns-upstream untuk mengakses Pod kube-dns. Pada diagram berikut, alamat IP Layanan kube-dns adalah 10.0.0.10:53.
  • Domain stub kustom atau server nama upstream: kueri diteruskan langsung dari Pod NodeLocal DNSCache.
  • Cloud DNS: semua kueri lainnya diteruskan ke server metadata lokal yang berjalan di node yang sama dengan Pod tempat kueri berasal. Server metadata lokal mengakses Cloud DNS.

Jalur permintaan DNS, seperti yang dijelaskan di paragraf sebelumnya.

Jika Anda mengaktifkan NodeLocal DNSCache di cluster yang ada, GKE akan membuat ulang semua node cluster yang menjalankan GKE versi 1.15 dan yang lebih baru sesuai dengan proses upgrade node.

Setelah GKE membuat ulang node, GKE otomatis menambahkan label addon.gke.io/node-local-dns-ds-ready=true ke node tersebut. Anda tidak boleh menambahkan label ini ke node cluster secara manual.

Manfaat NodeLocal DNSCache

NodeLocal DNSCache memberikan manfaat berikut:

  • Mengurangi waktu pencarian DNS rata-rata
  • Koneksi dari Pod ke cache lokal tidak membuat entri tabel conntrack. Hal ini mencegah koneksi terputus dan ditolak yang disebabkan oleh kehabisan tabel conntrack dan kondisi race.
  • Anda dapat menggunakan NodeLocal DNSCache dengan Cloud DNS untuk GKE.
  • Kueri DNS untuk URL eksternal (URL yang tidak merujuk ke resource cluster) akan diteruskan langsung ke server metadata Cloud DNS lokal, dengan mengabaikan kube-dns.
  • Cache DNS lokal akan otomatis mengambil domain stub dan server nama upstream yang ditentukan dalam kube-dns ConfigMap.

Persyaratan dan batasan

  • NodeLocal DNSCache menggunakan resource komputasi di setiap node cluster Anda.
  • NodeLocal DNSCache tidak didukung dengan node pool Windows Server.
  • NodeLocal DNSCache memerlukan GKE versi 1.15 atau yang lebih baru.
  • NodeLocal DNSCache mengakses Pod kube-dns menggunakan TCP.
  • NodeLocal DNSCache mengakses upstreamServers dan stubDomains menggunakan TCP dan UDP di GKE versi 1.18 atau yang lebih baru. Server DNS harus dapat dijangkau menggunakan TCP dan UDP.
  • Data DNS di-cache selama periode berikut:
    • Time to live (TTL) kumpulan data, atau 30 detik jika TTL lebih dari 30 detik.
    • 5 detik jika respons DNS adalah NXDOMAIN.
  • Pod NodeLocal DNSCache memproses port 53, 9253, 9353, dan 8080 pada node. Jika Anda menjalankan Pod hostNetwork lainnya atau mengonfigurasi hostPorts dengan port tersebut, NodeLocal DNSCache akan gagal dan error DNS akan terjadi. Pod NodeLocal DNSCache tidak menggunakan mode hostNetwork saat menggunakan GKE Dataplane V2 dan Cloud DNS untuk GKE.
  • Cache DNS lokal hanya berjalan di node pool yang menjalankan GKE versi 1.15 dan yang lebih baru. Jika Anda mengaktifkan NodeLocal DNSCache di cluster dengan node yang menjalankan versi sebelumnya, Pod pada node tersebut akan menggunakan kube-dns.

Mengaktifkan NodeLocal DNSCache

Untuk cluster Autopilot, NodeLocal DNSCache diaktifkan secara default dan tidak dapat diganti.

Untuk cluster Standard, Anda dapat mengaktifkan NodeLocal DNSCache di cluster baru atau yang sudah ada menggunakan Google Cloud CLI. Anda dapat mengaktifkan NodeLocal DNSCache di cluster baru menggunakan Konsol Google Cloud.

Mengaktifkan NodeLocal DNSCache di cluster baru

gcloud

Untuk mengaktifkan NodeLocal DNSCache di cluster baru, gunakan flag --addons dengan argumen NodeLocalDNS:

gcloud container clusters create CLUSTER_NAME \
    --location=COMPUTE_LOCATION \
    --addons=NodeLocalDNS

Ganti kode berikut:

Konsol

Untuk mengaktifkan NodeLocal DNSCache di cluster baru, gunakan langkah-langkah berikut:

  1. Buka halaman Google Kubernetes Engine di Konsol Google Cloud.

    Buka Google Kubernetes Engine

  2. Di samping Standard, klik Configure.

  3. Konfigurasi cluster sesuai keinginan Anda.

  4. Dari panel navigasi, klik Networking.

  5. Di bagian Advanced networking options, centang kotak Enable NodeLocal DNSCache.

  6. Klik Create.

Mengaktifkan NodeLocal DNSCache di cluster yang ada

Untuk mengaktifkan NodeLocal DNSCache di cluster yang ada, gunakan flag --update-addons dengan argumen NodeLocalDNS=ENABLED:

gcloud container clusters update CLUSTER_NAME \
    --update-addons=NodeLocalDNS=ENABLED

Ganti kode berikut:

  • CLUSTER_NAME: nama cluster Anda.

Perubahan ini memerlukan pembuatan ulang node, yang dapat menyebabkan gangguan pada workload yang sedang berjalan. Untuk mengetahui detail tentang perubahan khusus ini, temukan baris yang sesuai dalam tabel perubahan manual yang membuat ulang node menggunakan strategi upgrade node dan mematuhi kebijakan pemeliharaan. Untuk mempelajari update node lebih lanjut, lihat Merencanakan gangguan update node.

Memastikan NodeLocal DNSCache telah diaktifkan

Anda dapat memverifikasi bahwa NodeLocal DNSCache sudah berjalan dengan mencantumkan Pod node-local-dns:

kubectl get pods -n kube-system -o wide | grep node-local-dns

Outputnya mirip dengan hal berikut ini:

node-local-dns-869mt    1/1   Running   0   6m24s   10.128.0.35   gke-test-pool-69efb6b8-5d7m   <none>   <none>
node-local-dns-htx4w    1/1   Running   0   6m24s   10.128.0.36   gke-test-pool-69efb6b8-wssk   <none>   <none>
node-local-dns-v5njk    1/1   Running   0   6m24s   10.128.0.33   gke-test-pool-69efb6b8-bhz3   <none>   <none>

Output menunjukkan Pod node-local-dns untuk setiap node yang menjalankan GKE versi 1.15 atau yang lebih baru.

Menonaktifkan NodeLocal DNSCache

Anda dapat menonaktifkan NodeLocal DNSCache menggunakan perintah berikut:

gcloud container clusters update CLUSTER_NAME \
    --update-addons=NodeLocalDNS=DISABLED

Ganti kode berikut:

  • CLUSTER_NAME: nama cluster yang akan dinonaktifkan.

Perubahan ini memerlukan pembuatan ulang node, yang dapat menyebabkan gangguan pada workload yang sedang berjalan. Untuk mengetahui detail tentang perubahan khusus ini, temukan baris yang sesuai dalam tabel perubahan manual yang membuat ulang node menggunakan strategi upgrade node dan mematuhi kebijakan pemeliharaan. Untuk mempelajari update node lebih lanjut, lihat Merencanakan gangguan update node.

Memecahkan masalah NodeLocal DNSCache

Untuk mengetahui informasi umum tentang mendiagnosis masalah DNS Kubernetes, lihat Men-debug Resolusi DNS.

NodeLocal DNSCache tidak langsung diaktifkan

Saat Anda mengaktifkan NodeLocal DNSCache di cluster yang ada, GKE mungkin tidak langsung mengupdate node jika cluster tersebut memiliki jendela pemeliharaan atau pengecualian yang dikonfigurasi. Untuk informasi selengkapnya, lihat catatan untuk masa pemeliharaan dan pembuatan ulang node.

Jika tidak ingin menunggu, Anda dapat menerapkan perubahan pada node secara manual dengan memanggil perintah gcloud container clusters upgrade dan meneruskan flag --cluster-version dengan versi GKE yang sama dengan yang sudah dijalankan node pool. Anda harus menggunakan Google Cloud CLI untuk solusi ini.

NodeLocal DNSCache dengan Cloud DNS

Jika Anda menggunakan NodeLocal DNSCache dengan Cloud DNS, cluster akan menggunakan alamat IP server nama 169.254.20.10, seperti yang ditunjukkan dalam diagram berikut:

NodeLocal DNSCache dengan arsitektur Cloud DNS.

Akibatnya, alamat IP Layanan kube-dns mungkin berbeda dengan alamat IP server nama yang digunakan Pod Anda. Perbedaan alamat IP ini diharapkan, karena alamat IP server nama 169.254.20.10 diperlukan agar Cloud DNS berfungsi dengan benar.

Untuk memeriksa alamat IP, jalankan perintah berikut:

  1. Lihat alamat IP Layanan kube-dns:

    kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"
    

    Output-nya adalah alamat IP kube-dns, seperti 10.0.0.10:53

  2. Buka sesi shell di Pod Anda:

    kubectl exec -it POD_NAME -- /bin/bash
    
  3. Dalam sesi shell Pod, baca konten file /etc/resolv.conf:

    cat /etc/resolv.conf
    

    Outputnya adalah 169.254.20.10

Kebijakan jaringan dengan NodeLocal DNSCache

Jika Anda menggunakan kebijakan jaringan dengan NodeLocal DNSCache dan tidak menggunakan Cloud DNS atau GKE Dataplane V2, Anda harus mengonfigurasi aturan untuk mengizinkan workload dan Pod node-local-dns untuk mengirim kueri DNS.

Gunakan aturan ipBlock dalam manifes untuk mengizinkan komunikasi antara Pod dan kube-dns.

Manifes berikut menjelaskan kebijakan jaringan yang menggunakan aturan ipBlock:

spec:
  egress:
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
    to:
    - ipBlock:
        cidr: KUBE_DNS_SVC_CLUSTER_IP/32
  podSelector: {}
  policyTypes:
    - Egress

Ganti KUBE_DNS_SVC_CLUSTER_IP dengan alamat IP layanan kube-dns. Anda bisa mendapatkan alamat IP layanan kube-dns menggunakan perintah berikut:

kubectl get svc -n kube-system kube-dns -o jsonpath="{.spec.clusterIP}"

Masalah umum

Waktu tunggu DNS di dnsPolicy ClusterFirstWithHostNet saat menggunakan NodeLocal DNSCache dan GKE Dataplane V2

Pada cluster yang menggunakan GKE Dataplane V2 dan NodeLocal DNSCache, pod dengan hostNetwork yang ditetapkan ke true dan dnsPolicy yang ditetapkan ke ClusterFirstWithHostNet tidak dapat menjangkau backend DNS cluster. Log DNS mungkin berisi entri yang mirip dengan yang berikut ini:

nslookup: write to 'a.b.c.d': Operation not permitted

;; connection timed out; no servers could be reached

Output menunjukkan bahwa permintaan DNS tidak dapat menjangkau server backend.

Solusinya adalah menetapkan dnsPolicy dan dnsConfig untuk pod hostNetwork:

spec:
 dnsPolicy: "None"
 dnsConfig:
   nameservers:
     - KUBE_DNS_UPSTREAM
   searches:
     - cluster.local
     - svc.cluster.local
     - NAMESPACE.svc.cluster.local
     - c.PROJECT_ID.internal
     - google.internal
   options:
     - name: ndots
       value: "5"

Ganti kode berikut:

  • NAMESPACE: namespace pod hostNetwork.
  • PROJECT_ID: ID project Google Cloud Anda.
  • KUBE_DNS_UPSTREAM: ClusterIP layanan kube-dns upstream. Anda bisa mendapatkan nilai ini menggunakan perintah berikut:

    kubectl get svc -n kube-system kube-dns-upstream -o jsonpath="{.spec.clusterIP}"
    

Permintaan DNS dari Pod kini dapat menjangkau kube-dns dan mengabaikan NodeLocal DNSCache.

Error waktu tunggu NodeLocal DNSCache

Pada cluster dengan NodeLocal DNSCache yang diaktifkan, log mungkin berisi entri yang serupa dengan yang berikut ini:

[ERROR] plugin/errors: 2 <hostname> A: read tcp <node IP: port>-><kubedns IP>:53: i/o timeout

Output-nya mencakup alamat IP Layanan IP Cluster kube-dns-upstream. Dalam contoh ini, respons terhadap permintaan DNS tidak diterima dari kube-dns dalam 2 detik. Hal ini mungkin disebabkan oleh salah satu alasan berikut:

  • Masalah konektivitas jaringan yang mendasarinya.
  • Secara signifikan meningkatkan kueri DNS dari workload atau karena peningkatan jumlah node.

Akibatnya, pod kube-dns yang ada tidak dapat menangani semua permintaan secara tepat waktu. Solusinya adalah meningkatkan jumlah replika kube-dns dengan menyesuaikan parameter penskalaan otomatis.

Meningkatkan skala kube-dns

Anda dapat menggunakan nilai yang lebih rendah untuk nodesPerReplica guna memastikan bahwa lebih banyak Pod kube-dns yang dibuat saat node cluster ditingkatkan skalanya. Sebaiknya tetapkan nilai max eksplisit untuk memastikan bahwa mesin virtual (VM) bidang kontrol GKE tidak kewalahan karena banyaknya pod kube-dns yang menonton API Kubernetes.

Anda dapat menetapkan max ke jumlah node dalam cluster. Jika cluster memiliki lebih dari 500 node, tetapkan max ke 500.

Untuk cluster Standar, Anda dapat mengubah jumlah replika kube-dns dengan mengedit ConfigMap kube-dns-autoscaler. Konfigurasi ini tidak didukung di cluster Autopilot.

kubectl edit configmap kube-dns-autoscaler --namespace=kube-system

Outputnya mirip dengan hal berikut ini:

linear: '{"coresPerReplica":256, "nodesPerReplica":16,"preventSinglePointFailure":true}'

Jumlah replika kube-dns dihitung menggunakan formula berikut:

replika = max( ceil( cores × 1/coresPerReplica ) , ceil( nodes × 1/nodesPerReplica ), maxValue )

Untuk meningkatkan skala, ubah nodesPerReplica ke nilai yang lebih kecil dan sertakan nilai max.

linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"preventSinglePointFailure":true}'

Konfigurasi ini akan membuat 1 pod kube-dns untuk setiap 8 node dalam cluster. Cluster dengan 24 node akan memiliki 3 replika dan cluster 40 node akan memiliki 5 replika. Jika cluster berkembang melebihi 120 node, jumlah replika kube-dns tidak bertambah melebihi 15, yaitu nilai max.

Untuk memastikan tingkat dasar ketersediaan DNS di cluster Anda, tetapkan jumlah replika minimum untuk kube-dns.

Output ConfigMap kube-dns-autoscaler dengan kolom min akan mirip dengan yang berikut ini:

linear: '{"coresPerReplica":256, "nodesPerReplica":8,"max": 15,"min": 5,"preventSinglePointFailure":true}'

Langkah selanjutnya