DNS และ Service Discovery
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”CoreDNS ให้ทุก Service มี DNS name ที่คาดเดาได้ ทำให้ Pod หากันด้วยชื่อแทนที่จะเป็น IP และ headless Service เปลี่ยนจาก IP เดียวที่ load balance ให้กลายเป็น IP ของแต่ละ Pod ที่อยู่เบื้องหลังโดยตรง
CoreDNS กับ DNS name ของ Service
หัวข้อที่มีชื่อว่า “CoreDNS กับ DNS name ของ Service”CoreDNS รันเป็น Deployment อยู่ใน cluster (ปกติอยู่ใน kube-system) และทำหน้าที่เป็น DNS server ภายในของ cluster ทุก Pod ถูกตั้งค่าผ่าน /etc/resolv.conf ให้ส่ง DNS query ไปที่ CoreDNS พอ Service ถูกสร้างขึ้น CoreDNS จะเริ่มตอบชื่อของ Service นั้นทันทีด้วยชื่อเต็มในรูปแบบ
<service-name>.<namespace>.svc.cluster.local# From inside any Pod in the clusternslookup payments.default.svc.cluster.localถ้าอยู่ใน namespace เดียวกัน ชื่อแบบสั้นก็ใช้ได้เหมือนกัน เพราะ DNS search path ของ Pod จะมี suffix svc.cluster.local ของ namespace ตัวเองต่อท้ายให้อัตโนมัติ
# From a Pod that lives in the same namespace as the "payments" Servicenslookup paymentscurl http://payments/healthสำหรับ Service ปกติ (ไม่ใช่ headless) ชื่อนั้นจะ resolve ไปที่ A/AAAA record เดียว คือ ClusterIP ของ Service ทุก request ที่ยิงไปชื่อนั้นก็ยังถูก load balance ไปยัง Pod เบื้องหลังผ่าน kube-proxy อยู่ดี DNS แค่พา client ไปหา virtual IP เท่านั้น
Headless Service: ข้าม load balancer ไปเลย
หัวข้อที่มีชื่อว่า “Headless Service: ข้าม load balancer ไปเลย”บางครั้ง client ต้องการเข้าถึง Pod ตัวใดตัวหนึ่งเจาะจง ไม่ใช่แค่ “Pod ตัวไหนก็ได้ที่ healthy อยู่หลัง Service” การตั้ง clusterIP: None จะสร้าง headless Service
apiVersion: v1kind: Servicemetadata: name: cachespec: clusterIP: None selector: app: cache ports: - port: 6379headless Service จะไม่มี virtual IP เลย แทนที่ด้วยการที่ CoreDNS ตอบกลับ IP ของทุก Pod ที่ match และพร้อมใช้งานโดยตรง query ยังคง resolve ชื่อเดิม cache.default.svc.cluster.local แต่คำตอบตอนนี้กลายเป็นลิสต์ของ Pod IP แทนที่จะเป็น ClusterIP เดียว
ทำไม StatefulSet ถึงต้องพึ่งสิ่งนี้
หัวข้อที่มีชื่อว่า “ทำไม StatefulSet ถึงต้องพึ่งสิ่งนี้”StatefulSet ให้แต่ละ Pod มี identity ที่เสถียร เช่น web-0, web-1, web-2 และจับคู่กับ headless Service (ผ่าน spec.serviceName) เพื่อให้แต่ละ Pod มี DNS record ของตัวเองที่เสถียรด้วย
<pod-name>.<service-name>.<namespace>.svc.cluster.local# Reach one specific ordinal Pod directly, not a load-balanced peernslookup web-0.cache.default.svc.cluster.localนี่คือสิ่งที่ระบบ stateful แบบ distributed ต้องการเป๊ะ ๆ database replica ต้องต่อกลับไปที่ peer ตัวเดิม ที่เคยต่อไว้ ไม่ใช่ตัวสุ่มที่ load balancer เลือกให้ ถ้าไม่มี headless Service DNS record รายตัวแบบนี้จะไม่มีทางเกิดขึ้นเลย
flowchart TB pod["Client Pod"] -->|"DNS query"| coredns["CoreDNS"] coredns -->|"normal Service"| vip["Service ClusterIP\n(load-balanced)"] coredns -->|"headless Service"| p0["web-0 IP"] coredns -->|"headless Service"| p1["web-1 IP"] coredns -->|"headless Service"| p2["web-2 IP"]