อะไรคือความแตกต่างระหว่างอิมเมจ Docker และคอนเทนเนอร์?


924

เมื่อใช้นักเทียบท่าเราเริ่มต้นด้วยภาพฐาน เราบูตมันขึ้นสร้างการเปลี่ยนแปลงและการเปลี่ยนแปลงเหล่านั้นจะถูกบันทึกไว้ในเลเยอร์สร้างภาพอื่น

ในที่สุดฉันก็มีภาพสำหรับอินสแตนซ์ PostgreSQL ของฉันและรูปภาพสำหรับเว็บแอปพลิเคชันของฉันการเปลี่ยนแปลงที่ยังคงมีอยู่

คอนเทนเนอร์คืออะไร


ก่อนที่คุณจะข้ามไปยังคำตอบที่ซับซ้อนคำตอบด้านล่างคำตอบของคนธรรมดาสำหรับคำถามดั้งเดิมของคุณน่าจะเป็นคำถามนี้ - sunilk.work/what-is-docker-with-example
Sunil Kumar

คำตอบ:


1241

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

คุณสามารถดูภาพทั้งหมดของคุณdocker imagesในขณะที่คุณสามารถดูภาชนะที่ใช้ด้วยdocker ps(และคุณสามารถดูภาชนะทั้งหมดที่มีdocker ps -a)

อินสแตนซ์ที่กำลังทำงานของรูปภาพจึงเป็นคอนเทนเนอร์


107
ดังนั้นความแตกต่างระหว่างภาพและภาชนะหยุดคืออะไร?
Victor Dombrovsky

342
ภาพเป็นสูตรภาชนะเป็นเค้ก ;-) คุณสามารถทำเค้กได้มากเท่าที่คุณต้องการด้วยสูตรที่กำหนด
Julien

142
@VictorDombrovsky ภาชนะที่หยุดเป็นเค้กในช่องแช่แข็ง
Jacob Ford

44
@Julien ถ้าภาพนั้นเป็นสูตรแล้วล่ะ Dockerfile ล่ะ? :)
Johnny Willer

71
@JohnnyWiller Analogies มีขีด จำกัด แต่บางทีเราสามารถเห็น Dockerfile เป็นรายการช้อปปิ้งของคุณสำหรับส่วนผสม ;-) มิฉะนั้นเรียก Dockerfile สูตรภาพแม่พิมพ์ภาชนะยังคงเป็นเค้กอร่อย
Julien

585

จากบทความของฉันเกี่ยวกับการปรับใช้นักเทียบท่าอัตโนมัติ :

รูปภาพเทียบกับนักเทียบท่า

ใน Dockerland มีภาพและมีภาชนะบรรจุ ทั้งสองมีความสัมพันธ์กันอย่างใกล้ชิด แต่ชัดเจน สำหรับฉันการจับขั้วสองขั้วนี้ทำให้นักเทียบท่าชัดเจนมาก

รูปคืออะไร

รูปภาพเป็นไฟล์เฉื่อยไม่เปลี่ยนรูปที่เป็นสแน๊ปช็อตของคอนเทนเนอร์ ภาพจะถูกสร้างขึ้นด้วยการสร้างคำสั่งและพวกเขาจะผลิตภาชนะเมื่อเริ่มต้นด้วยการวิ่ง ภาพจะถูกเก็บไว้ในรีจิสทรีหางเช่นregistry.hub.docker.com เนื่องจากสามารถมีขนาดค่อนข้างใหญ่ภาพจึงได้รับการออกแบบให้ประกอบด้วยเลเยอร์ของภาพอื่นทำให้สามารถส่งข้อมูลจำนวนเล็กน้อยเมื่อถ่ายโอนภาพผ่านเครือข่าย

สามารถแสดงภาพท้องถิ่นโดยการเรียกใช้docker images:

REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                    13.10               5e019ab7bf6d        2 months ago        180 MB
ubuntu                    14.04               99ec81b80c55        2 months ago        266 MB
ubuntu                    latest              99ec81b80c55        2 months ago        266 MB
ubuntu                    trusty              99ec81b80c55        2 months ago        266 MB
<none>                    <none>              4ab0d9120985        3 months ago        486.5 MB

บางสิ่งที่ควรทราบ:

  1. IMAGE ID เป็นอักขระ 12 ตัวแรกของตัวระบุที่แท้จริงสำหรับรูปภาพ คุณสามารถสร้างแท็กจำนวนมากของภาพที่กำหนด แต่ ID ของพวกเขาจะเหมือนกัน (เหมือนด้านบน)
  2. VIRTUAL SIZE เป็นเสมือนเพราะมันเพิ่มขนาดของเลเยอร์ต้นแบบที่แตกต่างกันทั้งหมด ซึ่งหมายความว่าผลรวมของค่าทั้งหมดในคอลัมน์นั้นอาจมีขนาดใหญ่กว่าพื้นที่ดิสก์ที่ใช้โดยอิมเมจเหล่านั้นทั้งหมด
  3. ค่าในคอลัมน์ REPOSITORY มาจากการ-tตั้งค่าสถานะของdocker buildคำสั่งหรือจากdocker tagอิมเมจที่มีอยู่ คุณมีอิสระในภาพแท็กโดยใช้ศัพท์ที่ทำให้รู้สึกถึงคุณ แต่รู้ว่านักเทียบท่าที่จะใช้แท็กเป็นสถานที่รีจิสทรีในหรือdocker pushdocker pull
  4. [REGISTRYHOST/][USERNAME/]NAME[:TAG]เต็มรูปแบบของแท็กคือ สำหรับubuntuข้างต้น REGISTRYHOST registry.hub.docker.comอนุมานได้ว่าจะเป็น ดังนั้นหากคุณวางแผนที่จะจัดเก็บภาพที่เรียกว่าmy-applicationในรีจิสทรีที่docker.example.comคุณควรติดแท็กภาพdocker.example.com/my-applicationนั้น
  5. คอลัมน์ TAG เป็นเพียงส่วน [: TAG] ของแท็กแบบเต็ม นี่เป็นคำศัพท์ที่โชคร้าย
  6. latestแท็กไม่ได้มีมนต์ขลังก็เพียงแท็กค่าเริ่มต้นเมื่อคุณไม่ได้ระบุแท็ก
  7. คุณสามารถมีภาพที่ไม่ได้ติดแท็กซึ่งสามารถระบุได้ด้วยรหัส IMAGE เท่านั้น สิ่งเหล่านี้จะได้รับ<none>แท็กและน่าเชื่อถือ มันง่ายที่จะลืมพวกเขา

ข้อมูลเพิ่มเติมเกี่ยวกับภาพที่ได้จากเอกสารหางและคำศัพท์

คอนเทนเนอร์คืออะไร

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

ดูภาชนะที่ใช้งานในท้องถิ่นด้วยdocker ps:

CONTAINER ID        IMAGE                               COMMAND                CREATED             STATUS              PORTS                    NAMES
f2ff1af05450        samalba/docker-registry:latest      /bin/sh -c 'exec doc   4 months ago        Up 12 weeks         0.0.0.0:5000->5000/tcp   docker-registry

ที่นี่ฉันกำลังเรียกใช้รีจิสตรีของ dockerized version เพื่อให้ฉันมีสถานที่ส่วนตัวในการจัดเก็บภาพของฉัน อีกสิ่งที่ควรทราบ:

  1. เช่นเดียวกับ IMAGE ID CONTAINER ID เป็นตัวระบุจริงสำหรับคอนเทนเนอร์ มันมีรูปแบบเดียวกัน แต่มันระบุวัตถุชนิดอื่น
  2. docker psเอาต์พุตเท่านั้นที่รันคอนเทนเนอร์ คุณสามารถดูภาชนะทั้งหมด ( ทำงานหรือหยุด ) docker ps -aด้วย
  3. NAMES สามารถใช้เพื่อระบุคอนเทนเนอร์ที่เริ่มต้นผ่านการ--nameตั้งค่าสถานะ

วิธีหลีกเลี่ยงอิมเมจและการ build คอนเทนเนอร์

หนึ่งในความผิดหวังในช่วงต้นของฉันที่มีหางเป็นสะสมอย่างต่อเนื่องดูเหมือนของภาพไม่ติดแท็กและภาชนะบรรจุหยุด ในบางครั้งการสะสมนี้ส่งผลให้ฮาร์ดไดรฟ์ maxed out ช้าลงแล็ปท็อปของฉันหรือหยุดการสร้างอัตโนมัติของฉัน พูดคุยเกี่ยวกับ "ตู้คอนเทนเนอร์ทุกที่"!

เราสามารถลบภาพที่ไม่ได้ติดแท็กทั้งหมดโดยรวมdocker rmiกับdangling=trueข้อความค้นหาล่าสุด:

docker images -q --filter "dangling=true" | xargs docker rmi

นักเทียบท่าจะไม่สามารถลบภาพที่อยู่ด้านหลังคอนเทนเนอร์ที่มีอยู่ดังนั้นคุณอาจต้องลบคอนเทนเนอร์ที่หยุดด้วยdocker rmก่อน:

docker rm `docker ps --no-trunc -aq`

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

  1. นำภาชนะที่ไม่มีประโยชน์หยุดอยู่docker rm [CONTAINER_ID]เสมอด้วย
  2. ลบภาพที่อยู่เบื้องหลังภาชนะที่ไร้ประโยชน์และหยุดdocker rmi [IMAGE_ID]เสมอ

5
ความแตกต่างที่ดีภาพ bte และภาชนะบรรจุ ช่วยได้มากสำหรับผู้เริ่มต้นอย่างฉัน
Gibbs

2
ฉันเดาว่าสิ่งที่ฉันติดอยู่คือวิธีที่รูปภาพทำงาน (ฉันใช้ boot2docker บน Windows) ทำไมเราสร้างภาพสำหรับแอปพลิเคชันพูด mysql ณ จุดนี้ mysql ทำงานอย่างไร? ฉันไม่จำเป็นต้องมีอิมเมจ Linux เพื่อเรียกใช้ mysql ด้านบนใช่ไหม
Kenny Worden

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

4
ใน Docker เวอร์ชันที่ใหม่กว่าคุณสามารถใช้docker image pruneในการล้างรูปภาพที่ห้อยอยู่ ตัดวัตถุนักเทียบท่าที่ไม่ได้ใช้ออก
Dario Seidl

3
ฉันใช้docker system pruneทำความสะอาดทุกอย่าง
Rami Alloush

137

ในคำง่าย ๆ

รูปภาพ -

แอ็พพลิเคชันระบบไฟล์และคอนฟิกูเรชัน (อ่านอย่างเดียว) ซึ่งใช้เพื่อสร้างคอนเทนเนอร์ รายละเอียดเพิ่มเติม

ภาชนะบรรจุ -

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


คำสำคัญอื่น ๆ ที่ควรแจ้งให้ทราบ:


ภูตนักเลง -

บริการเบื้องหลังทำงานบนโฮสต์ที่จัดการสิ่งปลูกสร้างการทำงานและการกระจายคอนเทนเนอร์ Docker

ลูกค้าเทียบท่า -

เครื่องมือบรรทัดคำสั่งที่อนุญาตให้ผู้ใช้โต้ตอบกับ Docker daemon

ร้านนักเทียบท่า -

ร้านค้าคือภาพสตรีของนักเทียบท่า คุณสามารถคิดว่ารีจิสทรีเป็นไดเรกทอรีของอิมเมจ Docker ที่มีอยู่ทั้งหมด

ภาพจากโพสต์บล็อกนี้มีค่าหนึ่งพันคำ

ป้อนคำอธิบายภาพที่นี่

(เพื่อความเข้าใจที่ลึกซึ้งยิ่งขึ้นโปรดอ่านสิ่งนี้ )

สรุป:

  • ดึงภาพจาก Docker Hub หรือสร้างจาก Dockerfile => ให้ภาพ Docker (ไม่สามารถแก้ไขได้)
  • เรียกใช้อิมเมจ ( docker run image_name:tag_name) => ให้รูปภาพทำงานอยู่เช่นคอนเทนเนอร์ (แก้ไขได้)

1
ขอบคุณ แหล่งที่มาของแผนภาพคืออะไร? มาจากเอกสารทางการของนักเทียบท่าหรือไม่?

ภาพที่โพสต์ที่ยอดเยี่ยม สิ่งหนึ่งที่ฉันกังวล: คุณพูดว่า "พบมันในขณะที่อ่านบทความ" - ถ้าไม่ใช่แผนภาพของคุณมันเป็นสิ่งสำคัญทางศีลธรรม [และจำเป็นต้องมีตามกฎหมาย] เพื่อให้เครดิตที่ครบกำหนด ("ที่มา"): ผู้แต่งภาพต้นฉบับคือ Who? เริ่มแรกพบที่ URL ใด
ToolmakerSteve

@ToolmakerSteve ขอบคุณสำหรับคำแนะนำฉันจะจำไว้และจะอัปเดตคำตอบทันทีที่ฉันพบแหล่งที่มา
Imran Ahmad

126

ในขณะที่มันง่ายที่จะคิดว่าภาชนะที่เป็นภาพการทำงานนี้ไม่ได้ค่อนข้างถูกต้อง

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


ฉันจะเปลี่ยนรูปภาพให้เป็นคอนเทนเนอร์ได้อย่างไรโดยไม่ต้องเรียกใช้
Janus Troelsen

12
@JanusTroelsen docker createใช้
Adrian Mouat

1
นี่คือความสับสนเล็กน้อย เราบอกว่ารูปภาพไม่เปลี่ยนรูป แต่เมื่อถูกเรียกใช้เป็นคอนเทนเนอร์จะเก็บการเปลี่ยนแปลงใด ๆ กับเลเยอร์บนสุดที่ไม่แน่นอนดังที่คุณกล่าว แต่เมื่อหยุดการเปลี่ยนแปลงเหล่านี้จะบันทึกเป็นเลเยอร์ใหม่ในภาพหรือไม่ ถ้าใช่แล้วเป็นไปได้อย่างไรที่ภาพต้นฉบับควรจะไม่เปลี่ยนรูป
Dchucks

4
ตกลงได้อ่านและได้รับคำตอบในหัวข้อนี้เอง "เมื่อคอนเทนเนอร์ถูกลบเลเยอร์ที่เขียนได้จะถูกลบด้วยรูปภาพต้นแบบยังคงไม่เปลี่ยนแปลง"
Dchucks

คำตอบที่เป็นประโยชน์มาก ฉันสับสนมาก่อน หากฉันถ่ายภาพให้เรียกใช้เป็นที่เก็บใส่ไฟล์ข้อความแบบสุ่มลงในที่เก็บและหยุดที่เก็บไฟล์ข้อความจะอยู่ในที่เก็บที่หยุดแล้ว แต่ไม่ใช่ภาพพื้นฐานที่ฉันดาวน์โหลด
James Allen

89

การอธิบายขั้นตอนการทำงานทั้งหมดอาจช่วยได้

ทุกอย่างเริ่มต้นด้วยDockerfile Dockerfile เป็นรหัสที่มาของภาพ

เมื่อสร้าง Dockerfile แล้วคุณจะสร้างมันขึ้นมาเพื่อสร้างอิมเมจของคอนเทนเนอร์ ภาพเป็นเพียง "เวอร์ชั่นที่คอมไพล์" ของ "ซอร์สโค้ด" ซึ่งก็คือ Dockerfile

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

ถัดไปคุณสามารถใช้ภาพในการทำงานภาชนะบรรจุ คอนเทนเนอร์ที่ใช้งานคล้ายกันมากในหลาย ๆ ด้านกับเครื่องเสมือน (แต่ไม่มีไฮเปอร์ไวเซอร์ )


44

ขั้นตอนการทำงาน

นี่คือเวิร์กโฟลว์แบบ end-to-end ที่แสดงคำสั่งต่างๆและอินพุตและเอาต์พุตที่สัมพันธ์กัน ที่ควรอธิบายความสัมพันธ์ระหว่างรูปภาพและคอนเทนเนอร์

+------------+  docker build   +--------------+  docker run -dt   +-----------+  docker exec -it   +------+
| Dockerfile | --------------> |    Image     | --------------->  | Container | -----------------> | Bash |
+------------+                 +--------------+                   +-----------+                    +------+
                                 ^
                                 | docker pull
                                 |
                               +--------------+
                               |   Registry   |
                               +--------------+

หากต้องการแสดงรายการรูปภาพที่คุณสามารถเรียกใช้งานได้ให้ดำเนินการดังนี้

docker image ls

หากต้องการแสดงรายการคอนเทนเนอร์คุณสามารถเรียกใช้คำสั่งบน:

docker ps

1
สำหรับไดอะแกรมเวิร์กโฟลว์ที่ครอบคลุมยิ่งขึ้นดูที่นี่: stackoverflow.com/a/46528745/714112
Sridhar Sarnobat

1
แต่การเลื่อนที่จำเป็นในศิลปะ ASCII นั้นเป็นปัญหา
ปีเตอร์มอร์เทนเซ่น

สามารถใช้ Unicode แทนรับกล่องที่ดูดีกว่าได้ เครื่องมือออนไลน์เป็นJavascript กล่องถอนเงินสาธิต
Peter Mortensen

40

ฉันไม่เข้าใจแนวคิดของภาพและเลเยอร์ทั้งๆที่อ่านคำถามทั้งหมดที่นี่แล้วในที่สุดก็เจอเอกสารที่ยอดเยี่ยมนี้จาก Docker (duh!)

ตัวอย่างมีกุญแจสำคัญที่จะเข้าใจแนวคิดทั้งหมด มันเป็นการโพสต์ที่มีความยาวดังนั้นฉันจึงสรุปประเด็นสำคัญที่ต้องเข้าใจเพื่อให้เกิดความชัดเจน

  • ภาพ : รูปภาพ Docker สร้างขึ้นจากชุดเลเยอร์แบบอ่านอย่างเดียว

  • Layer : แต่ละ Layer แสดงคำสั่งใน Dockerfile ของรูปภาพ

Example: Dockerfile ด้านล่างมีคำสั่งสี่คำแต่ละคำสั่งจะสร้างเลเยอร์

จาก Ubuntu: 15.04

คัดลอก / แอป

เรียกใช้ / แอป

CMD python /app/app.py

ที่สำคัญแต่ละชั้นเป็นเพียงชุดของความแตกต่างจากชั้นก่อนหน้า

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

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

การทำความเข้าใจกับรูปภาพและภาชนะบรรจุจากมุมมองขนาดต่อดิสก์

หากต้องการดูขนาดโดยประมาณของคอนเทนเนอร์ที่รันอยู่คุณสามารถใช้docker ps -sคำสั่ง คุณได้รับsizeและvirtual sizeเป็นผลลัพธ์สองรายการ:

  • ขนาด: จำนวนข้อมูล (บนดิสก์) ที่ใช้สำหรับเลเยอร์ที่เขียนได้ของแต่ละคอนเทนเนอร์

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

อีกแนวคิดที่สำคัญคือกลยุทธ์การคัดลอกเมื่อเขียน

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

ฉันหวังว่าจะช่วยคนอื่นเช่นฉัน


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

34

Dockerfile → (BUILD) → ภาพ → (Run) → คอนเทนเนอร์

  • Dockerfile : ประกอบด้วยชุดคำสั่ง Docker ที่จัดเตรียมระบบปฏิบัติการตามที่คุณต้องการและติดตั้ง / กำหนดค่าซอฟต์แวร์ทั้งหมดของคุณ

  • รูป : Dockerfile ที่คอมไพล์แล้ว ช่วยคุณประหยัดเวลาจากการสร้าง Dockerfile ขึ้นใหม่ทุกครั้งที่คุณต้องการเรียกใช้คอนเทนเนอร์ และเป็นวิธีซ่อนรหัสการจัดเตรียมของคุณ

  • Container : ระบบปฏิบัติการเสมือนนั้นเอง คุณสามารถใช้มันและเรียกใช้คำสั่งใด ๆ ที่คุณต้องการราวกับว่ามันเป็นสภาพแวดล้อมจริง คุณสามารถเรียกใช้ 1,000+ คอนเทนเนอร์จากอิมเมจเดียวกัน


การเปรียบเทียบที่ยอดเยี่ยม ถ้าฉันจะให้ 1,000 thumbs up ฉันจะ
Rich Lysakowski ระดับปริญญาเอก

16

เพียงแค่บอกว่าถ้าภาพเป็นระดับแล้วภาชนะที่เป็นตัวอย่างของการเรียนเป็นรันไทม์วัตถุ


13

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

ข้อ จำกัด โดยทั่วไปเกี่ยวข้องกับกระบวนการแยก, เกี่ยวข้องกับความปลอดภัย (เช่นการใช้การป้องกันSELinux ) และทรัพยากรระบบที่เกี่ยวข้อง (หน่วยความจำ, ดิสก์, CPU และระบบเครือข่าย)

จนกระทั่งเมื่อไม่นานมานี้มีเพียงเคอร์เนลในระบบที่ใช้ Unix เท่านั้นที่รองรับความสามารถในการเรียกใช้โปรแกรมปฏิบัติการภายใต้ข้อ จำกัด ที่เข้มงวด นั่นคือเหตุผลที่ว่าทำไมการสนทนาตู้คอนเทนเนอร์ในปัจจุบันส่วนใหญ่เกี่ยวข้องกับ Linux หรือ Unix distributions

นักเทียบท่าเป็นหนึ่งในแอพพลิเคชั่นที่รู้วิธีบอก OS (Linux เป็นส่วนใหญ่) ว่ามีข้อ จำกัด ในการใช้งานโปรแกรมปฏิบัติการได้อย่างไร ไฟล์เรียกทำงานอยู่ในอิมเมจ Docker ซึ่งเป็นเพียง tarfile ไฟล์ปฏิบัติการนั้นมักจะเป็นเวอร์ชั่นลีนุกซ์ของการกระจายลีนุกซ์ (Ubuntu, CentOS, Debian, ฯลฯ ) ที่กำหนดค่าไว้ล่วงหน้าเพื่อรันแอปพลิเคชั่นอย่างน้อยหนึ่งตัวภายใน

แม้ว่าคนส่วนใหญ่ใช้ฐาน Linux เป็นไฟล์ปฏิบัติการมันสามารถเป็นแอพพลิเคชั่นไบนารีอื่น ๆ ได้ตราบใดที่ระบบปฏิบัติการโฮสต์สามารถใช้งานได้ (ดูการสร้างอิมเมจพื้นฐานอย่างง่ายโดยใช้การขีดข่วน ) ไม่ว่าไบนารีในอิมเมจ Docker จะเป็นระบบปฏิบัติการหรือเพียงแค่แอปพลิเคชั่นไปยังโฮสต์ของระบบปฏิบัติการนั้นเป็นเพียงกระบวนการอื่นกระบวนการที่มีอยู่จะถูกควบคุมโดยขอบเขต OS ที่ตั้งไว้ล่วงหน้า

โปรแกรมอื่น ๆ ว่าเหมือนหางสามารถบอก OS โฮสต์ซึ่งขอบเขตที่จะนำไปใช้กับกระบวนการในขณะที่มีการทำงานรวมถึงLXC , libvirtและsystemd นักเทียบท่าเคยใช้แอพพลิเคชั่นเหล่านี้เพื่อโต้ตอบกับ Linux OS ทางอ้อม แต่ตอนนี้ Docker โต้ตอบโดยตรงกับ Linux โดยใช้ไลบรารีของตัวเองที่เรียกว่า " libcontainer "

ดังนั้นคอนเทนเนอร์จึงเป็นเพียงกระบวนการที่ทำงานในโหมด จำกัด เช่นเดียวกับchroot ที่ใช้ทำ

IMO สิ่งที่ทำให้นักเทียบท่าแตกต่างจากเทคโนโลยีคอนเทนเนอร์อื่น ๆ คือที่เก็บข้อมูล (Docker Hub) และเครื่องมือการจัดการที่ทำให้การทำงานกับคอนเทนเนอร์นั้นง่ายมาก

ดูหาง (ซอฟต์แวร์)


12

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

รูปภาพแสดงสถานะของตู้คอนเทนเนอร์ทุกเวลา ดังนั้นเวิร์กโฟลว์พื้นฐานคือ:

  1. สร้างภาพ
  2. เริ่มภาชนะ
  3. ทำการเปลี่ยนแปลงภาชนะ
  4. บันทึกคอนเทนเนอร์กลับเป็นรูปภาพ

8

ในฐานะที่เป็นคำตอบมากมายชี้ให้เห็นนี้: คุณสร้าง Dockerfileที่จะได้รับภาพและคุณเรียกใช้ ภาพที่จะได้รับตู้คอนเทนเนอร์

อย่างไรก็ตามขั้นตอนต่อไปนี้ช่วยให้ฉันรู้สึกดีขึ้นเกี่ยวกับอิมเมจและคอนเทนเนอร์ของ Docker:

1) สร้าง Dockerfile:

docker build -t my_image dir_with_dockerfile

2) บันทึกภาพเป็น.tarไฟล์

docker save -o my_file.tar my_image_id

my_file.tarจะเก็บภาพ เปิดด้วยtar -xvf my_file.tarและคุณจะได้เห็นเลเยอร์ทั้งหมด หากคุณดำน้ำลึกลงไปในแต่ละเลเยอร์คุณสามารถเห็นการเปลี่ยนแปลงที่เพิ่มเข้ามาในแต่ละเลเยอร์ (ควรอยู่ใกล้กับคำสั่งใน Dockerfile)

3) ในการดูภายในคอนเทนเนอร์คุณสามารถทำได้:

sudo docker run -it my_image bash

และคุณจะเห็นว่ามันเป็นเหมือนระบบปฏิบัติการ


6

อิมเมจเทียบเท่ากับการกำหนดคลาสใน OOP และเลเยอร์เป็นวิธีการและคุณสมบัติที่แตกต่างกันของคลาสนั้น

Containerคือการสร้างอินสแตนซ์ที่แท้จริงของภาพเช่นเดียวกับที่วัตถุเป็นอินสแตนซ์หรืออินสแตนซ์ของคลาส


4

ฉันคิดว่าเป็นการดีกว่าที่จะอธิบายในตอนแรก

docker run hello-worldสมมติว่าคุณเรียกใช้คำสั่ง เกิดอะไรขึ้น?

มันเรียกDocker CLIซึ่งรับผิดชอบในการใช้คำสั่ง Docker และเปลี่ยนเป็นการเรียกคำสั่งเซิร์ฟเวอร์ Docker ทันทีที่เซิร์ฟเวอร์ Dockerได้รับคำสั่งให้เรียกใช้รูปภาพมันจะตรวจสอบสภาพอากาศที่แคชรูปภาพเก็บภาพด้วยชื่อดังกล่าว

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

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

เมื่อคุณเรียกใช้เช่น Chrome บนคอมพิวเตอร์ของคุณจะเรียกระบบปฏิบัติการระบบปฏิบัติการเรียกเคอร์เนลและถามว่าเฮ้ฉันต้องการเรียกใช้โปรแกรมนี้ เคอร์เนลจัดการเพื่อเรียกใช้ไฟล์จากฮาร์ดดิสก์ของคุณ

ทีนี้ลองจินตนาการว่าคุณมีสองโปรแกรม Chrome และ Node.js Chrome ต้องการ Python เวอร์ชัน 2 เพื่อให้ทำงานได้และ Node.js ต้องการให้ Python เวอร์ชัน 3 ทำงาน หากคุณเพิ่งติดตั้ง Python v2 บนคอมพิวเตอร์ของคุณจะมีเฉพาะ Chrome เท่านั้นที่จะทำงานได้

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

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


3

อิมเมจ Docker จะรวมแอปพลิเคชันและสภาพแวดล้อมที่แอพพลิเคชั่นต้องการให้ทำงานและคอนเทนเนอร์เป็นอินสแตนซ์ที่ใช้งานของรูปภาพ

รูปภาพเป็นส่วนที่บรรจุของนักเทียบท่าซึ่งคล้ายคลึงกับ "ซอร์สโค้ด" หรือ "โปรแกรม" ตู้คอนเทนเนอร์เป็นส่วนการทำงานของ Docker ซึ่งคล้ายกับ "กระบวนการ"

ในคำถามเฉพาะส่วน "โปรแกรม" เท่านั้นที่ถูกอ้างถึงและนั่นคือภาพ ส่วน "กำลังทำงาน" ของนักเทียบท่าคือคอนเทนเนอร์ เมื่อมีการเรียกใช้คอนเทนเนอร์และทำการเปลี่ยนแปลงราวกับว่ากระบวนการนั้นทำการเปลี่ยนแปลงในซอร์สโค้ดของมันเองและบันทึกเป็นอิมเมจใหม่


3

ในด้านการเขียนโปรแกรม

ภาพเป็นรหัสที่มา

เมื่อคอมไพล์ซอร์สโค้ดถูกคอมไพล์และบิวด์จะถูกเรียกว่าแอปพลิเคชัน

เช่นเดียวกับที่ "เมื่อมีการสร้างอินสแตนซ์สำหรับรูปภาพ" จะเรียกว่า " คอนเทนเนอร์ "


1
Dockerfile เหมือนกับซอร์สโค้ด ภาพเหมือนไฟล์ที่ปฏิบัติการได้หลังจากคอมไพล์ซอร์สโค้ด / บิลด์ คอนเทนเนอร์เป็นเหมือนแอปพลิเคชันที่ทำงานจากไฟล์ปฏิบัติการ
ejlp12

อิมเมจไม่ใช่ซอร์สโค้ดสำหรับคอนเทนเนอร์ dockerfile เป็น metaclass หรือข้อกำหนดสำหรับชั้นเรียน รูปภาพเป็นคลาสหรือเทมเพลตสำหรับคอนเทนเนอร์และคอนเทนเนอร์เป็นอินสแตนซ์ของคลาส ภาชนะเป็นตัวอย่างที่ทำงาน คุณสามารถมีคลาสได้ 1,000 อินสแตนซ์ ภาพเหมือนรหัสวัตถุที่คอมไพล์ซึ่งสามารถเชื่อมโยงเข้ากับโปรแกรมอื่นและเรียกใช้เป็นส่วนหนึ่งของโปรแกรมนั้น
Rich Lysakowski ระดับปริญญาเอก

3

ภาพคือ "ภาพรวม" ของภาชนะ คุณสามารถสร้างรูปภาพจากคอนเทนเนอร์ ("สแน็ปช็อตใหม่") และคุณยังสามารถเริ่มคอนเทนเนอร์ใหม่จากรูปภาพ (อินสแตนซ์ "snapshot")

ตัวอย่างเช่นคุณสามารถสร้างอินสแตนซ์ของคอนเทนเนอร์ใหม่จากอิมเมจพื้นฐานรันคำสั่งบางอย่างในคอนเทนเนอร์แล้วสแนปชอตนั้นเป็นอิมเมจใหม่ จากนั้นคุณสามารถเรียกใช้ 100 คอนเทนเนอร์จากอิมเมจใหม่นั้น

สิ่งอื่น ๆ ที่ควรพิจารณา:

  • ภาพที่ทำจากเลเยอร์และเลเยอร์เป็น snapshot "diffs" (ดังนั้นเมื่อคุณกดรูปภาพคุณจะต้องส่ง "diff" ไปยังรีจิสทรีเท่านั้น)
  • Dockerfile กำหนดคำสั่งบางคำที่ด้านบนของภาพฐานที่สร้างเลเยอร์ใหม่ ("diffs") ที่ทำให้เกิดภาพใหม่ ("ภาพรวม")
  • แท็กรูปภาพไม่ใช่แค่แท็ก รูปภาพเหล่านี้เป็น "ชื่อเต็ม" ของรูปภาพ ("ที่เก็บ: แท็ก") docker imagesหากภาพเดียวกันมีหลายชื่อก็แสดงให้เห็นหลายครั้งเมื่อทำ

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

คำตอบนี้จะเริ่มต้นเมื่อสิ้นสุดกระบวนการ สามารถสร้างอิมเมจใหม่เป็นสแน็ปช็อตของคอนเทนเนอร์ แต่คอนเทนเนอร์ทั้งหมดต้องมีอิมเมจพาเรนต์ ในกรณีนี้ที่นี่ไม่มีปัญหาไก่และไข่เพราะภาพแรกแรกจะต้องสร้างจาก Dockerfile ก่อน มาก่อน Dockerfile แล้วรูปแล้วคอนเทนเนอร์ คอนเทนเนอร์สามารถใช้เป็นรากฐานสำหรับรูปภาพใหม่ แต่คอนเทนเนอร์นั้นต้องมี "รูปภาพหลัก"
Rich Lysakowski ระดับปริญญาเอก

3

ผมอยากจะเติมเต็มส่วนที่ขาดหายไประหว่างที่นี่และdocker images นักเทียบท่าใช้ระบบไฟล์รวม ( UFS ) สำหรับตู้คอนเทนเนอร์ซึ่งช่วยให้สามารถติดตั้งระบบไฟล์หลายระบบในลำดับชั้นและปรากฏเป็นระบบไฟล์เดียว ระบบไฟล์จากอิมเมจถูกเมาท์เป็นเลเยอร์และการเปลี่ยนแปลงใด ๆ กับคอนเทนเนอร์ที่รันอยู่จะทำกับเลเยอร์ที่เมาท์ด้านบนของสิ่งนี้ ด้วยเหตุนี้ Docker จึงต้องดูที่เลเยอร์การอ่าน - เขียนระดับสูงสุดเพื่อค้นหาการเปลี่ยนแปลงที่เกิดขึ้นกับระบบที่รันอยู่containersread-onlyread-write


1

สำหรับการเขียนโปรแกรมหุ่นเปรียบเทียบที่คุณสามารถคิดเทียบท่ามี ImageFactory นามธรรมซึ่งถือ ImageFactories พวกเขามาจากร้าน

จากนั้นเมื่อคุณต้องการสร้างแอพจาก ImageFactory นั้นคุณจะมีที่เก็บใหม่และคุณสามารถแก้ไขได้ตามที่คุณต้องการ DotNetImageFactory จะไม่เปลี่ยนรูปเพราะมันทำหน้าที่เป็นคลาสของโรงงานที่เป็นนามธรรมซึ่งจะส่งมอบอินสแตนซ์ที่คุณต้องการเท่านั้น

IContainer newDotNetApp = ImageFactory.DotNetImageFactory.CreateNew(appOptions);
newDotNetApp.ChangeDescription("I am making changes on this instance");
newDotNetApp.Run();

1

ในระยะสั้น:

Container คือส่วน (เสมือน) ในเคอร์เนลซึ่งใช้ร่วมกับระบบปฏิบัติการทั่วไปและเรียกใช้รูปภาพ (อิมเมจ Docker)

คอนเทนเนอร์เป็นแอ็พพลิเคชันแบบยั่งยืนที่จะมีแพ็กเกจและการพึ่งพาที่จำเป็นทั้งหมดเข้าด้วยกันเพื่อรันโค้ด


1

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


1

รูปภาพคือคลาสเป็นคอนเทนเนอร์สำหรับวัตถุ

ภาชนะเป็นตัวอย่างของภาพเป็นวัตถุเป็นตัวอย่างของชั้นเรียน


1

Dockerfile เหมือนกับสคริปต์ Bash ของคุณที่สร้าง tarball (อิมเมจ Docker)

คอนเทนเนอร์นักเทียบท่าเปรียบเสมือนรุ่น tarball ที่แยกออกมา คุณสามารถมีสำเนาได้มากเท่าที่คุณต้องการในโฟลเดอร์ที่แตกต่างกัน (บรรจุภัณฑ์)

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