
Belum lama ini, kami meluncurkan Kubernetes 1.9 di AWS menggunakan Kops. Kemarin, sementara dengan lancar meluncurkan lalu lintas baru ke kelompok Kubernetes terbesar kami, saya mulai melihat kesalahan resolusi nama DNS yang tidak biasa yang dicatat oleh aplikasi kami.
GitHub membicarakan hal ini cukup lama, jadi saya juga memutuskan untuk mencari tahu. Pada akhirnya, saya menyadari bahwa dalam kasus kami ini adalah karena peningkatan beban pada kube-dns
dan dnsmasq
. Yang paling menarik dan baru bagi saya adalah alasan utama peningkatan lalu lintas permintaan DNS. Tentang ini dan apa yang harus dilakukan dengan itu, posting saya.
Resolusi DNS di dalam wadah - seperti halnya sistem Linux lainnya - ditentukan oleh file konfigurasi /etc/resolv.conf
. Secara default, Kubernetes dnsPolicy
adalah ClusterFirst
, yang berarti bahwa setiap permintaan DNS akan dialihkan ke dnsmasq
berjalan di kube-dns
di dalam cluster, yang pada gilirannya akan mengarahkan kueri ke aplikasi kube-dns
jika namanya berakhir dengan akhiran cluster, atau jika tidak, ke server DNS tingkat yang lebih tinggi.
File /etc/resolv.conf
di dalam setiap wadah akan terlihat seperti ini secara default:
nameserver 100.64.0.10 search namespace.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal options ndots:5
Seperti yang Anda lihat, ada tiga arahan:
- Server nama adalah layanan IP dari
kube-dns
- 4 domain pencarian lokal ditentukan
- Ada opsi
ndots:5
Bagian yang menarik dari konfigurasi ini adalah bagaimana domain pencarian lokal dan ndots:5
pengaturan bergaul. Untuk memahami ini, Anda perlu memahami cara kerja resolusi DNS untuk sebagian nama.
Apa nama lengkapnya?
Nama yang sepenuhnya memenuhi syarat adalah nama yang tidak akan dilakukan pencarian lokal, dan nama tersebut akan dianggap mutlak selama resolusi nama. Secara konvensional, perangkat lunak DNS menganggap nama sepenuhnya memenuhi syarat jika diakhiri dengan tanda titik (.), Dan tidak sepenuhnya ditentukan sebaliknya. Itu adalah google.com.
sepenuhnya ditentukan, tetapi google.com
tidak.
Bagaimana menangani nama yang tidak lengkap?
Ketika aplikasi terhubung ke host jarak jauh yang ditentukan dalam nama, resolusi nama DNS biasanya dilakukan menggunakan panggilan sistem, misalnya, getaddrinfo()
. Tetapi jika nama itu tidak lengkap (tidak berakhir dengan.), Saya bertanya-tanya apakah panggilan sistem akan mencoba untuk menyelesaikan nama sebagai absolut terlebih dahulu, atau akankah ia pergi melalui domain pencarian lokal terlebih dahulu? Itu tergantung pada opsi ndots
.
Dari manual di resolv.conf
:
ndots:n , , . n 1, , - , , - .
Ini berarti bahwa jika ndots
diatur ke 5 dan namanya mengandung kurang dari 5 poin, system call akan mencoba menyelesaikannya secara berurutan, pertama dengan menelusuri semua domain pencarian lokal, dan, jika tidak berhasil, pada akhirnya akan menyelesaikannya sebagai nama absolut.
Mengapa ndots:5
mempengaruhi kinerja aplikasi?
Seperti yang Anda pahami, jika aplikasi Anda menggunakan banyak lalu lintas eksternal, untuk setiap koneksi TCP yang dibuat (atau, lebih tepatnya, untuk setiap nama yang diselesaikan), ia akan mengeluarkan 5 permintaan DNS sebelum nama tersebut diselesaikan dengan benar, karena akan melalui 4 terlebih dahulu domain pencarian lokal, dan pada akhirnya akan mengeluarkan permintaan resolusi nama absolut.
Diagram berikut menunjukkan total trafik pada modul 3 kube-dns kami sebelum dan sesudah kami mengganti beberapa nama host yang dikonfigurasi dalam aplikasi kami menjadi yang sepenuhnya ditentukan.

Diagram berikut menunjukkan penundaan aplikasi sebelum dan sesudah kami mengganti beberapa nama host yang dikonfigurasi dalam aplikasi kami menjadi penuh (garis biru vertikal adalah penyebaran):

Solusi # 1 - gunakan nama yang sepenuhnya memenuhi syarat
Jika Anda memiliki beberapa nama eksternal statis (yaitu, ditentukan dalam konfigurasi aplikasi) yang Anda buat sejumlah besar koneksi, mungkin solusi paling sederhana adalah dengan mengubahnya menjadi yang didefinisikan sepenuhnya dengan hanya menambahkannya. pada akhirnya.
Ini bukan keputusan akhir, tetapi membantu dengan cepat, meskipun tidak bersih, memperbaiki situasi. Kami menerapkan tambalan ini untuk menyelesaikan masalah kami, yang hasilnya ditunjukkan pada tangkapan layar di atas.
Solusi # 2 - menyesuaikan ndots
di dnsConfig
Di Kubernetes 1.9, fitur muncul dalam mode alfa (versi beta v1.10), yang memungkinkan kontrol parameter DNS yang lebih baik melalui properti pod di dnsConfig
. Antara lain, ini memungkinkan Anda untuk menyesuaikan nilai ndots
untuk perapian tertentu, mis.
apiVersion: v1 kind: Pod metadata: namespace: default name: dns-example spec: containers: - name: test image: nginx dnsConfig: options: - name: ndots value: "1"
Sumber
Baca juga artikel lain di blog kami: