CMD และ ENTRYPOINT แตกต่างกันอย่างไรใน Dockerfile


1698

ใน Dockerfiles มีสองคำสั่งที่มีลักษณะคล้ายกับฉัน: และCMD ENTRYPOINTแต่ฉันเดาว่ามีความแตกต่าง (บอบบาง?) ระหว่างพวกเขา - ไม่อย่างนั้นคงไม่มีเหตุผลที่จะมีสองคำสั่งสำหรับสิ่งเดียวกัน

เอกสารประกอบสำหรับ CMD

วัตถุประสงค์หลักของ CMD คือการให้ค่าเริ่มต้นสำหรับคอนเทนเนอร์ที่ดำเนินการ

และสำหรับENTRYPOINT:

ENTRYPOINT ช่วยให้คุณกำหนดค่าคอนเทนเนอร์ที่คุณสามารถเรียกใช้เป็นปฏิบัติการได้

ดังนั้นความแตกต่างระหว่างสองคำสั่งคืออะไร?


12
โพสต์บล็อกนี้มีคำอธิบายที่ดีของความแตกต่างและวิธีการที่พวกเขาสามารถใช้ร่วมกันเกินไป: crosbymichael.com/dockerfile-best-practices.html
slm

2
^ นั่น! ขอบคุณ @slm ต่อไปนี้เป็นข้อมูลอ้างอิงที่คล้ายกันซึ่งอาจเป็นข้อมูลอัปเดตอีกเล็กน้อย: docs.docker.com/reference/builder/#entrypoint
Adam Monsen


1
ลิงค์นี้ให้ความแตกต่างระหว่าง RUN, CMD และ ENTRYPOINT: goinbigdata.com/docker-run-vs-cmd-vs-entrypoint
prafi

1
@JaimeHablutzel วลีนี้เป็นที่โปรดปรานของตัวเอง
Jonathan Komar

คำตอบ:


1736

นักเทียบท่ามีจุดเริ่มต้นเริ่มต้นซึ่งเป็น/bin/sh -cแต่ไม่มีคำสั่งเริ่มต้น

เมื่อคุณเรียกนักเทียบท่าเช่นนี้ docker run -i -t ubuntu bash จุดเข้าใช้งานเป็นค่าเริ่มต้น/bin/sh -cภาพที่และคำสั่งคือ ubuntubash

คำสั่งรันผ่านจุดเข้าใช้งาน /bin/sh -c bashนั่นคือสิ่งที่เกิดขึ้นจริงที่ได้รับการดำเนินการคือ สิ่งนี้ทำให้นักเทียบท่าใช้งานRUNได้อย่างรวดเร็วโดยอาศัย parser ของเชลล์

ต่อมาผู้คนขอให้สามารถปรับแต่งสิ่งนี้ได้ENTRYPOINTและ--entrypointได้รับการแนะนำ

ทุกอย่างubuntuในตัวอย่างด้านบนเป็นคำสั่งและถูกส่งไปยังจุดเข้าใช้งาน เมื่อใช้การเรียนการสอนก็เป็นสิ่งราวกับว่าคุณกำลังทำCMD จะเป็นพารามิเตอร์ของจุดเข้าใช้งานdocker run -i -t ubuntu <cmd><cmd>

docker run -i -t ubuntuนอกจากนี้คุณยังจะได้รับผลเหมือนกันถ้าคุณแทนพิมพ์คำสั่งนี้ คุณจะยังคงเริ่ม bash shell ในคอนเทนเนอร์ได้เนื่องจากubuntu Dockerfileระบุ CMD เริ่มต้น:CMD ["bash"]

เมื่อทุกอย่างถูกส่งผ่านไปยังจุดเข้าคุณสามารถมีพฤติกรรมที่ดีมากจากภาพของคุณ ตัวอย่างเช่น @Jiri ดีมันแสดงให้เห็นว่าจะใช้รูปภาพเป็น "ไบนารี่" ได้อย่างไร เมื่อใช้["/bin/cat"]เป็นจุดเข้าใช้งานแล้วทำdocker run img /etc/passwdคุณได้รับมันเป็นคำสั่งและส่งผ่านไปยังจุดเข้าใช้งานเพื่อให้การดำเนินการผลสุดท้ายก็คือ/etc/passwd/bin/cat /etc/passwd

อีกตัวอย่างหนึ่งคือการมี cli ใด ๆ เป็นจุดเข้าใช้งาน ตัวอย่างเช่นถ้าคุณมีภาพ Redis แทนการทำงานdocker run redisimg redis -H something -u toto get keyคุณก็สามารถมีและใช้แล้วเช่นนี้สำหรับผลเดียวกัน:ENTRYPOINT ["redis", "-H", "something", "-u", "toto"]docker run redisimg get key


3
ไม่ใช่เลย. ENTRYPOINT ตั้งค่าเมตาดาต้าที่สามารถ (แต่สามารถแทนที่ได้) ที่รันไทม์ดังนั้นหากคุณไม่เปลี่ยนแปลงอะไรหลังจากเริ่มต้นคอนเทนเนอร์ของคุณผลลัพธ์จะเหมือนกันอย่างไรก็ตาม RUN จะถูกสร้างขึ้นที่เวลาสร้างและไม่ว่าคุณจะทำอะไรก็ตาม ทำที่ runtime มันจะอยู่ที่นี่
creack

8
โดยค่าเริ่มต้นไม่มีENTRYPOINT; การใช้เชลล์ขึ้นอยู่กับรูปแบบที่ใช้ของCMDคำสั่ง ( docs.docker.com/engine/reference/builder/#cmd )
Blaisorblade

19
ขอบคุณสำหรับสิ่งนี้บริบททางประวัติศาสตร์ช่วยได้มากในขณะที่ฉันดิ้นรนที่จะจดจำกฎที่ดูเหมือนจะผิดเกี่ยวกับสิ่งที่ถูกเขียนทับและสิ่งที่ผนวกเข้ามา ฯลฯ จุดที่มีประโยชน์สำหรับนักเขียนเอกสารด้านเทคนิคทุกที่: ช่วยผู้อ่านสร้างแบบจำลองทางจิตของระบบ อย่าเพียงแสดงข้อเท็จจริงและสถานการณ์ :-)
Ashirley

84
นี่คือคำตอบที่ยอดเยี่ยม ผมคิดว่าเอกสารหางควรเพิ่มนี้อยู่ภายใต้ส่วนที่เรียกว่าเทียบกับCMD ENTRYPOINT
Tarik

5
@ Webman ไม่พวกเขาเป็นสองคำแนะนำที่แตกต่างกัน หากทั้งคู่มีอยู่ CMD จะถือว่าเป็นพารามิเตอร์ของ ENTRYPOINT
Light.G

627

ENTRYPOINTระบุคำสั่งที่จะถูกดำเนินการเมื่อภาชนะที่จะเริ่มต้น

ข้อโต้แย้งระบุว่าจะถูกป้อนให้กับCMDENTRYPOINT

หากคุณต้องการสร้างภาพเฉพาะคำสั่งเฉพาะคุณจะใช้ ENTRYPOINT ["/path/dedicated_command"]

มิฉะนั้นถ้าคุณต้องการที่จะทำให้ภาพเพื่อวัตถุประสงค์ทั่วไปคุณสามารถปล่อยให้ENTRYPOINTพลรบและใช้เท่าที่คุณจะสามารถที่จะแทนที่การตั้งค่าโดยการจัดหาข้อโต้แย้งCMD ["/path/dedicated_command"]docker run

ตัวอย่างเช่นหาก Dockerfile ของคุณคือ:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

การเรียกใช้อิมเมจโดยไม่มีอาร์กิวเมนต์จะทำการปิง localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

ตอนนี้การรันอิมเมจด้วยอาร์กิวเมนต์จะทำการ ping อาร์กิวเมนต์:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

สำหรับการเปรียบเทียบหาก Dockerfile ของคุณคือ:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

การเรียกใช้อิมเมจโดยไม่มีอาร์กิวเมนต์จะทำการปิง localhost:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

แต่การเรียกใช้อิมเมจที่มีอาร์กิวเมนต์จะเรียกใช้อาร์กิวเมนต์:

docker run -it test bash
root@e8bb7249b843:/#

ดูบทความนี้จาก Brian DeHamer สำหรับรายละเอียดเพิ่มเติม: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/


219
The ENTRYPOINT specifies a command that will always be executed when the container starts. The CMD specifies arguments that will be fed to the ENTRYPOINT.เป็นบทสรุปที่ดีในประเด็น
Jingguo Yao

1
ENTRYPOINT ยังสามารถเขียนทับได้โดยใช้ --Filepoint flag สำหรับตัวอย่างเช่นนักเทียบท่าวิ่ง -it - ผู้ใช้จุดทดสอบ bash
seenimurugan

2
ฉันชอบตัวอย่างของคุณมันมีประโยชน์จริง ๆ !
Chau Giang

2
@Jingguo Yao: เกิดอะไรขึ้นถ้า CMD มีคำสั่งเช่น - CMD ["nginx", "- g", "daemon", "off"]? มันจะถูกผูกมัด?
KMC

@KMC CMD เป็นอาร์กิวเมนต์เริ่มต้นของ ENTRYPOINT คุณจะแทนที่มันโดยส่ง ARG ใหม่เมื่อเรียกใช้รูปภาพ
MGP

237

ตามเอกสารนักเทียบท่า ,

ทั้งคำสั่ง CMD และ ENTRYPOINT กำหนดว่าคำสั่งใดที่จะถูกเรียกใช้งานเมื่อเรียกใช้คอนเทนเนอร์ มีกฎบางอย่างที่อธิบายถึงความร่วมมือของพวกเขา

  1. Dockerfile ควรระบุอย่างน้อยหนึ่งคำสั่งCMDหรือENTRYPOINT
  2. ENTRYPOINT ควรถูกกำหนดเมื่อใช้คอนเทนเนอร์เป็นไฟล์เรียกทำงาน
  3. CMDควรใช้เป็นวิธีในการกำหนดอาร์กิวเมนต์เริ่มต้นสำหรับENTRYPOINTคำสั่งหรือสำหรับการดำเนินการคำสั่ง ad-hoc ในคอนเทนเนอร์
  4. CMD จะถูกเขียนทับเมื่อเรียกใช้คอนเทนเนอร์ด้วยอาร์กิวเมนต์อื่น

ตารางด้านล่างแสดงสิ่งที่เรียกใช้งานคำสั่งสำหรับชุดค่าผสมENTRYPOINT/ ต่างๆCMD :

- No ENTRYPOINT

╔════════════════════════════╦═════════════════════════════╗
║ No CMD                     ║ error, not allowed          ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════╝

- ENTRYPOINT exec_entry p1_entry

╔════════════════════════════╦══════════════════════════════════╗
║ No CMD                     ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ /bin/sh -c exec_entry p1_entry   ║
╟────────────────────────────╫──────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry   ║
╚════════════════════════════╩══════════════════════════════════╝

- ENTRYPOINT [“exec_entry”, “p1_entry”]

╔════════════════════════════╦═════════════════════════════════════════════════╗
║ No CMD                     ║ exec_entry p1_entry                             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_entry p1_entry exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝

px_cmd และ exec_entry คืออะไร เมื่อพวกเขาอยู่ในบรรทัดการปฏิบัติการเดียวกันหมายความว่าอะไร? พวกเขาถูกส่งผ่านเป็นอาร์กิวเมนต์กัน? แม้ในขณะที่/bin/sh -cมีส่วนเกี่ยวข้อง?
Danielo515

1
@ Danielo515 ทั้ง 'px_cmd' และ 'exec_entry' เป็นเพียงสตริงตัวอย่างที่นี่ คุณอาจสังเกตเห็นว่า/bin/sh -cจะถูกเพิ่มไปยัง CMD เป็นคำนำหน้าในขณะที่ CMD เขียนในไวยากรณ์ปฏิบัติการ (ไม่ใช่ไวยากรณ์ของรายการ)
Light.G

1
@royki หากผู้ใช้ระบุอาร์กิวเมนต์เพื่อให้นักเทียบท่าทำงานพวกเขาจะแทนที่ค่าเริ่มต้นที่ระบุใน CMD
donrondadon

2
ENTRYPOINT exec_entry p1_entถูกอธิบายอย่างผิดพลาด รูปแบบเปลือกป้องกัน CMD หรือเรียกใช้อาร์กิวเมนต์บรรทัดคำสั่งใด ๆ จากการใช้ - docs.docker.com/engine/reference/builder/#entrypoint
Mariusz Miesiak

1
@MariuszMiesiak ได้ทำการอัพเดทแล้ว ขอบคุณสำหรับความคิดเห็นของคุณ
Rafaf Tahsin

170

ใช่นั่นเป็นคำถามที่ดี ฉันยังไม่เข้าใจทั้งหมด แต่:

ฉันเข้าใจว่าENTRYPOINTเป็นไบนารีที่กำลังดำเนินการ คุณสามารถแทนที่จุดเข้าใช้งานโดย --entrypoint = ""

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD เป็นอาร์กิวเมนต์เริ่มต้นไปยังคอนเทนเนอร์ หากไม่มีจุดเข้าใช้งานอาร์กิวเมนต์เริ่มต้นคือคำสั่งที่ดำเนินการ ด้วย entrypoint, cmd จะถูกส่งไปยัง entrypoint เป็นอาร์กิวเมนต์ คุณสามารถจำลองคำสั่งด้วยจุดเข้าใช้งาน

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

ดังนั้นข้อดีหลักคือด้วย entrypoint คุณสามารถส่งอาร์กิวเมนต์ (cmd) ไปยังคอนเทนเนอร์ของคุณ เพื่อให้บรรลุสิ่งนี้คุณต้องใช้ทั้ง:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

และ

docker build -t=cat .

จากนั้นคุณสามารถใช้:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT

@Blauhirn ในกรณีของคุณคุณต้องเพิ่มอาร์กิวเมนต์ไปยัง CMD ในรายการไวยากรณ์และตรวจสอบให้แน่ใจว่าจุดเข้าใช้งานที่คุณระบุไว้สามารถแยกอาร์กิวเมนต์ของคุณใน CMD ได้ โดยปกติฉันจะเพิ่มอาร์กิวเมนต์ '-h' ลงในจุดเริ่มต้น จากนั้นฉันอาจดำเนินการdocker run image_name -hเพื่อแสดงข้อมูลความช่วยเหลือบางอย่างของภาพนี้
Light.G

1
นี่เป็นคำตอบที่ง่ายและชัดเจนที่สุด
Eric Wang

44

ความแตกต่างระหว่าง CMD และ ENTRYPOINT โดยสัญชาตญาณ :

  • ENTRYPOINT: คำสั่งให้ทำงานเมื่อคอนเทนเนอร์เริ่มต้น
  • CMD: คำสั่งให้รันเมื่อคอนเทนเนอร์เริ่มต้นหรือขัดแย้งกับ ENTRYPOINT หากระบุ

ใช่มันมั่วไปหมด

คุณสามารถลบล้างสิ่งเหล่านี้ได้เมื่อเรียกใช้นักเทียบท่า

ความแตกต่างระหว่าง CMD และการเข้าร่วมตามตัวอย่าง :

docker run -it --rm yourcontainer /bin/bash            <-- /bin/bash overrides CMD
                                                       <-- /bin/bash does not override ENTRYPOINT
docker run -it --rm --entrypoint ls yourcontainer      <-- overrides ENTRYPOINT with ls
docker run -it --rm --entrypoint ls yourcontainer  -la  <-- overrides ENTRYPOINT with ls and overrides CMD with -la

เพิ่มเติมเกี่ยวกับความแตกต่างระหว่างCMDและENTRYPOINT:

อาร์กิวเมนต์docker runเช่น / bin / bash จะแทนที่คำสั่ง CMD ใด ๆ ที่เราเขียนไว้ใน Dockerfile

docker run [args]จุดเข้าใช้งานไม่สามารถแทนที่ในเวลาทำงานกับคำสั่งปกติเช่น argsในตอนท้ายของdocker run [args]จะถูกจัดให้เป็นข้อโต้แย้งที่จะจุดเข้าใช้งาน ด้วยวิธีนี้เราสามารถสร้างซึ่งเป็นเหมือนไบนารีเช่นปกติcontainerls

ดังนั้น CMD สามารถทำหน้าที่เป็นพารามิเตอร์เริ่มต้นเพื่อ ENTRYPOINT และจากนั้นเราสามารถแทนที่ CMD args จาก [args]

--entrypointจุดเข้าใช้งานสามารถแทนที่ด้วย


38

โดยสังเขป:

  • CMD ตั้งค่าคำสั่งเริ่มต้นและ / หรือพารามิเตอร์ซึ่งสามารถเขียนทับจากบรรทัดคำสั่งเมื่อเรียกใช้คอนเทนเนอร์นักเทียบท่า
  • คำสั่ง ENTRYPOINT และพารามิเตอร์จะไม่ถูกเขียนทับจากบรรทัดคำสั่ง อาร์กิวเมนต์บรรทัดคำสั่งทั้งหมดจะถูกเพิ่มแทนพารามิเตอร์ ENTRYPOINT

หากคุณต้องการรายละเอียดเพิ่มเติมหรือต้องการเห็นความแตกต่างในตัวอย่างมีโพสต์บล็อกที่เปรียบเทียบ CMD และการเข้าร่วมงานกับตัวอย่างมากมาย - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/


21

ฉันจะเพิ่มคำตอบของฉันเป็นตัวอย่าง1ที่อาจช่วยให้คุณเข้าใจความแตกต่าง

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

FROM ubuntu
CMD sleep 10

ตอนนี้เราสร้างภาพ:

docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits

ถ้าเราต้องการเปลี่ยนจำนวนวินาที? เราจะต้องเปลี่ยนDockerfileค่าตามที่ฮาร์ดโค้ดที่นั่นหรือแทนที่คำสั่งโดยระบุค่าอื่น:

docker run custom_sleep sleep 20

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

ตอนนี้ให้ลองใช้ENTRYPOINTคำสั่ง:

FROM ubuntu
ENTRYPOINT sleep

คำสั่งนี้ระบุโปรแกรมที่จะทำงานเมื่อภาชนะที่จะเริ่มต้น

ตอนนี้เราสามารถเรียกใช้:

docker run custom_sleep 20

แล้วค่าเริ่มต้นล่ะ คุณเดาได้ถูกต้อง:

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

ENTRYPOINTเป็นโปรแกรมที่จะถูกเรียกใช้และความคุ้มค่าที่ส่งไปยังภาชนะที่จะได้รับการผนวกเข้ากับมัน

ENTRYPOINTสามารถแทนที่โดยระบุ--entrypointธงตามด้วยจุดเริ่มต้นใหม่ที่คุณต้องการใช้

ไม่ใช่ของฉันฉันเคยดูบทช่วยสอนที่ให้ตัวอย่างนี้


1
นี่คือการเชื่อมโยงไปกวดวิชา: youtu.be/OYbEWUbmk90 อาจเป็นประโยชน์กับผู้ใช้ในอนาคต
ChiPlusPlus

16

คำตอบที่ได้รับการยอมรับนั้นยอดเยี่ยมในการอธิบายประวัติ ฉันพบว่าตารางนี้อธิบายได้ดีมากจากdoc อย่างเป็นทางการเกี่ยวกับวิธีการที่ CMD และ ENTRYPOINT โต้ตอบอย่างไร : ป้อนคำอธิบายรูปภาพที่นี่


7

ความคิดเห็นเกี่ยวกับฟังก์ชั่น EntryPoint ในรหัส

// ENTRYPOINT / usr / sbin / nginx

// ตั้งค่าจุดเข้าใช้งาน (ซึ่งค่าเริ่มต้นคือ sh -c) เป็น / usr / sbin / nginx

// จะยอมรับ CMD เป็นอาร์กิวเมนต์ของ / usr / sbin / nginx

การอ้างอิงอื่นจากเอกสาร

คุณสามารถใช้รูปแบบ exec ของ ENTRYPOINT เพื่อตั้งค่าคำสั่งและอาร์กิวเมนต์เริ่มต้นที่ค่อนข้างเสถียรแล้วใช้ CMD เพื่อตั้งค่าเริ่มต้นเพิ่มเติมที่น่าจะมีการเปลี่ยนแปลง

ตัวอย่าง:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

สร้าง : sudo docker build -t ent_cmd

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

.

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

ps: ต่อหน้า EntryPoint, CMD จะเก็บอาร์กิวเมนต์เพื่อป้อนไปยัง EntryPoint ในกรณีที่ไม่มี EntryPoint, CMD จะเป็นคำสั่งที่จะถูกเรียกใช้


3

CMDคำสั่งที่กล่าวถึงในDockerfileไฟล์สามารถเขียนทับผ่านdocker runคำสั่งในขณะที่ENTRYPOINTไม่สามารถ


4
docker run --helpคำสั่งพูดเป็นอย่างอื่น:--entrypoint string Overwrite the default ENTRYPOINT of the image
35432

3

ฉันได้อ่านคำตอบทั้งหมดและต้องการสรุปเพื่อความเข้าใจที่ดีขึ้นในแวบแรกเช่น:

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

  • ENTRYPOINTกำหนดปฏิบัติการที่เรียกเมื่อภาชนะเริ่มต้น (สำหรับคำสั่ง)

  • CMDระบุอาร์กิวเมนต์ที่ส่งผ่านไปยัง ENTRYPOINT (สำหรับอาร์กิวเมนต์)

ในหนังสือKubernetes In Actionมีโน้ตสำคัญเกี่ยวกับมัน (ตอนที่ 7)

แม้ว่าคุณสามารถใช้คำสั่งCMDเพื่อระบุคำสั่งที่คุณต้องการดำเนินการเมื่ออิมเมจรัน แต่วิธีที่ถูกต้องคือทำผ่านคำสั่งENTRYPOINTและเพื่อระบุCMDหากคุณต้องการกำหนดอาร์กิวเมนต์เริ่มต้นเท่านั้น

นอกจากนี้คุณยังสามารถอ่านนี้บทความสำหรับคำอธิบายที่ดีในวิธีที่ง่าย


2

CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"]เป็นกระบวนการแรก
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2เป็นกระบวนการแรก CMD command param1 param2ถูกแยกจากกระบวนการแรก
  • CMD ["param1","param2"]: ENTRYPOINTแบบฟอร์มนี้จะใช้เพื่อให้การขัดแย้งเริ่มต้นสำหรับ

รายการ (รายการต่อไปนี้ไม่ได้พิจารณากรณีที่ใช้ CMD และ ENTRYPOINT ร่วมกัน):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"]เป็นกระบวนการแรก
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2เป็นกระบวนการแรก command param1 param2ถูกแยกจากกระบวนการแรก

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


2

คนส่วนใหญ่อธิบายอย่างสมบูรณ์ที่นี่ดังนั้นฉันจะไม่ตอบซ้ำทั้งหมด แต่เพื่อให้ได้ความรู้สึกที่ดีฉันจะแนะนำให้ทดสอบด้วยตัวเองโดยดูที่กระบวนการในคอนเทนเนอร์

สร้าง Dockerfile เล็ก ๆ ของแบบฟอร์ม:

FROM ubuntu:latest
CMD /bin/bash

สร้างมันเรียกใช้ด้วยdocker run -it theimageและเรียกใช้ps -eo ppid,pid,argsในภาชนะ เปรียบเทียบเอาต์พุตนี้กับเอาต์พุตที่คุณได้รับจาก ps เมื่อใช้:

  • docker run -it theimage bash
  • การสร้างรูปภาพขึ้นใหม่ แต่มีENTRYPOINT /bin/bashและเรียกใช้ในทั้งสองวิธี
  • การใช้ CMD ["/bin/bash"]
  • ...

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


0

เอกสารอย่างเป็นทางการของแนวทางปฏิบัติที่ดีที่สุดของ Dockerfile เป็นงานที่ยอดเยี่ยมในการอธิบายความแตกต่าง แนวทางปฏิบัติที่ดีที่สุดของ Dockerfile

CMD:

ควรใช้คำสั่ง CMD เพื่อเรียกใช้ซอฟต์แวร์ที่มีภาพของคุณพร้อมกับข้อโต้แย้งใด ๆ CMD CMD ["executable", "param1", "param2"…]ควรมักจะถูกนำมาใช้ในรูปแบบของ ดังนั้นหากเป็นภาพที่หาบริการเช่น Apache และ Rails CMD ["apache2","-DFOREGROUND"]คุณจะทำงานบางอย่างเช่น อันที่จริงแล้วคำแนะนำในรูปแบบนี้แนะนำสำหรับรูปภาพที่อ้างอิงกับบริการใด ๆ

จุดเข้าใช้งาน:

การใช้งานที่ดีที่สุดสำหรับ ENTRYPOINT คือการตั้งค่าคำสั่งหลักของอิมเมจทำให้สามารถรันอิมเมจนั้นได้ราวกับว่ามันเป็นคำสั่งนั้น (จากนั้นใช้ CMD เป็นแฟล็กเริ่มต้น)

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