วิธีแก้ไขข้อผิดพลาด "ไม่สามารถเชื่อมต่อกับ Docker Daemon" ได้
เผยแพร่แล้ว: 2022-08-14Docker เป็นหนึ่งในแพลตฟอร์มชั้นนำสำหรับการสร้างและใช้งานคอนเทนเนอร์ซอฟต์แวร์ มันมาพร้อมกับทุกสิ่งที่คุณต้องการเพื่อใช้คอนเทนเนอร์บนโฮสต์เดียวหรือหลายโหนดแบบกระจายในโหมด Swarm
นักเทียบท่ามีสถาปัตยกรรมที่ใช้ภูต ซอฟต์แวร์ที่รับผิดชอบในการสร้างและเริ่มต้นคอนเทนเนอร์นั้นไม่ขึ้นอยู่กับกระบวนการ CLI ที่ยอมรับคำสั่งของคุณ ซึ่งหมายความว่าคุณจะเห็นข้อผิดพลาดใน CLI หากคุณพยายามเรียกใช้คำสั่งโดยไม่มีการเชื่อมต่อ daemon ที่ใช้งานอยู่ ในบทความนี้ เราจะแบ่งปันวิธีการบางอย่างในการแก้ไขปัญหาข้อความที่น่าผิดหวังเหล่านี้
อาการปัญหา
Docker CLI อาศัยการเชื่อมต่อ daemon ที่มีอยู่ มันโต้ตอบกับภูตโดยใช้การเรียก API เมื่อ daemon ที่กำหนดค่าไม่สามารถเข้าถึงได้ คำสั่ง docker
เช่น docker ps
, docker run
และ docker build
จะแสดงข้อความแสดงข้อผิดพลาดคล้ายกับข้อความนี้:
$ docker run สวัสดีโลก: ล่าสุด ไม่สามารถเชื่อมต่อกับ Docker daemon ที่ unix:///var/run/docker.sock docker daemon ทำงานอยู่หรือไม่
สิ่งนี้แสดงให้เห็นว่า CLI พยายามสื่อสารกับ Docker daemon โดยใช้ซ็อกเก็ต /var/run/docker.sock
Unix ซ็อกเก็ตไม่เปิด ดังนั้นการเชื่อมต่อจึงล้มเหลว
1. ตรวจสอบว่าบริการ Docker Daemon กำลังทำงานอยู่
โดยปกติ Docker daemon จะได้รับการจัดการโดยบริการ systemd ที่เริ่ม Docker โดยอัตโนมัติหลังจากโฮสต์ของคุณรีบูต คุณสามารถเริ่มแก้ไขปัญหาได้โดยตรวจสอบว่าบริการนี้กำลังทำงานอยู่หรือไม่:
$ sudo systemctl สถานะ นักเทียบท่า docker.service - Docker Application Container Engine โหลดแล้ว: โหลดแล้ว (/lib/systemd/system/docker.service; เปิดใช้งาน; ค่าที่ตั้งไว้ล่วงหน้าของผู้ขาย: เปิดใช้งาน) ใช้งานอยู่: ไม่ทำงาน (ตาย)
บริการควรรายงาน Active: active (running)
หาก daemon กำลังทำงานอยู่ ตัวอย่างข้างต้นแสดงให้เห็น inactive (dead)
ซึ่งหมายความว่า daemon หยุดทำงาน
เริ่ม Docker โดยใช้คำสั่งต่อไปนี้:
$ sudo systemctl เริ่มนักเทียบท่า
ตอนนี้คุณควรจะสามารถรันคำสั่ง docker
CLI ได้สำเร็จ
คุณอาจพบว่า Docker อยู่ในสถานะหยุดหลังจากที่คุณรีบูตเครื่อง คุณสามารถแก้ปัญหานี้ได้โดยเปิดใช้บริการ อนุญาตให้ systemd เริ่มทำงานโดยอัตโนมัติ:
$ sudo systemctl เปิดใช้งานนักเทียบท่า $ sudo systemctl daemon-reload
คำสั่ง daemon-reload
สั่งให้ systemd โหลดการกำหนดค่าใหม่เพื่อใช้การเปลี่ยนแปลง
2. เริ่ม Daemon ด้วยตนเอง
บางครั้งคุณอาจใช้ระบบที่ไม่ได้ติดตั้งบริการ Docker คุณสามารถเริ่ม Docker daemon ด้วยตนเองโดยใช้คำสั่ง dockerd
โดยปกติจะต้องรันเป็น root
$ sudo dockerd INFO[2022-06-29T15:12:49.303428726+01:00] กำลังเริ่ม
Docker จะยังคงสามารถเข้าถึงได้ตราบเท่าที่คำสั่งทำงานอยู่ ใช้ Ctrl+C เพื่อหยุดภูต
3. การตรวจสอบ CLI กำลังกำหนดเป้าหมาย Daemon ที่ถูกต้อง
ปัญหาอาจเกิดขึ้นเมื่อ CLI พยายามเชื่อมต่อกับอินสแตนซ์ Docker daemon ระยะไกล ซึ่งมักเป็นสาเหตุเมื่อข้อความแสดงข้อผิดพลาดแสดงที่อยู่ TCP:
$ docker run สวัสดีโลก: ล่าสุด ไม่สามารถเชื่อมต่อกับ Docker daemon ที่ tcp:///0.0.0.0:2375
ในตัวอย่างนี้ docker
CLI กำลังพยายามติดต่อ Docker daemon ที่ 0.0.0.0:2375
โดยใช้ TCP แทนซ็อกเก็ต Unix Docker ในเครื่อง การดำเนินการนี้จะล้มเหลวหากปิดใช้งานการสนับสนุน TCP ของ Docker daemon หรือโฮสต์ที่ระบุไม่สามารถเข้าถึงได้บนเครือข่าย
โดยปกติ คุณสามารถแก้ไขปัญหานี้ได้โดยเปลี่ยนเป็นบริบท Docker CLI ที่ถูกต้องสำหรับการเชื่อมต่อ daemon ที่คุณต้องการใช้:
$ บริบทนักเทียบท่าใช้ค่าเริ่มต้น
คุณสามารถแสดงรายการบริบทที่มีอยู่ทั้งหมดและจุดปลาย daemon ที่เชื่อมต่อด้วยคำสั่ง context ls
:
$ บริบทนักเทียบท่า ls ชื่อ คำอธิบาย DOCKER ENDPOINT ค่าเริ่มต้น * การกำหนดค่าตาม DOCKER_HOST ปัจจุบัน unix:///var/run/docker.sock
บริบทที่เลือกในปัจจุบันจะถูกเน้นด้วยเครื่องหมายดอกจัน
ค่าที่ไม่คาดคิดในคอลัมน์ DOCKER ENDPOINT
มักเกิดจากตัวแปรสภาพแวดล้อม DOCKER_HOST
ที่ตั้งค่าไว้ คุณจะเห็นคำเตือนในกรณีนี้:
$ ส่งออก DOCKER_HOST=1.2.3.4 $ บริบทนักเทียบท่า ls ชื่อ คำอธิบาย DOCKER ENDPOINT ค่าเริ่มต้น * การกำหนดค่าตาม DOCKER_HOST ปัจจุบัน tcp://1.2.3.4:2375 คำเตือน: ตัวแปรสภาพแวดล้อม DOCKER_HOST จะแทนที่บริบทที่ใช้งานอยู่ หากต้องการใช้บริบท ให้ตั้งค่า global --context flag หรือยกเลิกการตั้งค่าตัวแปรสภาพแวดล้อม DOCKER_HOST
การมีอยู่ของตัวแปรสภาพแวดล้อม DOCKER_HOST
ในเชลล์ของคุณจะแทนที่ปลายทางที่กำหนดโดยบริบทที่คุณเลือก ในตัวอย่างนี้ คำสั่ง docker
จะกำหนดเป้าหมายอินสแตนซ์ daemon เสมอที่ tcp://1.2.3.4:2375
ปัญหานี้สามารถแก้ไขได้โดยล้างตัวแปร DOCKER_HOST
:
$ ส่งออก DOCKER_HOST=
นักเทียบท่าจะใช้ปลายทางที่กำหนดค่าโดยบริบทที่ใช้งานอยู่ของคุณ นี่จะเป็นซ็อกเก็ต Unix ในเครื่องเริ่มต้นที่ /var/run/docker.sock
เว้นแต่คุณจะตั้งค่าบริบทที่กำหนดเองด้วยตนเอง
$ บริบทนักเทียบท่า ls ชื่อ คำอธิบาย DOCKER ENDPOINT ค่าเริ่มต้น * การกำหนดค่าตาม DOCKER_HOST ปัจจุบัน unix:///var/run/docker.sock
4. ปัญหาการอนุญาต
สิทธิ์ผู้ใช้ที่ไม่ถูกต้องบนซ็อกเก็ตของ Docker เป็นอีกสาเหตุหนึ่งของปัญหาการเชื่อมต่อ daemon ปัญหาประเภทนี้มักจะแสดงข้อความแสดงข้อผิดพลาดที่แตกต่างกันเล็กน้อย:
$ docker run สวัสดีโลก: ล่าสุด ถูกปฏิเสธขณะพยายามเชื่อมต่อกับซ็อกเก็ต Docker daemon ที่ unix:///var/run/docker.sock
สิ่งนี้จะเกิดขึ้นเมื่อบัญชีผู้ใช้ Unix ของคุณไม่มีสิทธิ์โต้ตอบกับซ็อกเก็ตที่เปิดเผย Docker API การเพิ่มตัวเองในกลุ่ม docker
เป็นวิธีปฏิบัติที่ดีที่สุดในการแก้ไขปัญหานี้:
$ sudo usermod -aG นักเทียบท่า $USER
คุณจะต้องเปิดหน้าต่างเชลล์ใหม่หรือออกจากระบบแล้วกลับเข้ามาใหม่อีกครั้งเพื่อให้การเปลี่ยนแปลงนี้มีผล ตอนนี้คุณควรจะสามารถเรียกใช้คำสั่ง docker
ได้โดยไม่มีปัญหาเรื่องสิทธิ์
สรุป
“ไม่สามารถเชื่อมต่อกับ Docker daemon” ปรากฏขึ้นเมื่อ Docker CLI ไม่สามารถสื่อสารกับอินสแตนซ์ Docker daemon โดยใช้การกำหนดค่าปัจจุบันของคุณ บ่อยครั้งเนื่องจากบริการ Docker daemon ถูกหยุดหรือปิดใช้งาน คุณยังสามารถพยายามเชื่อมต่อกับโฮสต์ Docker ระยะไกลที่ออฟไลน์อยู่
ตอนนี้คุณควรตระหนักถึงสาเหตุที่เป็นไปได้ของปัญหานี้และวิธีแก้ปัญหาทั่วไป แก้ไขข้อผิดพลาดโดยตรวจสอบการตั้งค่า Docker daemon รีสตาร์ทบริการ Docker และตรวจสอบให้แน่ใจว่าบัญชีผู้ใช้ของคุณได้รับอนุญาตให้โต้ตอบกับซ็อกเก็ตของ Docker