วิธีแก้ไขข้อผิดพลาด "ไม่สามารถเชื่อมต่อกับ Docker Daemon" ได้

เผยแพร่แล้ว: 2022-08-14

กราฟิกแสดงโลโก้ Docker

Docker เป็นหนึ่งในแพลตฟอร์มชั้นนำสำหรับการสร้างและใช้งานคอนเทนเนอร์ซอฟต์แวร์ มันมาพร้อมกับทุกสิ่งที่คุณต้องการเพื่อใช้คอนเทนเนอร์บนโฮสต์เดียวหรือหลายโหนดแบบกระจายในโหมด 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