วิธีแก้ปัญหา Temporary failure in name resolution เมื่อใช้คำสั่ง kubectl port-forward
เมื่อวานผมทำการอัพเกรดเวอร์ชันของ Kubernetes บน Cluster ของออฟฟิศ หลังจากอัพเกรดไปก็มีส่วนที่ต้องแก้นิดหน่อย แล้วระบบก็กลับมาทำงานได้ปกติ จนมีเหตุต้องใช้คำสั่ง kubectl port-forward เพื่อทำการเชื่อมต่อกับ redis เพื่อเปลี่ยนค่าบางอย่าง
kubectl port-forward --namespace me-more-dev service/redis-dev 8080:6379
เกิด error ขึ้นเมื่อใช้คำสั่งนี้
E0624 12:06:20.664091 34312 portforward.go:331] an error occurred forwarding 42399 -> 44134: error forwarding port 44134 to pod 255e06439c2da94a4b6a8b1ad2d3d7f4d6d1ba1f82ab6eb2ae519133b1f2bc58, uid : exit status 1: 2018/06/24 15:06:20 socat[22114] E getaddrinfo("localhost", "NULL", {1,2,1,6}, {}): Temporary failure in name resolution
ตอนแรกก็ไล่เช็ค DNS resolve service (CoreDNS) บน Cluster ก็สามารถ resolve ชื่อ service ต่างๆได้ปกติ ไม่มีอะไร
จนได้พบว่า ปัญหาอยู่ที่ตัว systemd-resolved
โดยที่ไฟล์ /etc/resolv.conf
มี localhost
อยู่ด้วย แล้วตัว kube-dns
เวลาจะทำการ query ข้อมูลชื่อ service มันจะไปอ่าน config ของระบบปฎิบัติการ แล้วพบว่ามันเจอ localhost
มันก็ loopback กลับมาที่ตัวเอง ทำให้ระบบไม่สามารถ resolve service name ได้
วิธีการแก้ง่ายๆ คือให้ทำ symbolic link ระหว่าง /run/systemd/resolve/resolv.conf
ไปยัง /etc/resolv.conf
บน node ทุก node แทน
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
ทำแบบนี้ทุก node
หลังจากนั้นให้ทำการ kill pods ของ kube-dns
ทิ้งซะ
kubectl -n kube-system delete pods -l k8s-app=kube-dns
แล้วทดสอบใหม่อีกครั้งครับ หากยังไม่ได้ ให้ทำการทยอย reboot node ทุก node ไปเรื่อยๆ แล้วทดสอบใหม่ครับ