CMD指令和ENTRYPOINT指令都是指定一個容器啟動時要運行的命令往产。
1搀捷、CMD指令和ENTRYPOINT指令說明
CMD指令戳杀, 支持三種格式:
CMD ["executable","param1","param2"] 使用 exec 執(zhí)行宁否,推薦方式晌杰;
CMD command param1 param2 在 /bin/sh 中執(zhí)行桂敛,提供給需要交互的應(yīng)用功炮;
CMD ["param1","param2"] 提供給 ENTRYPOINT 的默認參數(shù);
每個Dockerfile只能生效一條CMD指令术唬。如果指定了多條CMD指令薪伏,只有最后一條生效。
如果用戶啟動容器時候指定了運行的命令碴开,則會覆蓋掉CMD指定的命令毅该。
ENTRYPOINT指令,支持兩種格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中執(zhí)行)潦牛。
每個Dockerfile中只能生效一個ENTRYPOINT指令眶掌,當有多個ENTRYPOINT指令時,只有最后一個起效巴碗。
如果用戶啟動容器時候指定了運行的命令朴爬,不會被docker run
執(zhí)行的命令參數(shù)覆蓋。(追加效果:docker run
命令之后的參數(shù)橡淆,會被當做參數(shù)傳遞給ENTRYPOINT召噩,之后形成新的命令組合)
2、CMD指令只有最后一條生效的原因
CMD指令是一個容器的默認的可執(zhí)行命令逸爵。也就是容器啟動以后具滴,默認執(zhí)行的命令。(默認是重點)
換句話說师倔,給出了CMD指令的一個角色定位构韵,它主要作用是定義默認的容器啟動后執(zhí)行的命令。
提示:
這也就是網(wǎng)上所說,只有最后一條CMD指令會生效疲恢,之前的都會被覆蓋掉凶朗。
就是因為CMD指令的角色定位就是默認,如果你不進行額外指定显拳,那么就執(zhí)行CMD指令棚愤。否則,你要自己指定了命令杂数,那么就不會執(zhí)行CMD指令宛畦,這也就是相當于CMD指令會被覆蓋。
而ENTRYPOINT指令耍休,才是正統(tǒng)地用于定義容器啟動以后的執(zhí)行體刃永,從名字上我們也可以看出,entrypoint
入口點的意思羊精,一個容器的“入口”斯够。
3、CMD指令演示
我們以contos鏡像為基礎(chǔ)喧锦,對該鏡像進行修改读规。
(1)準備測試環(huán)境
進入宿主機/home/mydockerfile
目錄中,創(chuàng)建Dockerfil文件Dockerfile_cmd
燃少。
# mydockerfile目錄中創(chuàng)建Dockerfile_cmd文件
[root@192 mydockerfile]# pwd
/home/mydockerfile
[root@192 mydockerfile]# touch Dockerfile_cmd
編輯Dockerfile_cmd文件束亏,內(nèi)容如下:
FROM centos # 繼承了本地的centos鏡像
CMD ["ls","-a"] # 執(zhí)行l(wèi)s -a 命令
說明:我們之前CMD執(zhí)行都是/bin/bash
,這回改成ls -a
命令是一樣的阵具,就是啟動容器后執(zhí)行ls -a
命令碍遍。
根據(jù)Dockerfile_cmd生成cmd鏡像。
[root@192 mydockerfile]# docker build -f /home/mydockerfile/Dockerfile_cmd -t wukong/cmd:1.0 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
---> Running in e34a0fc14329
Removing intermediate container e34a0fc14329
---> de211d4ca7f3
Successfully built de211d4ca7f3
Successfully tagged wukong/cmd:1.0
(2)進行驗證
運行wukong/cmd鏡像阳液,查看結(jié)果怕敬。
# 查看本地Docker鏡像
[root@192 mydockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wukong/cmd 1.0 de211d4ca7f3 2 minutes ago 209MB
wokong_centos 1.6 6441f63090d4 3 hours ago 291MB
centos latest 300e315adb2f 3 months ago 209MB
# 直接運行該容器,查看結(jié)果帘皿,輸出了默認工作目錄中的內(nèi)容东跪。
[root@192 mydockerfile]# docker run wukong/cmd:1.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 容器啟動,執(zhí)行完ls -a 命令后鹰溜,就會停止虽填。
[root@192 mydockerfile]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
接下來,我們在docker run
命令后曹动,加入-l
命令斋日,我們再來查看一下結(jié)果。
[root@192 mydockerfile]# docker run wukong/cmd:1.0 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
說明:
我的意思是想追加一個-l
參數(shù)墓陈,讓容器啟動后桑驱,執(zhí)行ls -al
命令竭恬。結(jié)果我們看到是跛蛋,可執(zhí)行文件找不到的報錯熬的,exec: "-l":executable file not found
。
這就是我們之前說過的赊级,跟在鏡像名后面的是command(命令)押框,運行時會替換CMD的默認值。也就是-l
參數(shù)替換了Dockerfile文件中的CMD ["ls","-a"]
命令理逊,而不是添加在原來的命令里橡伞。
而單獨的-l
參數(shù)不是Linux命令,不能單獨的命令晋被,自然找不到兑徘,所以就報錯了。
所以綜上所述羡洛,CMD指令會被docker run
之后的參數(shù)替換挂脑。
那么如果我們希望加入-i
這個參數(shù),就必須重新完整的輸入整個命令欲侮,如下:
[root@192 mydockerfile]# docker run wukong/cmd:1.0 ls -al
total 0
drwxr-xr-x. 1 root root 6 Mar 20 11:13 .
drwxr-xr-x. 1 root root 6 Mar 20 11:13 ..
-rwxr-xr-x. 1 root root 0 Mar 20 11:13 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Mar 20 11:13 dev
drwxr-xr-x. 1 root root 66 Mar 20 11:13 etc
drwxr-xr-x. 2 root root 6 Nov 3 15:22 home
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------. 2 root root 6 Dec 4 17:37 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 15:22 media
drwxr-xr-x. 2 root root 6 Nov 3 15:22 mnt
drwxr-xr-x. 2 root root 6 Nov 3 15:22 opt
dr-xr-xr-x. 122 root root 0 Mar 20 11:13 proc
dr-xr-x---. 2 root root 162 Dec 4 17:37 root
drwxr-xr-x. 11 root root 163 Dec 4 17:37 run
lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv
dr-xr-xr-x. 13 root root 0 Mar 20 06:42 sys
drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp
drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr
drwxr-xr-x. 20 root root 262 Dec 4 17:37 var
4崭闲、ENTRYPOINT指令演示
通過上面CMD指令演示相似。
我們以contos鏡像為基礎(chǔ)威蕉,對該鏡像進行修改刁俭。
(1)準備測試環(huán)境
進入宿主機/home/mydockerfile
目錄中,創(chuàng)建Dockerfil文件Dockerfile_entrypoint
韧涨。
# mydockerfile目錄中創(chuàng)建Dockerfile_entrypoint文件
[root@192 mydockerfile]# pwd
/home/mydockerfile
[root@192 mydockerfile]# touch Dockerfile_entrypoint
編輯Dockerfile_entrypoint文件牍戚,內(nèi)容如下:
FROM centos # 繼承了本地的centos鏡像
ENTRYPOINT ["ls","-a"] # 執(zhí)行l(wèi)s -a 命令
根據(jù)Dockerfile_entrypoint生成entrypoint鏡像。
[root@192 mydockerfile]# docker build -f /home/mydockerfile/Dockerfile_entrypoint -t wukong/entrypoint:1.0 .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in ecd4a636d8be
Removing intermediate container ecd4a636d8be
---> e641401b4ea5
Successfully built e641401b4ea5
Successfully tagged wukong/entrypoint:1.0
(2)進行驗證
運行wukong/entrypoint鏡像虑粥,查看結(jié)果如孝。
# 查看本地Docker鏡像
[root@192 mydockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wukong/entrypoint 1.0 e641401b4ea5 2 minutes ago 209MB
wukong/cmd 1.0 adda4543a402 3 minutes ago 209MB
wokong_centos 1.6 6441f63090d4 4 hours ago 291MB
centos latest 300e315adb2f 3 months ago 209MB
# 直接運行該容器,查看結(jié)果舀奶,輸出了默認工作目錄中的內(nèi)容暑竟。
[root@192 mydockerfile]# docker run wukong/entrypoint:1.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
接下來,我們在docker run
命令后育勺,加入-l
命令但荤,我們再來查看一下結(jié)果。
[root@192 mydockerfile]# docker run wukong/entrypoint:1.0 -l
total 0
drwxr-xr-x. 1 root root 6 Mar 20 12:03 .
drwxr-xr-x. 1 root root 6 Mar 20 12:03 ..
-rwxr-xr-x. 1 root root 0 Mar 20 12:03 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Mar 20 12:03 dev
drwxr-xr-x. 1 root root 66 Mar 20 12:03 etc
drwxr-xr-x. 2 root root 6 Nov 3 15:22 home
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------. 2 root root 6 Dec 4 17:37 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 15:22 media
drwxr-xr-x. 2 root root 6 Nov 3 15:22 mnt
drwxr-xr-x. 2 root root 6 Nov 3 15:22 opt
dr-xr-xr-x. 124 root root 0 Mar 20 12:03 proc
dr-xr-x---. 2 root root 162 Dec 4 17:37 root
drwxr-xr-x. 11 root root 163 Dec 4 17:37 run
lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv
dr-xr-xr-x. 13 root root 0 Mar 20 06:42 sys
drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp
drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr
drwxr-xr-x. 20 root root 262 Dec 4 17:37 var
說明:想給Dockerfile文件中的ENTRYPOINT ["ls","-a"]
命令追加一個-l
參數(shù)涧至,讓容器啟動后執(zhí)行ls -al
命令腹躁,結(jié)果順利執(zhí)行。
結(jié)論:這就說明了南蓬,ENTRYPOINT指令是可以在容器啟動的時候追加命令纺非。
Dockerfile中很多命令的功能都十分的相似哑了,我們需要了解它們的區(qū)別,我們最好的學(xué)習(xí)就是對比他們烧颖,然后測試效果弱左。
以上就是CMD指令和ENTRYPOINT指令的區(qū)別。