เมื่อไม่กี่วันมา ผมเขียน tutorials สนุกๆ เกี่ยวกับ Docker เทคโนโลยีที่ห่อหุ้ม LXC ใน furry bundle of joy (มัดความสุขขนเฟอร์) และให้ developers, engineers และ system administrators ที่ less autistically inclined (น้อยแนวโน้มออทิสติก) และไม่ค่อยชอบ Python vomit (ขยะ Python) สนุกกับ wonders ของ OS-level virtualization แต่มีปัญหา
สอง issues ที่เราจะพูดวันนี้ เกิดขึ้นเมื่อคุณ start named container หรือพยายาม delete หนึ่ง ตัวอักษร fancy บนหน้าจอจะอ่านประมาณว่า: "Conflict. The name W is already in use by container XYZ. You have to delete..." และชิ้นที่สอง: "Conflict, cannot remove the default name of the container..." นอกจากการใช้ punctuation (เครื่องหมายวรรคตอน) อย่าง blatant misuse (ลักลอบใช้ผิด/ใช้แบบลักลอบ) เราต้องหาวิธี sort this out (จัดการให้เสร็จ)
ปัญหา (Problems)
โอเค เรามี issue นี้:
docker run -d -ti -p 22 -p 80 --name <name> <repo:tag>
FATA[0000] Error response from daemon: Conflict. The name "XYZ" is already in use by container hexacode. You have to delete (or rename) that container to be able to reuse that name.
เราไม่สามารถ start container ได้ เพราะ name ถูกใช้แล้ว รัน docker ps คุณจะไม่เห็นมันอยู่ที่นั่น อีกทั้งถ้าพยายาม kill หรือ remove offending container leftovers (เศษซากที่ทำให้ผิดปกติ) จะได้:
docker rm --link <name>
Error response from daemon: Conflict, cannot remove the default name of the container
FATA[0000] Error: failed to remove one or more containers
ดูเหมือน dead end (ทางตาย) แล้วทำไงต่อ?
วิธีแก้ (Solution(s))
ก่อนอื่น มาทำความเข้าใจว่ามีอะไรบ้าง ตามมาเห็นได้ว่า ในบางจุดในอดีต คุณได้สร้าง named container และทิ้งมันรันอยู่ หลังจากนั้น host ของคุณ reboot ไปเพราะเหตุผลไหนก็ตาม และคุณไม่ได้ terminate containers อย่าง graceful (สงบ/สมบูรณ์) Leftover files ตอนนี้ดูเหมือนจะ prevent (ป้องกัน) คุณจากการ respawn (สร้างใหม่) containers ใหม่ด้วยชื่อเก่า เพราะระบบคิดว่าเก่าๆยังคงอยู่
มีสองวิธีแก้ เริ่มจาก graceful method ก่อน หากรัน docker ps คุณจะไม่เห็น old containers เพราะมันไม่ได้ running จริง แต่ถ้ารัน docker ps พร้อม flag -a คุณควรเห็น container run history ทั้งหมด:
Containers ที่ exited แบบ abnormal จะมี non-zero status code ค้นหาตัวที่ต้องการจาก name แล้ว remove ด้วย actual hexadecimal code เช่น:
docker rm 85c2981e63f6 26ea04f41ab3
วิธีที่สอง คือ manual delete leftover files จากภายใต้ /var โดยเฉพาะ files อยู่ที่ /var/lib/docker/containers/ แต่ละ container directory จะมี super long hash identifier และข้างในมี JSON output น่ารังเกียจเยอะ หากค้นหา particular string ที่ match desired container name คุณจะหา relevant directory ที่เก็บ configuration files ได้
ลบ parent directory ที่ match name search แล้ว restart Docker service หลังจากนั้น คุณควรใช้ name นั้นได้อีกครั้ง นี่คล้ายกับที่เราเห็นกับ KVM และ libvirt leftovers
systemctl restart docker
และคุณควรพร้อมใช้งานแล้ว คุณเก่า (old boy)!
สรุป
บางปัญหาอาจ annoying (รำคาญ) มาก โดยเฉพาะเมื่อเกี่ยวกับว่า services จัดการ crashes, reboots และอย่างนั้นได้ดีแค่ไหน ผม dislike (ไม่ชอบ) เมื่อ leftover files ก่อให้เกิด grief (ความทุกข์/ปัญหา) มากมาย ไม่ควรเป็นเช่นนั้น และ services ควร recover (กู้คืน) อย่าง majestic (อันยิ่งใหญ่/มั่นคง) แต่ hey containers ยังเป็น young technology (เทคโนโลยีหนุ่ม) ดังนั้น stuff แบบนี้คาดหมายได้
หวังว่าคล้าย glorious aircon system (ระบบแอร์คอนดิชันเนอร์อันอัศจรรย์) ที่เป่า fury (ความโกรธ) บน windshield (กระจก擋風) เราได้ demistified (ทำให้ชัดเจน/กำจัดหมอก) ความสับสนและความสับสนรอบๆ การสร้าง named containers และการลบ leftovers หลัง unexpected reboots และอื่นๆ ตอนนี้ Docker experience ของคุณจะ pleasant (สนุกสนาน) ขึ้นหน่อย และคุณเรียนรู้หน่อยสองเรื่องเกี่ยวกับการทำงานใน background ไปแล้ว มีความสุขกันเถอะ
ขอแสดงความนับถือ