Computer >> คอมพิวเตอร์ >  >> ซอฟต์แวร์ >> เครื่องเสมือน

ปัญหาเครือข่ายการแก้ไขชื่อนักเทียบท่า - บทช่วยสอน

หวังว่าคุณจะไม่จำเป็นต้องอ่านบทความนี้จริงๆ และคุณบังเอิญมาที่นี่เพราะคุณเบื่อหรือค้นหาผิดประเภทเท่านั้น หรือคุณอาจประสบปัญหาที่คอนเทนเนอร์ Docker ของคุณไม่สามารถเข้าถึงอินเทอร์เน็ตได้อีกต่อไป แม้ว่าจะเพิ่งเคยใช้งานได้ดี และคุณไม่ได้ทำการเปลี่ยนแปลงใดๆ กับสภาพแวดล้อม

ฟังดูเหมือนเป็นปัญหาที่คลุมเครือมาก แต่นี่คือสิ่งที่ฉันเผชิญในทันที คอนเทนเนอร์ของฉันไม่มีการเข้าถึงเครือข่าย โดยมีข้อผิดพลาด เช่น ความล้มเหลวในการแก้ไข URL ชั่วคราว ดูเหมือนปัญหาเกี่ยวกับการแก้ไขชื่อ และทำให้ฉันรำคาญเป็นพิเศษ เพราะมันไม่ควรเกิดขึ้น แต่เรากำลังก้าวไปข้างหน้า โฮสต์ทดสอบ:Ubuntu พร้อม systemd - สำคัญสำหรับรุ่นหลัง มาค่อยๆ กัน

ปัญหาในรายละเอียดเพิ่มเติม

คุณได้กำหนดค่า Docker บนระบบของคุณแล้ว มันทำงานได้ดี คุณมีหลายภาพ หลายคอนเทนเนอร์ และคุณยังใช้กฎเครือข่ายขั้นสูง และทุกอย่างดูเหมือนจะเป็นระเบียบเรียบร้อย จากนั้น คุณจะสังเกตเห็นว่าคุณไม่สามารถทำกิจกรรมบางอย่างในคอนเทนเนอร์ของคุณได้อีกต่อไป เช่น การอัปเดตหรือการติดตั้งแพ็คเกจ วิธีที่ดีที่สุดในการแก้ไขจุดบกพร่องนี้คือการแนบเชลล์กับอินสแตนซ์คอนเทนเนอร์ที่กำลังทำงานอยู่ ตามที่ฉันได้อธิบายไว้ในคู่มือแนะนำ อันที่จริง ภายในคอนเทนเนอร์ที่กำลังทำงานอยู่ คุณจะเห็นบางอย่างเช่น:

# apt-get update
Err:1 https://archive.ubuntu.com/ubuntu bionic InRelease
ความล้มเหลวชั่วคราวในการแก้ไข 'archive.ubuntu.com'
0% [กำลังเชื่อมต่อกับความปลอดภัย ubuntu.com]

ดูเหมือนว่าปัญหา DNS (การแก้ไขชื่อ) คอนเทนเนอร์ไม่สามารถหาวิธีแก้ไขชื่อโดเมนเป็นที่อยู่ IP ดังนั้นจึงไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์เพื่อดึงข้อมูล เช่น การอัปเดต มีสองประเด็นที่นี่ หนึ่ง เหตุใดปัญหาจึงเกิดขึ้นอย่างกะทันหัน สอง เราต้องแก้ไขเครือข่ายจริงๆ ตอนนี้ ฉันต้องการแสดงวิธีแก้ปัญหาด้วยวิธีที่สวยงาม

วิธีแก้ปัญหา

ก่อนอื่นมาทำความเข้าใจว่าเหตุใดจึงเกิดปัญหาขึ้น ไม่มีคำตอบทันทีที่นี่ แต่บางสิ่งที่ต้องพิจารณาอาจรวมถึงสภาพแวดล้อมที่ใกล้ชิดของคุณ ตัวอย่างเช่น โฮสต์ของคุณอาจไม่มีการเปลี่ยนแปลง แต่เครือข่ายอาจมี - เราเตอร์ นโยบายเครือข่าย เซิร์ฟเวอร์ DNS เอง เนื่องจากโดยปกติแล้วคุณไม่สามารถควบคุมสิ่งที่เกิดขึ้นนอกการตั้งค่าทันทีได้ วิธีที่ดีที่สุดในการค้นหาว่าปัญหาอยู่ที่ใดโดยแยกปัญหาทีละขั้นตอน

  • หากระบบโฮสต์ของคุณมีเครือข่ายและไม่สามารถแก้ไข URL ได้ คุณจะต้องจัดการก่อน เป็นไปได้มากว่าจะมีปัญหาระหว่างโฮสต์และปลายทาง และโครงสร้างพื้นฐานเครือข่ายอะไรก็ตามที่อยู่ระหว่างนั้น
  • หากระบบโฮสต์ของคุณมีเครือข่ายและสามารถแก้ไข URL ได้อย่างถูกต้อง ปัญหาอยู่ที่วิธีที่คอนเทนเนอร์ Docker แก้ไข URL โดยเฉพาะ นี่คือจุดที่เราต้องให้ความสำคัญต่อไป
  • ตรวจสอบว่าอินเทอร์เฟซเครือข่าย Docker เปิดใช้งานอยู่หรือไม่ (ด้วยคำสั่ง เช่น ip หรือ ifconfig) หากไม่ คุณจะต้องแก้ไขปัญหานั้นก่อนที่จะไปยังขั้นตอนถัดไป

ifconfig docker0

  • ตรวจสอบว่าอินสแตนซ์ของคอนเทนเนอร์มีที่อยู่ IP หรือไม่ ถ้าไม่ คุณจะต้องแก้ไขสิ่งนั้น

นักเทียบท่าตรวจสอบ <ชื่อคอนเทนเนอร์หรือ ID> | grep -i "ipaddr"

  • ตรวจสอบว่าคุณได้รับผลลัพธ์เดียวกันภายในคอนเทนเนอร์หรือไม่ ถ้าเป็นไปได้ (ip หรือ ifconfig) หากผลลัพธ์ไม่ตรงกับที่คุณเห็นในคำสั่งก่อนหน้า คุณจะต้องแก้ไขสิ่งนั้น
  • ตรวจสอบว่าคุณสามารถ ping คอนเทนเนอร์จากภายนอกได้หรือไม่ (และในทางกลับกัน หากคำสั่ง ping พร้อมใช้งาน) หาก ping ทำงาน นี่อาจเป็นข้อบ่งชี้ที่ดีว่าเครือข่ายได้รับการกำหนดค่าอย่างถูกต้อง และไม่มีกฎไฟร์วอลล์ปิดกั้นการรับส่งข้อมูล (น่าจะเป็นไปได้มากที่สุด)

การจำแนกชื่อ

หากการตรวจสอบทั้งหมดนี้ไม่พบปัญหาหรือข้อผิดพลาดแปลกๆ ขั้นตอนต่อไปคือการมุ่งเน้นไปที่การแก้ไข DNS คอนฟิกูเรชันสำหรับสิ่งนั้นจะมีอยู่ในไฟล์คอนฟิกูเรชัน /etc/resolv.conf สิ่งนี้เป็นจริงทั้งสำหรับอินสแตนซ์จริงของ Linux เช่นเดียวกับเครื่องเสมือนและคอนเทนเนอร์ คุณอาจสังเกตเห็นว่าคอนเทนเนอร์ใช้บางอย่างเช่น:

...
# ดู man:systemd-resolved.service(8) สำหรับรายละเอียดเกี่ยวกับโหมดที่รองรับ
# ของการดำเนินการสำหรับ /etc/resolv.conf

ค้นหา xyz

nameserver X.Y.Z.W
...

ที่อยู่ IP ของเนมเซิร์ฟเวอร์มักจะเป็นที่อยู่ IP ภายนอก (เช่น ISP ของคุณ) หรือ localhost (127.0.0.X) คำถามคือ:สิ่งเหล่านี้ตรงกับไฟล์ /etc/resolv.conf ของโฮสต์หรือไม่

คำตอบคือ คุณอาจกำหนด localhost ไว้ในไฟล์ /etc/resolv.conf ของโฮสต์ของคุณ ตอนนี้ลองทำในคอนเทนเนอร์ของคุณ แก้ไขไฟล์ resolv.conf และแทนที่ที่อยู่ IP ในบรรทัดเนมเซิร์ฟเวอร์ด้วยอันที่ตรงกับค่าของโฮสต์ =localhost หากนั่นช่วยแก้ปัญหาของคุณได้ก็ดี แต่ส่วนใหญ่จะไม่

แต่ ณ จุดนี้ คุณไม่มีปัญหากับการเชื่อมต่อเครือข่ายบนโฮสต์ของคุณ ดังนั้นเราจึงต้องหาที่อยู่จริงของเซิร์ฟเวอร์ DNS ในสภาพแวดล้อมของคุณ และสิ่งนี้ซับซ้อนยิ่งขึ้นเนื่องจากลีนุกซ์รุ่นใหม่ส่วนใหญ่ใช้ systemd เนื้อเรื่องเข้มข้นขึ้น

ค้นหา DNS ด้วย systemd

ใช่. เราจำเป็นต้องค้นหาว่าเนมเซิร์ฟเวอร์คืออะไร และเราจะต้องใช้คำสั่ง systemd สำหรับสิ่งนั้น เป็นไปได้มากว่า ถ้าคุณมี systemd ในระบบของคุณ แสดงว่าคุณกำลังใช้ systemd-resolve ซึ่งเป็นตัวจัดการชื่อเครือข่ายและบริการ การกำหนดค่าถูกเก็บไว้ภายใต้ /etc/systemd/resolved.conf แต่คุณยังสามารถรับผลลัพธ์ในบรรทัดคำสั่งได้ด้วยคำสั่ง systemd-resolve:

แก้ไข systemd --status

ลิงก์ 3 (wlp59s0)
ขอบเขตปัจจุบัน:DNS
การตั้งค่า LLMNR:ใช่
การตั้งค่า MulticastDNS:ไม่ใช่
การตั้งค่า DNSSEC:ไม่
รองรับ DNSSEC:ไม่
เซิร์ฟเวอร์ DNS:10.50.34.1
2001:64c:1462:b023::1
โดเมน DNS:dedoimedo

เรามีอะไรที่นี่? สิ่งที่น่าสนใจมากมาย แต่สิ่งที่สำคัญจริงๆ คือบรรทัดที่อ่าน DNS Servers นี่คือสิ่งที่เราต้องการ วางที่อยู่ IP นี้ลงในไฟล์คอนเทนเนอร์ /etc/resolv.conf แล้วลองอีกครั้ง คุณควรให้เครือข่ายใช้งานได้อีกครั้ง

ทำไมจึงเกิดปัญหานี้ขึ้น

ตอนนี้เราสามารถหารือเกี่ยวกับสาเหตุอีกครั้ง หากคุณดูที่เอกสารคู่มือ systemd-resolve อาจเป็นไปได้ว่ามีการเปลี่ยนแปลงบางอย่างในระบบของคุณ (อาจเกิดจากการอัพเดทเป็นประจำ) โดยที่โหมดการทำงานที่เลือกทำให้เกิดความขัดแย้งกับการแก้ไขชื่อ โดยเฉพาะอย่างยิ่ง หากเราดูวิธีจัดการ /etc/resolv.conf โหมดแรกจะระบุว่า:

systemd-resolved รักษาไฟล์ /run/systemd/resolve/stub-resolv.conf เพื่อให้เข้ากันได้กับโปรแกรม Linux แบบดั้งเดิม ไฟล์นี้อาจเชื่อมโยงมาจาก /etc/resolv.conf ไฟล์นี้แสดงรายการ DNS 127.0.0.53 stub (ดูด้านบน) เป็นเซิร์ฟเวอร์ DNS เพียงเซิร์ฟเวอร์เดียว นอกจากนี้ยังมีรายการโดเมนการค้นหาที่ใช้งานโดย systemd-resolved รายการโดเมนการค้นหาจะได้รับการอัปเดตอยู่เสมอ โปรดทราบว่าแอปพลิเคชันไม่ควรใช้ /run/systemd/resolve/stub-resolv.conf โดยตรง แต่ใช้ผ่าน symlink จาก /etc/resolv.conf เท่านั้น ไฟล์นี้อาจเชื่อมโยงจาก /etc/resolv.conf เพื่อเชื่อมต่อไคลเอนต์ในเครื่องทั้งหมดที่ข้าม DNS API ในเครื่องไปยังระบบที่แก้ไขด้วยการตั้งค่าโดเมนการค้นหาที่ถูกต้อง ขอแนะนำให้ใช้โหมดการทำงานนี้

หากลิงก์ใดลิงก์หนึ่งในสมการนี้เสียหรือมีบางสิ่งเปลี่ยนแปลง อาจเป็นไปได้ว่าบริการ Docker ไม่สามารถระบุได้ว่าสิ่งใดให้ และท้ายที่สุดคุณก็ไม่ได้รับการแก้ไขชื่อ ดังนั้นการแก้ปัญหา [sic] คือการให้ที่อยู่ DNS ของเครือข่ายจริง ซึ่งคอนเทนเนอร์สามารถเข้าใจและใช้งานได้ นี่เป็นการคาดเดาเล็กน้อยในฝั่งของฉัน แต่ฉันคิดว่ามันค่อนข้างถูกต้อง

บทสรุป

เอาล่ะ ความลึกลับอีกอย่างก็หายไป กระจกบังลมอีกอันก็หายไป หรือบางสิ่งบางอย่าง. ฉันไม่ชอบวิธีแก้ปัญหาแบบครึ่งๆ กลางๆ แต่เมื่อคุณมีโครงสร้างพื้นฐานของระบบที่ซับซ้อนเป็นชั้นๆ บางครั้งโซลูชันก็แย่พอๆ กับปัญหา ไม่ใช่เพราะพวกเขาไม่แก้ไขปัญหา - เพราะคุณมองเห็นและควบคุมได้น้อยกว่าที่ควรจะเป็น แต่นั่นคืออนาคตของ Linux - และทุกอย่างด้านไอที - นามธรรมที่ไม่มีที่สิ้นสุด

ตามหัวข้อ เราหวังว่าคำแนะนำเล็กๆ น้อยๆ นี้จะช่วยให้คุณแก้ไขปัญหาได้อย่างรวดเร็วและไม่เจ็บปวดสำหรับการผจญภัยในคอนเทนเนอร์ของคุณ หากคุณใช้ Docker และการจำแนกชื่อใช้งานไม่ได้อีกต่อไปในอินสแตนซ์คอนเทนเนอร์ บางทีคุณควรทดสอบเคล็ดลับและลูกเล่นที่เขียนไว้ด้านบน จากนั้นสร้างอิมเมจของคุณเองด้วยการแก้ไขที่ถูกต้อง ดังนั้นคุณไม่จำเป็นต้องทำ ต่อสู้กับสิ่งนี้อีกครั้ง เสร็จแล้วก็จบ

ไชโย