วิธีแก้ปัญหา docker ไม่สามารถต่อ Database ได้

Petch Kruapanich
readmoreth
Published in
2 min readAug 17, 2019

เมื่อไม่กี่วันมานี้ผมเจอปัญหาว่าระบบที่รันอยู่บน docker ที่ผมกำลังพัฒนาอยู่ไม่สามารถเชื่อมต่อ database ที่อยู่ในวง 172.17.x.x ได้ (docker daemon บน Windows) หลังจากลองหาข้อมูลซักพักหนึ่งก็พบว่า จริงๆแล้วมันเป็นปัญหาเส้นผมบังภูเขาจริงๆ แต่ก่อนที่จะแก้ปัญหานี้ได้ เราต้องมาทำความเข้าใจเกี่ยวกับ Docker Network เบื้องต้นกันก่อนดีกว่า

ประเภทของ Docker Network

โดยปกติแล้ว Docker จะสามารถแบ่ง Network ออกได้เป็น 5 ประเภทประกอบด้วย (ไม่รวม custom และพวก 3rd party)

  • None คือการรัน container ในระบบปิด ที่ไม่สามารถออก network ภายนอกได้ ปกติเรามักสร้าง None network ไว้เชื่อมกับ custom network driver ของเราเอง
  • Bridge คือการรัน container ที่สามารถเชื่อมต่อไปยัง host network หรือถ้าพูดง่ายๆก็คือ าสามารถออก internet ได้ โดยถ้าเราสั่งรัน container โดยไม่ระบุ network driver ก็จะได้ Bridge มาเป็น default network เสมอ ซึ่ง Bridge จะมี Subnet และ Gateway เป็นของตัวเอง
  • Host คือการรัน container บน host network เลย จะไม่มีการแยก network ระหว่าง container และ docker host เหมือนใน Bridge
  • Overlay คือการรัน container ที่มีการคุยกันข้าม docker daemons (host network) ถ้ามีโจทย์แนวๆการทำ distributed network และต้องการให้ container สามารถคุยกันได้ บน host ที่ต่างกัน Overlay ก็จะเป็น network อีกประเภทหนึ่ง ที่เราควรศึกษาเพิ่มดู
  • MacVlan คือการรัน container ที่สามารถทำให้ container วิ่งไปยัง router ที่ต้องการได้ โดยไม่ต้องผ่าน host network

ปัญหาคืออะไร

ทีนี้กลับมาที่ปัญหาที่ผมเจอ ก็คือใน Environment ที่ผมกำลังพัฒนาอยู่ จำเป็นต้องติดต่อ SQL Server ไปยัง ip 172.17.11.x (ไม่มี domain) ซึ่งเมื่อลองรันก็พบว่า ไม่สามารถเชื่อมต่อได้ เจอ error ว่า timeout ตลอดเวลา

โดยในการรัน docker ดังกล่าว ผมได้ใช้งาน bridge network (ไม่ได้เลือกอะไร รันเป็น default ให้อยู่แล้ว) จึงลองทำการ inspect เพื่อหาสาเหตุว่าทำไมมันถึง timeout ด้วยคำสั่ง

docker network inspect bridge

และพบว่า default Subnet ของ docker ถูกตั้งเอาไว้ที่ 172.17.0.0/16 ซึ่งการระบุ Subnet นี้ส่งผลทำให้ database connection มันวิ่งวนจน timeout นั้นเอง

default subnet ของ docker

วิธีแก้ไข

เมื่อเจอแบบนี้ สิ่งที่ต้องทำก็คือ แก้ไข Subnet ให้เป็นค่าอื่นไป โดยในที่นี้เราจะเปลี่ยนให้เป็น 172.17.10.1/24 เพื่อไม่ให้มันชนกัน

ในการแก้ไขก็เพียงไปที่ Setting ของ docker (คลิกขวาที่รูปปลาวาฬ > Setting) เลือก tab Daemon และเปลี่ยนจาก Setting จาก Basic เป็น Advance จากนั้นระบุ bridge ip เป็น http://172.17.10.1/24

แก้ไข bridge ip

จากนั้นลองเช็คด้วยคำสั่ง docker network inspect bridge อีกครั้งจะพบว่า subnet เปลี่ยนเป็นที่เรียบร้อยแล้ว

subnet ที่เปลี่ยนไป

ปัญหานี้ น่าจะไม่ใช่ปัญหาที่เจอกันทุกคน นอกจากว่า Environment ที่คุณกำลังพัฒนาอยู่จำเป็นต้องติดต่อไปยัง IP ที่อยู่ในวง 172.17.10.1/24 และถ้าคุณเจอปัญหานี้ หวังว่าบทความนี้จะช่วยคุณได้นะครับ

--

--

Petch Kruapanich
readmoreth

Full time Developer, Part time writer, Vinyl lover