Debugging Resolusi DNS

Laman ini menyediakan beberapa petunjuk untuk mendiagnosis masalah DNS.

Sebelum kamu memulai

Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klaster kamu. Jika kamu belum punya klaster, kamu dapat membuatnya dengan menggunakan Minikube, atau kamu dapat menggunakan salah satu tempat bermain Kubernetes ini:


Klaster kamu harus dikonfigurasi untuk menggunakan addonResources that extend the functionality of Kubernetes. CoreDNS atau pendahulunya, kube-dns.

Kubernetes servermu harus dalam versi yang sama atau lebih baru dari v1.6. Untuk melihat versi, tekan kubectl version.

Membuat Pod sederhana yang digunakan sebagai lingkungan pengujian

apiVersion: v1
kind: Pod
metadata:
  name: dnsutils
  namespace: default
spec:
  containers:
  - name: dnsutils
    image: gcr.io/kubernetes-e2e-test-images/dnsutils:1.3
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

Gunakan manifes berikut untuk membuat sebuah Pod:

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
pod/dnsutils created

…dan verifikasi statusnya:

kubectl get pods dnsutils
NAME      READY     STATUS    RESTARTS   AGE
dnsutils   1/1       Running   0          <some-time>

Setelah Pod tersebut berjalan, kamu dapat menjalankan perintah nslookup di lingkungan tersebut. Jika kamu melihat hal seperti ini, maka DNS sudah berjalan dengan benar.

kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10

Name:      kubernetes.default
Address 1: 10.0.0.1

Jika perintah nslookup gagal, periksa hal berikut:

Periksa konfigurasi DNS lokal terlebih dahulu

Periksa isi dari berkas resolv.conf. (Lihat Inheriting DNS dari node dan Isu-isu yang dikenal di bawah ini untuk informasi lebih lanjut)

kubectl exec -ti dnsutils -- cat /etc/resolv.conf

Verifikasi path pencarian dan nama server telah dibuat agar tampil seperti di bawah ini (perlu diperhatikan bahwa path pencarian dapat berbeda tergantung dari penyedia layanan cloud):

search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5

Kesalahan yang muncul berikut ini mengindikasikan terdapat masalah dengan add-on CoreDNS (atau kube-dns) atau Service terkait:

kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10

nslookup: can't resolve 'kubernetes.default'

atau

kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'kubernetes.default'

Periksa apakah Pod DNS sedang berjalan

Gunakan perintah kubectl get pods untuk memverifikasi apakah Pod DNS sedang berjalan.

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME                       READY     STATUS    RESTARTS   AGE
...
coredns-7b96bf9f76-5hsxb   1/1       Running   0           1h
coredns-7b96bf9f76-mvmmt   1/1       Running   0           1h
...
Catatan: Nilai dari label k8s-app adalah kube-dns baik untuk CoreDNS maupun kube-dns.

Jika kamu melihat tidak ada Pod CoreDNS yang sedang berjalan atau Pod tersebut gagal/telah selesai, add-on DNS mungkin tidak dijalankan (deployed) secara bawaan di lingkunganmu saat ini dan kamu harus menjalankannya secara manual.

Periksa kesalahan pada Pod DNS

Gunakan perintah kubectl logs untuk melihat log dari Container DNS.

Untuk CoreDNS:

kubectl logs --namespace=kube-system -l k8s-app=kube-dns

Berikut contoh log dari CoreDNS yang sehat (healthy):

.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c

Periksa jika ada pesan mencurigakan atau tidak terduga dalam log.

Apakah layanan DNS berjalan?

Verifikasi apakah layanan DNS berjalan dengan menggunakan perintah kubectl get service.

kubectl get svc --namespace=kube-system
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
...
kube-dns     ClusterIP   10.0.0.10      <none>        53/UDP,53/TCP        1h
...
Catatan: Nama layanan adalah kube-dns baik untuk CoreDNS maupun kube-dns.

Jika kamu telah membuat Service atau seharusnya Service telah dibuat secara bawaan namun ternyata tidak muncul, lihat debugging Service untuk informasi lebih lanjut.

Apakah endpoint DNS telah ekspos?

Kamu dapat memverifikasikan apakah endpoint DNS telah diekspos dengan menggunakan perintah kubectl get endpoints.

kubectl get endpoints kube-dns --namespace=kube-system
NAME       ENDPOINTS                       AGE
kube-dns   10.180.3.17:53,10.180.3.17:53    1h

Jika kamu tidak melihat endpoint, lihat bagian endpoint pada dokumentasi debugging Service.

Untuk tambahan contoh Kubernetes DNS, lihat contoh cluster-dns pada repositori Kubernetes GitHub.

Apakah kueri DNS diterima/diproses?

Kamu dapat memverifikasi apakah kueri telah diterima oleh CoreDNS dengan menambahkan plugin log pada konfigurasi CoreDNS (alias Corefile). CoreDNS Corefile disimpan pada ConfigMapSebuah objek API yang digunakan untuk menyimpan data nonkonfidensial sebagai pasangan kunci-nilai (key-value). Pod dapat menggunakan ConfigMap sebagai variabel lingkungan, argumen baris perintah (command-line), atau berkas konfigurasi dalam sebuah volume. dengan nama coredns. Untuk mengeditnya, gunakan perintah:

kubectl -n kube-system edit configmap coredns

Lalu tambahkan log pada bagian Corefile seperti contoh berikut:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        log
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          upstream
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }

Setelah perubahan disimpan, perubahan dapat memakan waktu satu hingga dua menit untuk Kubernetes menyebarkan perubahan ini pada Pod CoreDNS.

Berikutnya, coba buat beberapa kueri dan lihat log pada bagian atas dari dokumen ini. Jika pod CoreDNS menerima kueri, kamu seharusnya akan melihatnya pada log.

Berikut ini contoh kueri yang terdapat di dalam log:

.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s

Isu-isu yang Dikenal

Beberapa distribusi Linux (contoh Ubuntu) menggunakan resolver DNS lokal secara bawaan (systemd-resolved). Systemd-resolved memindahkan dan mengganti /etc/resolv.conf dengan berkas stub yang dapat menyebabkan forwarding loop yang fatal saat meresolusi nama pada server upstream. Ini dapat diatasi secara manual dengan menggunakan flag kubelet --resolv-conf untuk mengarahkan ke resolv.conf yang benar (Pada systemd-resolved, ini berada di /run/systemd/resolve/resolv.conf). kubeadm akan otomatis mendeteksi systemd-resolved, dan menyesuaikan flag kubelet sebagai mana mestinya.

Pemasangan Kubernetes tidak menggunakan berkas resolv.conf pada node untuk digunakan sebagai klaster DNS secara default, karena proses ini umumnya spesifik pada distribusi tertentu. Hal ini bisa jadi akan diimplementasi nantinya.

Libc Linux (alias glibc) secara bawaan memiliki batasan nameserver DNS sebanyak 3 rekaman (records). Selain itu, pada glibc versi yang lebih lama dari glibc-2.17-222 (versi terbaru lihat isu ini), jumlah rekaman DNS search dibatasi sejumlah 6 (lihat masalah sejak 2005 ini). Kubernetes membutuhkan 1 rekaman nameserver dan 3 rekaman search. Ini berarti jika instalasi lokal telah menggunakan 3 nameserver atau menggunakan lebih dari 3 search,sementara versi glibc kamu termasuk yang terkena dampak, beberapa dari pengaturan tersebut akan hilang. Untuk menyiasati batasan rekaman DNS nameserver, node dapat menjalankan dnsmasq,yang akan menyediakan nameserver lebih banyak. Kamu juga dapat menggunakan kubelet --resolv-conf flag. Untuk menyiasati batasan rekaman search, pertimbangkan untuk memperbarui distribusi linux kamu atau memperbarui glibc ke versi yang tidak terdampak.

Jika kamu menggunakan Alpine versi 3.3 atau lebih lama sebagai dasar image kamu, DNS mungkin tidak dapat bekerja dengan benar disebabkan masalah dengan Alpine. Masalah 30215 Kubernetes menyediakan informasi lebih detil tentang ini.

Selanjutnya

Last modified August 02, 2020 at 5:00 PM PST: Add ID localization for task/dns-debugging-resolution (28daaa4f2)