AKS ดึง image จาก registry ส่วนตัวหลัง VPN ไม่ได้
kubelet ดึงผ่านเครือข่ายของ node ไม่ใช่ผ่าน VPN ของ pod ตัดสินจากเส้นทางของ node, DNS ของ node, ทุก endpoint ที่การดึงแตะ แล้วจึงเป็น TLS และตัวตน
แล็ปท็อปของคุณดึง image ได้ไม่มีปัญหา แต่ pod ค้างอยู่ที่ ImagePullBackOff และมีคนเสนอให้รัน VPN client ขององค์กรเป็น sidecar ซึ่งไม่ช่วย เพราะการดึงเกิดขึ้นก่อนที่ container ของคุณจะมีอยู่: kubelet ขอให้ container runtime บน node ไปเอา image มา และ runtime ใช้ network namespace ของ node
ลำดับการทำงานเป็นตัวกำหนดชั้น
เริ่มจากการแปลงชื่อ registry จากนั้นเชื่อมต่อ ยืนยันตัวตน ดาวน์โหลดเลเยอร์ และจึงเริ่ม container ทุกอย่างที่ pod ทำกับ VPN เกิดหลังจากนั้น ดังนั้น tunnel ที่ทำงานในคลัสเตอร์ไม่ใช่หลักฐานเรื่องการดึง
นี่คือเหตุผลที่ image ใน cache เป็นคำโกหกที่น่าเชื่อ: node ที่ดึง image เมื่อสัปดาห์ก่อนยังคงให้บริการ deployment ดูปกติ และความล้มเหลวจะปรากฏเมื่อ scheduler วาง replica บน node ใหม่ scale-up หรือการเปลี่ยน node เป็นตัวกระตุ้น ไม่ใช่สาเหตุ
สามเงื่อนไขกำหนดการแก้ไข
การเข้าถึงขึ้นกับเส้นทาง การแปลงชื่อ และชุด endpoint ถ้า subnet ของ node หาเส้นทางไปเครือข่าย registry ไม่ได้ ข้อมูลรับรองใดก็ไม่ช่วย ถ้าแปลงชื่อผ่าน DNS ของ node ไม่ได้ การเชื่อมต่อจะไม่เริ่ม ถ้าเข้าถึงได้แค่ manifest แต่ไม่ได้ blob การดึงจะล้มกลางทาง
| Condition | Typical symptom | Where to look |
|---|---|---|
| Node subnet has no route to the registry network | Timeout, no connection | Effective routes on the node NIC, gateway transit, return path on-premises |
| Node resolver cannot see the private zone | Name resolution failure in events | VNet DNS settings and the resolver the node actually uses |
| Only the manifest endpoint is reachable | Auth succeeds, layer download fails | Every hostname the registry hands out during the pull |
| TLS or identity is wrong | Certificate error, 401 or 403 | Server certificate name and trust, scoped pull identity |
VNet peering อย่างเดียวไม่ได้ให้ทุกรูปแบบของ gateway transit และเส้นทางทางเดียวไม่ใช่เส้นทางที่ใช้งานได้ node ต้องมีเส้นทางที่รองรับผ่าน VPN gateway ที่ตั้งใจ และฝั่ง registry ต้องมีเส้นทางกลับไปยัง subnet ของ node
อ่านความล้มเหลวก่อนเลือกวิธีแก้
เริ่มจาก event ของ pod และ node ที่มันไปลง โดยใช้ชื่อจริงของคุณ: kubectl describe pod app-example -n team-example และ kubectl get pod app-example -n team-example -o wide ข้อความ event แยกชื่อโฮสต์ที่แปลงไม่ได้ออกจาก timeout การปฏิเสธ certificate ออกจาก image ที่หายไป และความล้มเหลวในการอนุญาตออกจากทั้งหมดนั้น
การยืนยันตัวตนเป็นเครื่องมือที่ถูกประเมินสูงเกินไปที่สุด imagePullSecret ให้ข้อมูลรับรอง registry แก่ runtime แต่ไม่ได้ติดตั้งเส้นทาง ไม่ได้เปลี่ยน resolver ของ node และไม่ได้ทำให้ certificate ที่ไม่น่าไว้วางใจใช้ได้ ถ้า event บอกว่าการดึงไม่ได้รับอนุญาต ให้ดูขอบเขตของตัวตน ถ้าบอกว่าการเชื่อมต่อหมดเวลา ข้อมูลรับรองก็ไม่เกี่ยวข้อง
เอกสาร image ของ Kubernetes เป็นแหล่งอ้างอิงเรื่องพฤติกรรมการดึงและข้อมูลรับรองของ registry ส่วนตัว และควรอ่านสักครั้งก่อนเปลี่ยนเครือข่าย เพราะมันทำให้เส้นแบ่งระหว่างการยืนยันตัวตนกับการขนส่งชัดเจน
สร้างเส้นทางใต้ pod
ทำตามลำดับนี้ เริ่มจากการกำหนดเส้นทางเครือข่ายของ node: ยืนยันว่า subnet มีเส้นทางที่รองรับไปยังเครือข่าย registry ตรวจสอบเส้นทางที่มีผลบน node กฎความปลอดภัยทั้งสองด้าน และเส้นทางกลับฝั่ง registry
จากนั้นแปลงชื่อจากบริบทของ node resolver ของ node ไม่ใช่การตั้งค่า DNS ของ pod และความสำเร็จใน pod ไม่ใช่หลักฐานของ host runtime ใช้ DNS ส่วนตัวที่มีการจัดการแทนการเพิ่มรายการใน hosts แบบถาวร เพราะรายการนั้นอยู่จนกว่า node จะถูกเปลี่ยนแล้วหายไปอย่างเงียบ ๆ
จากนั้นพิสูจน์ทุก endpoint registry อาจให้บริการยืนยันตัวตนแยกและที่เก็บ blob แยก การไปถึง manifest แทบไม่พิสูจน์อะไรเกี่ยวกับเลเยอร์ สุดท้ายทำ TLS และการอนุญาตให้ครบ: certificate ที่ใช้ได้กับชื่อ registry และได้รับความไว้วางใจผ่านการตั้งค่า node ที่รองรับ พร้อมตัวตนสำหรับการดึงที่จำกัดเฉพาะการอ่าน repository นั้น
ตรวจสอบบน node ที่คุณไม่ได้แก้ด้วยมือ
การทดสอบที่มีความหมายคือการดึงใหม่และการดาวน์โหลดทุกเลเยอร์จนครบบน node ที่เหมาะสม โดยเฉพาะ node ที่สร้างจากการขยายหรือการเปลี่ยน ทดสอบนี้ครอบคลุมทุก pool ที่อาจวาง workload รวมถึง pool ที่คุณลืม การแก้ด้วยมือบน node เดียวไม่ใช่รูปแบบการ deploy และ event autoscale ครั้งถัดไปจะพบช่องว่าง
การสร้างคลัสเตอร์ใหม่ใน VNet อื่นอาจเปลี่ยนเส้นทาง แต่เป็นทางเลือกสุดท้ายไม่ใช่ขั้นแรกในการวินิจฉัย เปรียบเทียบเครือข่าย node ที่มีอยู่กับเส้นทางส่วนตัวที่ต้องการและตัวควบคุมเครือข่าย AKS ที่รองรับก่อนเสนอการย้าย และแยกการเชื่อมต่อของแอปหลังเริ่มทำงานเป็นการตรวจสอบต่างหาก: pod คุยกับ backend เป็นคนละการตรวจกับการที่ node ดาวน์โหลด image