ฉันจะเรียกใช้ระบบปฏิบัติการแบบเต็มในคอนเทนเนอร์ Docker โดยไม่ระบุคำสั่งได้อย่างไร


25

ฉันกำลังติดตามCoreOS Docker Documentationและกล่าวถึงการเริ่มต้นคอนเทนเนอร์ด้วยคำสั่งเช่น:

docker run someImageName /bin/somebinary

ในกรณีที่someImageNameเป็นภาพ เมื่อ / bin / ออกจากบางภาพจะไม่ทำงานอีกต่อไป

ฉันต้องการเรียกใช้รูปภาพโดยไม่ระบุไบนารีใด ๆ เพื่อเรียกใช้ แต่ฉันก็ต้องการเรียกใช้บริการ (เช่น systemd / sysvinit) ที่มีการทำงานได้ตามปกติภายในภาพ OS

ดูเหมือนว่าเป็นสิ่งที่พบได้บ่อยที่สุดที่ทุกคนต้องการทำกับ Docker แต่พยายามที่จะเรียกใช้อิมเมจโดยไม่มีคำสั่งส่งคืน:

2014/02/05 14:49:19 Error: create: No command specified

ฉันจะเริ่มต้นนักเทียบท่าคอนเทนเนอร์และเรียกใช้ระบบปฏิบัติการแบบเต็มแทนที่จะระบุคำสั่งได้อย่างไร


นี่เป็นคำถามซ้ำซ้อนของคำถามนี้stackoverflow.com/questions/19332662/…
Fred the Magic Wonder Dog

@FredtheMagicWonderDog ไม่มากถึงแม้ว่าคำตอบจะเหมือนกัน
mikemaccana

คำตอบ:


24

ดังที่มีการบันทึกไว้ที่นี่คุณเพียงเรียกใช้/sbin/initคำสั่งเหมือนกับการบูตระบบยูนิกซ์อื่น ๆ จากผู้ใช้รายเดียวไปยังโหมดผู้ใช้หลายคน

https://stackoverflow.com/questions/19332662/start-full-container-in-docker

ภาชนะบรรจุอาจเต็มไปด้วยระบบปฏิบัติการที่ถูกเป่าพวกเขาเพียงแค่ไม่ต้องทำ (เช่นเดียวกับ VMs สำหรับเรื่องนั้นมันเป็นเพียงความซับซ้อนในการกำหนดค่าและจัดการ)

ฉันจะบอกว่าจุดรวมทั้งหมดของ Docker คือการทำให้แอปพลิเคชั่นคอนเทนเนอร์ง่ายขึ้นดังนั้นคุณต้องกำหนดค่าแอพไม่ใช่ระบบปฏิบัติการทั้งหมด


ขอบคุณ หลังจากเริ่มอิมเมจด้วย / sbin / init ฉันก็วิ่งdocker ps -notruncเพื่อรับ ID คอนเทนเนอร์จากนั้นก็sudo /usr/sbin/lxc-attach -n containerIDเข้าไปในอิมเมจที่กำลังรันอยู่ ในฐานะที่เป็นโปสเตอร์อื่น ๆ กล่าวถึงฉันไม่ต้องการจริงๆ init สองดังนั้นฉันจะตรวจสอบตู้คอนเทนเนอร์เดียวคำสั่งต่อไป ...
mikemaccana

การบอกว่าคุณไม่จำเป็นต้องเรียกใช้ระบบปฏิบัติการแบบเต็มรูปแบบใน VM เหมือนการบอกว่าคุณไม่จำเป็นต้องเรียกใช้ระบบปฏิบัติการแบบเต็มรูปแบบในเครื่องที่มีอยู่จริงใช่ว่าเป็นจริงที่เคอร์เนลเป็นเพียง x86 / C ปกติ โปรแกรมที่ทำงานโดยไม่มี stdlib และ init ก็ทำเช่นนั้นได้
Lie Ryan

11

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

คอนเทนเนอร์ Docker ของคุณควรเป็นแอพพลิเคชั่นที่มีขอบเขตแคบและแคบซึ่งสามารถเริ่มต้นได้ด้วยคำสั่งเดียว หากคุณกำลังมองหาสิ่งที่ซับซ้อนกว่านั้นนักเทียบท่าไม่ใช่ทางออกที่คุณต้องการ ในกรณีดังกล่าวให้ตรวจสอบ KVM, ESXi, OpenVZ, LXDเป็นต้น

หากคุณกำลังมองหาวิธีที่คุณสามารถระบุค่าเริ่มต้นCMDและENTRYPOINTสำหรับคอนเทนเนอร์ของคุณคุณสามารถทำได้ในเวลาบิลด์โดยใช้ Dockerfile


5
ฉันรู้ว่านักเทียบท่าคืออะไร ฉันจะชี้ให้เห็นว่าคอนเทนเนอร์ของแอปพลิเคชันนั้นใช้ระบบปฏิบัติการเช่น Fedora หรือ Ubuntu แอ็พพลิเคชันแบบต่อเนื่องบน Unix - แม้แต่ userspace เฉพาะ Unixes เช่นคอนเทนเนอร์ Docker - เริ่มต้นจากไฟล์ initscripts หรือ systemd unit ตัวอย่างเช่นหากแอปของฉันขัดข้องฉันต้องการให้รีสตาร์ทโดยอัตโนมัติพร้อมกับขีด จำกัด - ที่ systemd ให้
mikemaccana

5
คุณพยายามยัดเข้าไปในภาชนะของคุณมากเกินไป - มันไม่ใช่ระบบปฏิบัติการ การควบคุมกระบวนการควรได้รับการจัดการนอกภาชนะแต่ละอัน
EEAA

1
ดังนั้นถ้ากระบวนการตาย ... แค่รีสตาร์ทคอนเทนเนอร์ทั้งหมดหรือไม่ ฉันเดาว่ามันไม่แพงจนเกินไป มันรู้สึกแปลก ๆ - ภาชนะของฉันมี / sbin / init แต่มันไม่เคยถูกใช้ ...
mikemaccana

1
ใช่นั่นคือความคิด ภาชนะของคุณมี/sbin/initแต่มันไม่จำเป็นต้องมี คุณน่าจะใช้คอนเทนเนอร์อูบุนตูเริ่มต้นหรืออะไรทำนองนั้น มีบิตจำนวนมากในคอนเทนเนอร์เหล่านี้ที่สามารถลบออกได้หากคุณต้องการ
EEAA

1
@ValkoSipuli แน่นอนคุณมีอิสระที่จะระงับความคิดเห็นนั้น ฉันยังคงยืนยันว่าการเรียกใช้มากกว่าหนึ่งกระบวนการภายในคอนเทนเนอร์ปฏิเสธเหตุผลส่วนใหญ่ในการใช้คอนเทนเนอร์ในตอนแรก มีสถานที่สำหรับใช้งานระบบปฏิบัติการภายในคอนเทนเนอร์หรือไม่? อาจ. แม้ว่าจะเป็นข้อยกเว้น แต่ก็ไม่ควรกระทำโดยไม่คำนึงถึงข้อดีและข้อเสีย
EEAA

5

หากต้องการเรียกใช้ระบบปฏิบัติการเต็มรูปแบบในคอนเทนเนอร์ให้สร้าง Dockerfile ต่อไปนี้:

FROM fedora:25

CMD /sbin/init

จากนั้นสร้างและเริ่มคอนเทนเนอร์และป้อนเชลล์ภายในเพื่อสำรวจเซอร์วิสที่รันอยู่ภายใน:

docker build -t os .
docker run -d --privileged --name os os
docker exec -it os bash

บริการ systemd เต็มรูปแบบภายในภาชนะ สวย.


0
docker pull ubuntu

เพียงเรียกใช้จากภาพเดียวกันหลาย ๆ ครั้งตามต้องการ คอนเทนเนอร์ใหม่จะถูกสร้างขึ้นจากนั้นพวกเขาสามารถเริ่มและหยุดการบันทึกการกำหนดค่าของตนเอง เพื่อความสะดวกของคุณควรใช้ชื่อ "--name" ในแต่ละคอนเทนเนอร์

Fi:

docker run --name MyContainer1 <ubuntu image>
docker run --name MyContainer2 <ubuntu image>
docker run --name MyContainer3 <ubuntu image>

แค่นั้นแหละ.

$ docker ps
CONTAINER ID        IMAGE            CREATED          STATUS               NAMES
a7e789711e62        67759a80360c   12 hours ago     Up 2 minutes         MyContainer1
87ae9c5c3f84        67759a80360c   12 hours ago     Up About a minute    MyContainer2
c1524520d864        67759a80360c   12 hours ago     Up About a minute    MyContainer3

หลังจากนั้นคุณสร้างคอนเทนเนอร์ของคุณตลอดไปและคุณสามารถเริ่มและหยุดเหมือน VMs

docker start MyContainer1

ในการรับในภาชนะบรรจุและทำสิ่งที่คุณต้องการจะทำ:

docker exec -it MyContainer1 bash
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.