อิมเมจนักเทียบท่านั้นเป็นรายการที่เชื่อมโยงกันของเลเยอร์ระบบไฟล์ แต่ละคำสั่งในDockerfileสร้างเลเยอร์ระบบไฟล์ที่อธิบายความแตกต่างในระบบไฟล์ก่อนและหลังการใช้งานคำสั่งที่เกี่ยวข้อง คำdocker inspect
สั่งย่อยสามารถใช้กับอิมเมจ docker เพื่อแสดงลักษณะของการเป็นรายการลิงก์ของเลเยอร์ระบบไฟล์
จำนวนเลเยอร์ที่ใช้ในภาพเป็นสิ่งสำคัญ
- เมื่อผลักหรือดึงภาพเนื่องจากจะมีผลต่อจำนวนการอัพโหลดหรือดาวน์โหลดที่เกิดขึ้นพร้อมกัน
- เมื่อเริ่มต้นคอนเทนเนอร์เนื่องจากเลเยอร์ถูกรวมเข้าด้วยกันเพื่อสร้างระบบไฟล์ที่ใช้ในคอนเทนเนอร์ ยิ่งเลเยอร์มีส่วนเกี่ยวข้องมากเท่าไรประสิทธิภาพก็ยิ่งแย่ลง แต่แบ็กเอนด์ของระบบไฟล์ที่แตกต่างกันจะได้รับผลกระทบจากสิ่งนี้
สิ่งนี้มีผลตามมาหลายประการสำหรับวิธีการสร้างภาพ คำแนะนำแรกและสำคัญที่สุดที่ฉันสามารถให้ได้คือ:
แนะนำ # 1ตรวจสอบให้แน่ใจว่าการสร้างขั้นตอนที่รหัสต้นฉบับของคุณมีส่วนเกี่ยวข้องมาเป็นปลายเป็นไปได้ในDockerfileและไม่ได้ผูกติดอยู่กับคำสั่งก่อนหน้านี้ใช้หรือ&&
;
เหตุผลสำหรับสิ่งนี้คือขั้นตอนก่อนหน้านี้ทั้งหมดจะถูกแคชและเลเยอร์ที่เกี่ยวข้องจะไม่จำเป็นต้องดาวน์โหลดซ้ำแล้วซ้ำอีก นี่หมายถึงการสร้างที่เร็วขึ้นและการปล่อยที่เร็วกว่าซึ่งอาจเป็นสิ่งที่คุณต้องการ ที่น่าสนใจก็เป็นเรื่องยากที่จะใช้แคชนักเทียบท่าอย่างเหมาะสม
คำแนะนำที่สองของฉันมีความสำคัญน้อยกว่า แต่ฉันคิดว่ามันมีประโยชน์มากจากมุมมองการบำรุงรักษา:
คำแนะนำ # 2อย่าเขียนคำสั่งที่ซับซ้อนในDockerfileแต่ควรใช้สคริปต์ที่จะคัดลอกและดำเนินการ
Dockerfileทำตามคำแนะนำนี้จะมีลักษณะ
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh
และอื่น ๆ คำแนะนำในการรวมหลายคำสั่งด้วย&&
ขอบเขตที่ จำกัด เท่านั้น การเขียนสคริปต์ง่ายขึ้นซึ่งคุณสามารถใช้ฟังก์ชั่น ฯลฯ เพื่อหลีกเลี่ยงความซ้ำซ้อนหรือเพื่อวัตถุประสงค์ด้านเอกสาร
ผู้ที่สนใจโดยก่อนการประมวลผลและเต็มใจที่จะหลีกเลี่ยงค่าใช้จ่ายเล็ก ๆ ที่เกิดจากCOPY
ขั้นตอนและเป็นจริงสร้าง on-the-บินDockerfileที่
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
ลำดับจะถูกแทนที่ด้วย
RUN base64 --decode … | sh -x
ที่…
เป็นรุ่นที่เข้ารหัส base64 apt_setup.sh
ของ
คำแนะนำที่สามของฉันสำหรับผู้ที่ต้องการ จำกัด ขนาดและจำนวนเลเยอร์ในราคาที่เป็นไปได้ในการสร้างที่นานขึ้น
คำแนะนำ # 3ใช้with
-idiom เพื่อหลีกเลี่ยงไฟล์ที่มีอยู่ในตัวกลางชั้น แต่ไม่ได้อยู่ในระบบไฟล์ที่เกิดขึ้น
ไฟล์ที่เพิ่มโดยคำสั่งนักเทียบท่าบางส่วนและถูกลบออกโดยคำสั่งบางส่วนในภายหลังจะไม่ปรากฏในระบบไฟล์ผลลัพธ์ แต่จะมีการกล่าวถึงสองครั้งในชั้นนักเทียบท่าซึ่งประกอบเป็นภาพนักเทียบท่าในการก่อสร้าง ครั้งหนึ่งด้วยชื่อและเนื้อหาแบบเต็มในเลเยอร์ที่เป็นผลมาจากคำสั่งเพิ่มและอีกครั้งหนึ่งเป็นการแจ้งเตือนการลบในเลเยอร์ที่เกิดจากคำสั่งลบมัน
ตัวอย่างเช่นสมมติว่าเราต้องการคอมไพเลอร์ C และรูปภาพบางรูปชั่วคราว
# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc
(ตัวอย่างที่เป็นจริงมากขึ้นจะสร้างซอฟต์แวร์บางอย่างด้วยคอมไพเลอร์แทนที่จะเป็นเพียงการยืนยันว่ามีสถานะอยู่ด้วยการ--version
ตั้งค่าสถานะ)
Snippet Dockerfile สร้างสามเลเยอร์ส่วนแรกประกอบด้วยชุด gcc เต็มรูปแบบดังนั้นแม้ว่าจะไม่ปรากฏในระบบไฟล์สุดท้ายข้อมูลที่เกี่ยวข้องยังคงเป็นส่วนหนึ่งของภาพในลักษณะเดียวกันและจำเป็นต้องดาวน์โหลดอัพโหลดและแกะเมื่อใดก็ตามที่ ภาพสุดท้ายคือ
with
-idiom เป็นรูปแบบที่พบในการเขียนโปรแกรมการทำงานที่จะเป็นเจ้าของทรัพยากรแยกและทรัพยากรที่ปล่อยจากตรรกะที่ใช้มัน มันง่ายที่จะแปลงสำนวนนี้เป็น shell-scripting และเราสามารถใช้คำสั่งก่อนหน้าเป็นสคริปต์ต่อไปนี้เพื่อใช้กับCOPY & RUN
ในคำแนะนำ # 2
# with_c_compiler SIMPLE-COMMAND
# Execute SIMPLE-COMMAND in a sub-shell with gcc being available.
with_c_compiler()
(
set -e
apt-get install -y gcc
"$@"
trap 'apt-get --purge autoremove -y gcc' EXIT
)
with_c_compiler\
gcc --version
with_c_compiler
คำสั่งที่ซับซ้อนสามารถจะกลายเป็นฟังก์ชั่นเพื่อให้พวกเขาสามารถเลี้ยงไป นอกจากนี้ยังเป็นไปได้ที่จะเชื่อมโยงการเรียกหลายwith_whatever
ฟังก์ชั่น แต่อาจไม่เป็นที่ต้องการมากนัก (การใช้คุณสมบัติที่เป็นความลับของเชลล์มากขึ้นเป็นไปได้อย่างแน่นอนที่จะทำให้with_c_compiler
คำสั่งที่ซับซ้อนยอมรับได้
หากเราต้องการเพิกเฉยคำแนะนำ # 2 ข้อมูลโค้ด Dockerfile ที่ได้จะเป็นเช่นนั้น
RUN apt-get install -y gcc\
&& gcc --version\
&& apt-get --purge autoremove -y gcc
ซึ่งไม่ใช่เรื่องง่ายที่จะอ่านและบำรุงรักษาเพราะความงงงวย ดูว่าตัวแปรของเชลล์สคริปต์นั้นให้ความสำคัญกับส่วนที่สำคัญอย่างไรgcc --version
ในขณะที่&&
ตัวแปรที่ถูกล่ามโซ่ฝังอยู่ในส่วนที่อยู่ตรงกลางของเสียง