หลายจาก - ความหมาย


113

ฉันต้องการสร้างอิมเมจนักเทียบท่าสำหรับโปรเจ็กต์ Linkuriousบน github ซึ่งต้องใช้ทั้งฐานข้อมูล Neo4j และ Node.js เพื่อรัน

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

ภาพฐาน: ภาพที่ไม่มีพาเรนต์เป็นภาพฐาน

จากที่ฉันอ่านพบว่าฉันจะมีภาพฐานได้ก็ต่อเมื่อภาพนั้นไม่มีภาพฐาน

แต่ภาพฐานคืออะไร? หมายความว่าถ้าฉันประกาศ neo4j / neo4j ในคำสั่ง FROM เมื่อรูปภาพของฉันถูกเรียกใช้ฐานข้อมูลนีโอจะทำงานโดยอัตโนมัติและพร้อมใช้งานภายในคอนเทนเนอร์บนพอร์ต 7474

อ่านข้อมูลอ้างอิง Docker (ดู: https://docs.docker.com/reference/builder/#from ) ฉันเห็น:

FROM สามารถปรากฏได้หลายครั้งภายใน Dockerfile เดียวเพื่อสร้างภาพหลายภาพ เพียงจดบันทึกเอาต์พุต ID ภาพสุดท้ายโดยการคอมมิตก่อนคำสั่ง FROM ใหม่แต่ละคำสั่ง

ฉันต้องการสร้างภาพหลายภาพหรือไม่? ดูเหมือนว่าสิ่งที่ฉันต้องการคือการมีภาพเดียวที่มีเนื้อหาของภาพอื่น ๆ เช่น neo4j และ node.js

ฉันไม่พบคำสั่งในการประกาศการอ้างอิงในคู่มืออ้างอิง ไม่มีการอ้างอิงเช่นใน RPM ที่ในการเรียกใช้รูปภาพของฉันบริบทการเรียกต้องติดตั้งภาพที่ต้องการก่อนหรือไม่

ฉันสับสน ...


หมายเหตุ: พฤษภาคม 2017 ตอนนี้คุณมีหลายไฟล์FROMในไฟล์Dockerfile. ดูคำตอบที่แก้ไขของฉันด้านล่าง
VonC

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

คำตอบ:


113

ภาพฐานคืออะไร?

ชุดของไฟล์บวกEXPOSE'd พอร์ตENTRYPOINTและCMD.
คุณสามารถเพิ่มไฟล์และสร้างอิมเมจใหม่ตามอิมเมจพื้นฐานนั้นโดยDockerfileเริ่มต้นใหม่ด้วยFROMคำสั่ง: รูปภาพที่กล่าวถึงหลังFROMคือ "อิมเมจพื้นฐาน" สำหรับอิมเมจใหม่ของคุณ

หมายความว่าถ้าฉันประกาศneo4j/neo4jในFROMคำสั่งว่าเมื่อรูปภาพของฉันถูกเรียกใช้ฐานข้อมูลนีโอจะทำงานโดยอัตโนมัติและพร้อมใช้งานภายในคอนเทนเนอร์บนพอร์ต 7474

เฉพาะในกรณีที่คุณไม่เขียนทับCMDและENTRYPOINT.
แต่ภาพในตัวมันก็เพียงพอแล้ว: คุณจะใช้FROM neo4j/neo4jif คุณต้องเพิ่มไฟล์ที่เกี่ยวข้องกับneo4jการใช้งานneo4jไฟล์.

FROM สามารถปรากฏได้หลายครั้งภายใน Dockerfile เดียว

อย่า: มีข้อเสนอให้ลบ "คุณลักษณะ" นั้นอยู่ดี ( ฉบับ 13026 )

ฉบับ 14412กล่าวถึง:

การใช้หลายตัวFROMไม่ใช่คุณสมบัติ แต่เป็นข้อบกพร่อง (โอ้ดีขีด จำกัด นั้นแน่นและมีกรณีการใช้งานน้อยสำหรับหลาย ๆ ตัวFROMใน Dockerfile)


ปรับปรุงพฤษภาคม 2017 (18 เดือนต่อมา) กับนักเทียบท่า (Moby) 17.05-CE

สามารถใช้หลาย FROM ใน Dockerfile เดียว
โปรดดูที่ " รูปแบบการสร้างเทียบกับหลายขั้นตอนในการสร้างนักเทียบท่า " (โดยอเล็กซ์เอลลิส ) และส่งเสริมการขาย 31,257โดยTonis Tiigi

ก่อน:

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

หลังจาก:

ไวยากรณ์ทั่วไปเกี่ยวข้องกับการเพิ่มFROMเวลาเพิ่มเติมภายใน Dockerfile ของคุณ - แล้วแต่ว่าข้อความใดจะเป็นFROMรูปพื้นฐานสุดท้าย COPY --from=<base_image_number>ในการคัดลอกสิ่งประดิษฐ์และผลจากการใช้ภาพกลาง

ส่วนแรกของ Dockerfile:

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

ส่วนที่สองของเดียวกัน Dockerfile (!):

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app    .
CMD ["./app"]  

ผลลัพธ์จะเป็นสองภาพภาพหนึ่งสำหรับการสร้างภาพหนึ่งมีเพียงแอปที่เป็นผลลัพธ์ ( เล็กกว่ามาก )

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

multi               latest              bcbbf69a9b59        6 minutes ago       10.3MB  
golang              1.7.3               ef15416724f6        4 months ago        672MB  

2
น่าเสียดายเกี่ยวกับการลบ FROM หลายรายการ ดูเหมือนว่าจะมีประโยชน์มากที่สุดสำหรับฉันโดยเฉพาะอย่างยิ่งในกรณีที่ไม่มีกลไกการพึ่งพา ตัวอย่างเช่นด้วย RPM ฉันสามารถประกาศได้ว่าแพ็คเกจของฉันต้องการแพ็คเกจอื่นเพื่อให้ทำงานได้ในเวลาติดตั้งทุกอย่างจะถูกตั้งค่าให้ฉัน ความจริงก็คือทุกสิ่งส่วนใหญ่จะต้องมีการอ้างอิงหลาย ๆ อย่างดังนั้นในกรณีที่ไม่มีหลาย FROMs มันควรจะทำงานอย่างไร?
ekkis

3
@ekkis ตามที่ฉันได้กล่าวไว้ในคำตอบก่อนหน้าของฉัน ( stackoverflow.com/a/33295292/6309 ) คุณเรียกใช้ระบบของคุณโดยการจัดเตรียมหลายคอนเทนเนอร์แต่ละอันให้บริการเฉพาะและสื่อสารผ่าน --link ( docs.docker.com/ userguide / dockerlinks / … )
VonC

2
@ VonC แน่นอนว่าในโลกแห่งอุดมคติด้วยแอพใหม่และรูปแบบทั้งหมดที่เข้าใจ ในระหว่างนี้ฉันคาดว่าจะมีผู้คนจำนวนมากที่พยายามย้ายโซลูชันของพวกเขาไปยังนักเทียบท่าและมีความต้องการที่ไม่ได้รับการแก้ไขโดยระบบเครือข่ายเช่นการพึ่งพาซอฟต์แวร์ทั้งหมดนี้ใช้ฐานที่เข้ากันได้ แต่มาจาก Dockerfiles หลายไฟล์ แต่สิ่งที่ดีที่สุดที่ฉันสามารถเข้าใจได้คือการแฮ็ก Dockerfiles เพื่อสร้างของฉันเอง
rainabba

@rainabba เห็นด้วย เสาหินเดิมจะไม่สามารถย้ายได้อย่างง่ายดาย อ่านที่น่าสนใจ: martinfowler.com/articles/… , threedots.tech/post/microservices-or-monolith-its-detail , hackernoon.com/…
VonC

2

คำตอบแรกซับซ้อนเกินไปเป็นประวัติศาสตร์และไม่เป็นข้อมูลสำหรับรสนิยมของฉัน


จริงๆแล้วมันค่อนข้างง่าย Docker จัดเตรียมฟังก์ชันการทำงานที่เรียกว่าการสร้างหลายขั้นตอนแนวคิดพื้นฐานที่นี่คือ

  • ช่วยให้คุณไม่ต้องลบสิ่งที่คุณไม่ต้องการด้วยตนเองโดยบังคับให้คุณอนุญาตพิเศษในสิ่งที่คุณต้องการ
  • ทรัพยากรฟรีที่อาจถูกนำไปใช้เนื่องจากการใช้งาน Docker

เริ่มกันที่ข้อแรก บ่อยครั้งที่คุณจะเห็น Debian

RUN apt-get update \ 
  && apt-get dist-upgrade \
  && apt-get install <whatever> \
  && apt-get clean

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

RUN apt-get update ;
RUN apt-get dist-upgrade;
RUN apt-get install <whatever>;
RUN apt-get clean;

มันจะส่งผลให้มีรูปภาพกลางชั่วคราวอีก 3 รูป การลดขนาดเป็นภาพเดียวยังมีปัญหาอีกอย่างหนึ่งนั่นคือapt-get cleanไม่ได้ล้างสิ่งประดิษฐ์ที่ใช้ในการติดตั้ง หากผู้ดูแล Debian รวมไว้ในการติดตั้งสคริปต์ที่ปรับเปลี่ยนระบบการแก้ไขจะมีอยู่ในโซลูชันสุดท้ายด้วย (ดูpepperflashplugin-nonfreeตัวอย่างเช่น)

ด้วยการใช้งานสร้างหลายขั้นตอนคุณจะได้รับประโยชน์ทั้งหมดจากการดำเนินการที่เปลี่ยนแปลงเพียงครั้งเดียว แต่คุณจะต้องลงรายการที่อนุญาตพิเศษด้วยตนเองและคัดลอกไฟล์ที่แนะนำในภาพชั่วคราวโดยใช้COPY --fromไวยากรณ์ที่บันทึกไว้ที่นี่ ยิ่งไปกว่านั้นมันเป็นทางออกที่ยอดเยี่ยมที่ไม่มีทางเลือกอื่น (เช่น an apt-get clean) และคุณจะมีไฟล์ที่ไม่ต้องการจำนวนมากในภาพสุดท้ายของคุณ

ดูสิ่งนี้ด้วย


ขอบคุณ แต่ฉันไม่เห็นว่าคุณจัดการกับปัญหาของฉันอย่างไร สำหรับฉันแล้ว FROM เป็นกลไกการถ่ายทอดทางพันธุกรรมและการมีหลายคำสั่งหมายความว่าฉันสามารถสืบทอดจากพ่อแม่หลายคนได้ ในคำตอบของคุณคุณไม่ได้กล่าวถึง FROM หรือแนวคิดในการใช้ประโยชน์จากบรรจุภัณฑ์ของซอฟต์แวร์โดยผู้อื่น
ekkis

1
บางทีนั่นอาจเป็นความสับสน FROMโดยหลักแล้วเป็นการประกาศเนมสเปซ ผู้มีคุณสมบัติเหมือนส่วนขยายมากกว่าการสืบทอด คุณสามารถประกาศหลายเนมสเปซ และแต่ละเนมสเปซเหล่านั้นสามารถขยายเนมสเปซอื่นได้ @ekkis หากคำตอบอื่นเหมาะกับคุณก็ให้ยึดติดกับมัน
Evan Carroll
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.