Di Dockerfiles ada dua perintah yang terlihat mirip dengan saya: CMD
dan ENTRYPOINT
. Tapi saya kira ada perbedaan (halus?) Di antara mereka - jika tidak, tidak masuk akal untuk memiliki dua perintah untuk hal yang sama.
Dokumentasi menyatakan untuk CMD
Tujuan utama CMD adalah untuk menyediakan standar untuk wadah pelaksana.
dan untuk ENTRYPOINT
:
ENTRYPOINT membantu Anda mengonfigurasi wadah yang dapat Anda jalankan sebagai yang dapat dieksekusi.
Jadi, apa perbedaan antara kedua perintah itu?
ADD
danCOPY
Jawaban:
Docker memiliki titik masuk default yaitu
/bin/sh -c
tetapi tidak memiliki perintah standar.Ketika Anda menjalankan buruh pelabuhan seperti ini:
docker run -i -t ubuntu bash
titik masuk adalah default/bin/sh -c
, gambar adalahubuntu
dan perintahnya adalahbash
.Perintah dijalankan melalui titik masuk. yaitu, hal aktual yang dieksekusi adalah
/bin/sh -c bash
. Ini memungkinkan Docker untuk menerapkanRUN
dengan cepat dengan mengandalkan parser shell.Kemudian, orang-orang meminta untuk dapat menyesuaikan ini, jadi
ENTRYPOINT
dan--entrypoint
diperkenalkan.Semuanya setelah
ubuntu
dalam contoh di atas adalah perintah dan diteruskan ke titik masuk. Saat menggunakanCMD
instruksi, persis seperti yang Anda lakukandocker run -i -t ubuntu <cmd>
.<cmd>
akan menjadi parameter dari titik masuk.Anda juga akan mendapatkan hasil yang sama jika Anda mengetik perintah ini
docker run -i -t ubuntu
. Anda masih akan memulai bash shell dalam wadah karena Dockerfile ubuntu menentukan CMD default:CMD ["bash"]
Karena semuanya dilewatkan ke titik masuk, Anda dapat memiliki perilaku yang sangat baik dari gambar Anda. @Jiri contohnya bagus, ini menunjukkan cara menggunakan gambar sebagai "biner". Saat menggunakan
["/bin/cat"]
sebagai titik masuk dan kemudian lakukandocker run img /etc/passwd
, Anda mendapatkannya,/etc/passwd
adalah perintah dan diteruskan ke entrypoint sehingga eksekusi hasil akhirnya hanyalah/bin/cat /etc/passwd
.Contoh lain adalah memiliki cli sebagai titik masuk. Misalnya, jika Anda memiliki gambar Redis, bukan berjalan
docker run redisimg redis -H something -u toto get key
, Anda bisa hanya memilikiENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
dan kemudian jalankan seperti ini untuk hasil yang sama:docker run redisimg get key
.sumber
ENTRYPOINT
; apakah shell digunakan tergantung pada bentukCMD
perintah yang digunakan ( docs.docker.com/engine/reference/builder/#cmd ).CMD
vsENTRYPOINT
.The
ENTRYPOINT
menspesifikasikan perintah yang akan selalu dijalankan ketika wadah dimulai.The
CMD
menspesifikasikan argumen yang akan diumpankan keENTRYPOINT
.Jika Anda ingin membuat gambar yang didedikasikan untuk perintah tertentu yang akan Anda gunakan
ENTRYPOINT ["/path/dedicated_command"]
Jika tidak, jika Anda ingin membuat gambar untuk tujuan umum, Anda dapat meninggalkan yang
ENTRYPOINT
tidak ditentukan dan menggunakannyaCMD ["/path/dedicated_command"]
karena Anda akan dapat menimpa pengaturan dengan memberikan argumendocker run
.Misalnya, jika Dockerfile Anda adalah:
Menjalankan gambar tanpa argumen apa pun akan melakukan ping ke localhost:
Sekarang, menjalankan gambar dengan argumen akan mem-ping argumen:
Sebagai perbandingan, jika Dockerfile Anda adalah:
Menjalankan gambar tanpa argumen apa pun akan melakukan ping ke localhost:
Tetapi menjalankan gambar dengan argumen akan menjalankan argumen:
Lihat artikel ini dari Brian DeHamer untuk detail lebih lanjut: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/
sumber
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.
adalah ringkasan to-the-point yang baik.Menurut dok buruh pelabuhan ,
Tabel di bawah ini menunjukkan perintah apa yang dijalankan untuk
ENTRYPOINT
/CMD
kombinasi yang berbeda :-
No ENTRYPOINT
-
ENTRYPOINT exec_entry p1_entry
-
ENTRYPOINT [“exec_entry”, “p1_entry”]
sumber
/bin/sh -c
terlibat?/bin/sh -c
akan ditambahkan ke CMD sebagai awalan sementara CMD ditulis dalam sintaks yang dapat dieksekusi (bukan sintaksis daftar).ENTRYPOINT exec_entry p1_ent
salah dijelaskan. Formulir shell mencegah CMD atau menjalankan argumen baris perintah agar tidak digunakan - docs.docker.com/engine/reference/builder/#entrypointYa, itu pertanyaan yang bagus. Saya belum memahaminya sepenuhnya, tetapi:
Saya mengerti bahwa itu
ENTRYPOINT
adalah biner yang dieksekusi. Anda dapat mengesampingkan entrypoint dengan --entrypoint = "".CMD adalah argumen default untuk penampung. Tanpa titik masuk, argumen default adalah perintah yang dieksekusi. Dengan entrypoint, cmd dilewatkan ke entrypoint sebagai argumen. Anda dapat meniru suatu perintah dengan titik masuk.
Jadi, keuntungan utama adalah bahwa dengan entrypoint Anda dapat meneruskan argumen (cmd) ke wadah Anda. Untuk mencapai ini, Anda perlu menggunakan keduanya:
dan
maka Anda dapat menggunakan:
sumber
docker run image_name -h
untuk menunjukkan beberapa informasi bantuan dari gambar ini.Perbedaan antara CMD dan ENTRYPOINT berdasarkan intuisi :
Ya, ini bercampur.
Anda dapat mengesampingkan salah satu dari mereka saat menjalankan buruh pelabuhan.
Perbedaan antara CMD dan ENTRYPOINT dengan contoh :
Lebih lanjut tentang perbedaan antara
CMD
danENTRYPOINT
:Argumen untuk
docker run
seperti / bin / bash menimpa semua perintah CMD yang kami tulis di Dockerfile.ENTRYPOINT tidak dapat diganti pada saat dijalankan dengan perintah normal seperti
docker run [args]
. Diargs
akhirdocker run [args]
disediakan sebagai argumen untuk ENTRYPOINT. Dengan cara ini kita dapat membuatcontainer
yang seperti biner normal sepertils
.Jadi CMD dapat bertindak sebagai parameter default untuk ENTRYPOINT dan kemudian kita dapat mengganti argumen CMD dari [args].
ENTRYPOINT dapat diganti dengan
--entrypoint
.sumber
Pendeknya:
Jika Anda memerlukan detail lebih lanjut atau ingin melihat perbedaan pada contoh, ada posting blog yang secara komprehensif membandingkan CMD dan ENTRYPOINT dengan banyak contoh - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/
sumber
Saya akan menambahkan jawaban saya sebagai contoh 1 yang mungkin membantu Anda lebih memahami perbedaannya.
Misalkan kita ingin membuat gambar yang akan selalu menjalankan perintah tidur ketika dimulai. Kami akan membuat gambar kami sendiri dan menentukan perintah baru:
Sekarang, kami membangun gambar:
Bagaimana jika kita ingin mengubah jumlah detik? Kita harus mengubah
Dockerfile
karena nilainya hardcode di sana, atau menimpa perintah dengan memberikan yang berbeda:Meskipun ini berfungsi, ini bukan solusi yang baik, karena kami memiliki perintah "tidur" yang berlebihan (tujuan penampung adalah untuk tidur , jadi harus secara eksplisit menentukan
sleep
perintah itu bukan praktik yang baik).Sekarang mari kita coba menggunakan
ENTRYPOINT
instruksi:Instruksi ini menentukan program yang akan dijalankan ketika wadah mulai .
Sekarang kita dapat menjalankan:
Bagaimana dengan nilai default? Yah, Anda menebaknya dengan benar:
Ini
ENTRYPOINT
adalah program yang akan dijalankan, dan nilai yang diteruskan ke wadah akan ditambahkan padanya.The
ENTRYPOINT
dapat ditimpa dengan menentukan--entrypoint
bendera, diikuti oleh titik entri baru yang ingin Anda gunakan.Bukan milik saya, saya pernah menonton tutorial yang memberikan contoh ini
sumber
Jawaban yang diterima luar biasa dalam menjelaskan sejarah. Saya menemukan tabel ini menjelaskannya dengan sangat baik dari dokumen resmi tentang 'bagaimana CMD dan ENTRYPOINT berinteraksi' :
sumber
Komentar pada fungsi EntryPoint dalam kode
Referensi lain dari dokumen
Contoh:
Build : sudo docker build -t ent_cmd.
.
ps: Di hadapan EntryPoint, CMD akan mengadakan argumen untuk diumpankan ke EntryPoint. Tidak adanya EntryPoint, CMD akan menjadi perintah yang akan dijalankan.
sumber
CMD
perintah yang disebutkan di dalamDockerfile
file dapat ditimpa melaluidocker run
perintah sementaraENTRYPOINT
tidak bisa.sumber
docker run --help
perintah mengatakan sebaliknya:--entrypoint string Overwrite the default ENTRYPOINT of the image
Saya telah membaca semua jawaban dan saya ingin meringkas untuk pemahaman yang lebih baik pada pandangan pertama seperti berikut:
Pertama, seluruh perintah yang dieksekusi dalam wadah mencakup dua bagian: perintah dan argumen
Dalam buku Kubernetes In Action menunjukkan catatan penting tentang itu. (bab 7)
Anda juga dapat membaca artikel ini untuk penjelasan yang bagus dengan cara yang sederhana
sumber
CMD:
CMD ["executable","param1","param2"]
:["executable","param1","param2"]
adalah proses pertama.CMD command param1 param2
:/bin/sh -c CMD command param1 param2
adalah proses pertama.CMD command param1 param2
bercabang dari proses pertama.CMD ["param1","param2"]
: Formulir ini digunakan untuk memberikan argumen default untukENTRYPOINT
.ENTRYPOINT (Daftar berikut ini tidak mempertimbangkan kasus di mana CMD dan ENTRYPOINT digunakan bersama-sama):
ENTRYPOINT ["executable", "param1", "param2"]
:["executable", "param1", "param2"]
adalah proses pertama.ENTRYPOINT command param1 param2
:/bin/sh -c command param1 param2
adalah proses pertama.command param1 param2
bercabang dari proses pertama.Seperti yang dikatakan creack , CMD dikembangkan terlebih dahulu. Kemudian ENTRYPOINT dikembangkan untuk penyesuaian lebih lanjut. Karena mereka tidak dirancang bersama, ada beberapa fungsi yang tumpang tindih antara CMD dan ENTRYPOINT, yang sering membingungkan orang.
sumber
Kebanyakan orang menjelaskannya dengan sempurna di sini, jadi saya tidak akan mengulangi semua jawaban. Tetapi untuk mendapatkan perasaan yang baik, saya akan menyarankan mengujinya sendiri dengan melihat proses dalam wadah.
Buat Dockerfile kecil dari formulir:
Bangun, jalankan dengan
docker run -it theimage
dan jalankanps -eo ppid,pid,args
dalam wadah. Bandingkan output ini dengan output yang Anda terima dari ps saat menggunakan:docker run -it theimage bash
ENTRYPOINT /bin/bash
dan menjalankannya dengan dua caraCMD ["/bin/bash"]
Dengan cara ini Anda akan dengan mudah melihat perbedaan antara semua metode yang mungkin untuk diri Anda sendiri.
sumber
Dokumentasi resmi praktik terbaik Dockerfile sangat membantu menjelaskan perbedaan. Dockerfile praktik terbaik
CMD:
Instruksi CMD harus digunakan untuk menjalankan perangkat lunak yang terkandung oleh gambar Anda, bersama dengan argumen apa pun. CMD harus hampir selalu digunakan dalam bentuk
CMD ["executable", "param1", "param2"…]
. Jadi, jika gambar tersebut untuk layanan, seperti Apache dan Rails, Anda akan menjalankan sesuatu sepertiCMD ["apache2","-DFOREGROUND"]
. Memang, bentuk instruksi ini direkomendasikan untuk gambar berbasis layanan apa pun.TITIK MASUK:
Penggunaan terbaik untuk ENTRYPOINT adalah mengatur perintah utama gambar, yang memungkinkan gambar itu dijalankan seolah-olah itu perintah itu (dan kemudian menggunakan CMD sebagai flag default).
sumber