เราเพิ่งเปิดตัว Kubernetes 1.9 บน AWS โดยใช้ Kops เมื่อวานนี้ ในขณะที่เผยแพร่การรับส่งข้อมูลใหม่ไปยังคลัสเตอร์ Kubernetes ที่ใหญ่ที่สุดของเราอย่างราบรื่น ฉันเริ่มสังเกตเห็นข้อผิดพลาดการแก้ไขชื่อ DNS ที่ผิดปกติซึ่งบันทึกไว้โดยแอปพลิเคชันของเรา
มีเรื่องราวมากมายเกี่ยวกับเรื่องนี้บน GitHub kube-dns
и dnsmasq
. สิ่งที่น่าสนใจและใหม่ที่สุดสำหรับฉันคือสาเหตุที่ทำให้การรับส่งข้อมูลคำขอ DNS เพิ่มขึ้นอย่างมาก โพสต์ของฉันเกี่ยวกับเรื่องนี้และจะทำอย่างไรกับเรื่องนี้
ความละเอียด DNS ภายในคอนเทนเนอร์ เช่นเดียวกับในระบบ Linux ใดๆ จะถูกกำหนดโดยไฟล์การกำหนดค่า /etc/resolv.conf
. Kubernetes เริ่มต้น dnsPolicy
มัน ClusterFirst
ซึ่งหมายความว่าคำขอ DNS ใดๆ จะถูกส่งต่อไปยัง dnsmasq
, วิ่งอยู่ในฝัก kube-dns
ภายในคลัสเตอร์ซึ่งจะส่งต่อคำขอไปยังแอปพลิเคชัน kube-dns
หากชื่อลงท้ายด้วยส่วนต่อท้ายคลัสเตอร์ หรือมิฉะนั้น ลงท้ายด้วยเซิร์ฟเวอร์ DNS ระดับที่สูงกว่า
ไฟล์ /etc/resolv.conf
ภายในแต่ละคอนเทนเนอร์ค่าเริ่มต้นจะมีลักษณะดังนี้:
nameserver 100.64.0.10
search namespace.svc.cluster.local svc.cluster.local cluster.local
eu-west-1.compute.internal
options ndots:5
อย่างที่คุณเห็น มีสามคำสั่ง:
- เนมเซิร์ฟเวอร์คือ IP ของบริการ
kube-dns
- ระบุโดเมนการค้นหาในท้องถิ่น 4 รายการ
search
- มีตัวเลือก
ndots:5
ส่วนที่น่าสนใจของการกำหนดค่านี้คือวิธีการค้นหาโดเมนและการตั้งค่าในท้องถิ่น ndots:5
เข้ากันได้ เพื่อให้เข้าใจสิ่งนี้ คุณต้องเข้าใจว่าการแก้ไข DNS สำหรับชื่อที่ไม่เข้าเกณฑ์ทำงานอย่างไร
ชื่อเต็มคืออะไร?
ชื่อที่มีคุณสมบัติครบถ้วนคือชื่อที่จะไม่มีการค้นหาในเครื่อง และชื่อจะถือว่าสมบูรณ์ในระหว่างการจำแนกชื่อ ตามแบบแผน ซอฟต์แวร์ DNS จะถือว่าชื่อมีคุณสมบัติครบถ้วนหากลงท้ายด้วยจุด (.) และไม่มีคุณสมบัติครบถ้วน นั่นคือ google.com.
กำหนดไว้อย่างสมบูรณ์และ google.com
- เลขที่.
ชื่อที่ไม่เหมาะสมได้รับการจัดการอย่างไร?
เมื่อแอปพลิเคชันเชื่อมต่อกับโฮสต์ระยะไกลที่ระบุในชื่อ โดยทั่วไปการแก้ไขชื่อ DNS จะดำเนินการโดยใช้การเรียกของระบบ เช่น getaddrinfo()
. แต่ถ้าชื่อไม่เข้าเกณฑ์ (ไม่ได้ลงท้ายด้วย .) ฉันสงสัยว่าการเรียกของระบบจะพยายามแก้ไขชื่อเป็นชื่อที่แน่นอนก่อน หรือผ่านโดเมนการค้นหาในตัวเครื่องก่อน มันขึ้นอยู่กับตัวเลือก ndots
.
จากคู่มือ resolv.conf
:
ndots:n
устанавливает порог для количества точек, которые должны появиться в имени, прежде чем будет сделан начальный абсолютный запрос. Значение по умолчанию для n равно 1, что означает, что если в имени есть какие-либо точки, имя будет сначала опробовано как абсолютное имя, прежде чем к нему будут добавлены какие-либо элементы списка поиска.
ซึ่งหมายความว่าถ้าสำหรับ ndots
เมื่อกำหนดค่า 5 และชื่อมีน้อยกว่า 5 จุด การเรียกของระบบจะพยายามแก้ไขตามลำดับ โดยขั้นแรกให้ข้ามโดเมนการค้นหาโลคัลทั้งหมด และหากไม่สำเร็จ จะแก้ไขในที่สุดเป็นชื่อที่สมบูรณ์
ทำไมเป็นเช่นนั้น ndots:5
อาจส่งผลเสียต่อประสิทธิภาพของแอปพลิเคชันหรือไม่
ดังที่คุณสามารถจินตนาการได้ หากแอปพลิเคชันของคุณใช้การรับส่งข้อมูลภายนอกจำนวนมาก สำหรับการเชื่อมต่อ TCP ทุกครั้งที่สร้างขึ้น (หรือแม่นยำกว่านั้น สำหรับทุกชื่อที่ได้รับการแก้ไข) แอปพลิเคชันจะออกการสืบค้น DNS 5 รายการก่อนที่ชื่อจะได้รับการแก้ไขอย่างถูกต้อง เนื่องจากจะต้องผ่านขั้นตอนแรก 4 โดเมนการค้นหาในท้องถิ่นและในตอนท้ายจะออกคำขอแก้ไขชื่อที่แน่นอน
แผนภูมิต่อไปนี้แสดงปริมาณการรับส่งข้อมูลทั้งหมดในโมดูล kube-dns ทั้ง 3 โมดูลของเราก่อนและหลังจากที่เราเปลี่ยนชื่อโฮสต์สองสามชื่อที่กำหนดค่าในแอปพลิเคชันของเราเป็นชื่อที่ผ่านการรับรองโดยสมบูรณ์
แผนภาพต่อไปนี้แสดงเวลาแฝงของแอปพลิเคชันก่อนและหลังจากที่เราเปลี่ยนชื่อโฮสต์หลายชื่อที่กำหนดค่าในแอปพลิเคชันของเราเป็นชื่อเต็ม (เส้นสีน้ำเงินแนวตั้งคือการปรับใช้):
โซลูชัน #1 - ใช้ชื่อที่ผ่านการรับรองโดยสมบูรณ์
หากคุณมีชื่อภายนอกแบบคงที่ไม่กี่ชื่อ (เช่น กำหนดไว้ในการกำหนดค่าแอปพลิเคชัน) ที่คุณสร้างการเชื่อมต่อจำนวนมาก บางทีวิธีแก้ปัญหาที่ง่ายที่สุดคือการสลับชื่อเหล่านั้นเป็นชื่อที่มีคุณสมบัติครบถ้วนโดยเพียงแค่ต่อท้ายชื่อเหล่านั้น ในตอนท้าย
นี่ไม่ใช่วิธีแก้ปัญหาขั้นสุดท้าย แต่ช่วยให้สถานการณ์ดีขึ้นได้อย่างรวดเร็ว แม้ว่าจะไม่หมดจดก็ตาม เราใช้แพตช์นี้เพื่อแก้ไขปัญหาของเรา ซึ่งผลลัพธ์ที่ได้แสดงไว้ในภาพหน้าจอด้านบน
โซลูชัน # 2 - การปรับแต่ง ndots
в dnsConfig
ใน Kubernetes 1.9 ฟังก์ชันการทำงานปรากฏในโหมดอัลฟ่า (เวอร์ชันเบต้า v1.10) ซึ่งช่วยให้คุณควบคุมพารามิเตอร์ DNS ได้ดีขึ้นผ่านคุณสมบัติพ็อดใน dnsConfig
. เหนือสิ่งอื่นใด ช่วยให้คุณสามารถกำหนดค่าได้ ndots
สำหรับพ็อดเฉพาะ เช่น
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsConfig:
options:
- name: ndots
value: "1"
แหล่งที่มา
อ่านบทความอื่น ๆ ในบล็อกของเราด้วย:
ทำความเข้าใจกับแพ็คเกจบริบทใน Golang เคล็ดลับง่ายๆ สามประการในการย่อขนาดรูปภาพ Docker การสำรองข้อมูลแบบมีสถานะใน Kubernetes การสำรองข้อมูลโครงการเว็บที่ต่างกันจำนวนมาก บอทโทรเลขสำหรับ Redmine วิธีทำให้ชีวิตง่ายขึ้นสำหรับตัวคุณเองและผู้อื่น
ที่มา: will.com