วิธีแก้ปัญหา 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 ไปเรื่อยๆ แล้วทดสอบใหม่ครับ