DOCKERFILE的CMD指令和ENTRYPOINT指令
DOCKERFILE的CMD指令和ENTRYPOINT指令
本關的任務是學習CMD指令和ENTRYPOINT指令,要求學習者參照示例, 使用Dockerfile構建一個名為mydisk:v1的映象,Dockerfile的內容為:以busybox:latest為基礎映象,在預設情況下,將啟動命令設定為df -Th。 其中df命令用來檢視磁碟的資訊。要求df命令不能被覆蓋,但-Th能夠被覆蓋。
這一關我們繼續介紹Dockerfile的指令,本關將介紹CMD和ENTRYPOINT。
CMD 指定預設的容器主程式啟動命令
格式:CMD <command>(shell格式)
或 CMD ["executable","param1","param2"](exec格式,推薦格式)
或 CMD["param1","param2"](為ENTRYPOINT指令提供引數)
CMD指令提供容器啟動是執行的預設命令,例如ubuntu映象預設的CMD是/bin/bash,因此我們可以直接使用 docker run -it ubuntu進入bash。
同時也可以使用docker run -it ubuntu cat /etc/os-release,執行該命令後會輸出系統版本資訊。因為當在執行docker run命令時,如果顯示地指定了容器的啟動命令,那麼會將Dockerfile中CMD設定的預設啟動命令覆蓋,也就是說:cat /etc/os-release命令會替代成為容器的啟動命令,所以輸出了系統版本資訊。
在指令格式上,一般推薦使用exec格式,因為使用 shell格式時,實際的命令會被包裝為 sh -c的引數的形式進行執行。比如:CMD echo $HOME,在實際執行中,會將其變更為:CMD [ "sh", "-c", "echo $HOME" ]。
ENTRYPOINT 指定預設的容器主程式啟動命令
注意命令和中括號之間有空格。
格式:ENTRYPOINT <command>(shell格式)
或ENTRYPOINT ["executable","param1","param2"](exec格式,推薦格式)
ENTRYPOINT和CMD一樣,都可以指定容器預設的啟動命令,但是它又和CMD有所不同。上面我們說過,使用者在執行docker run命令建立並啟動容器時,如果指定了啟動命令,那麼"該啟動命令"會覆蓋CMD指令設定的預設啟動命令,但是ENTRYPOINT設定的啟動命令該不能被覆蓋。
細心的同學可能發現了CMD命令可以為ENTRYPOINT指令提供引數。實際上,如果使用Dockerfile構建映象時,既使用了ENTRYPOINT指令,又指定了CMD指令,那麼CMD 指令的含義就發生了改變,CMD 的內容將作為引數傳給 ENTRYPOINT指令,換句話說實際執行時,變成了<ENTRYPOINT> <CMD>。同時,如果執行docker run基於該映象建立並啟動容器,並設定了啟動命令時,docker run設定的"啟動命令"依然會覆蓋CMD的內容,但也僅僅是作為ENTRYPOINT指令的引數。
假設需要一個得知使用者當前公網IP的映象,可以使用下面的Dockerfile構建一個映象。
- FROM centos
- RUN yum install curl
- CMD ["curl","-s","http://ip.cn"]
執行docker build -t myip .來構建一個名為myip的映象,映象構建完成後,如果想要查詢當前公網的IP,執行docker run myip,如下所示:
- [root@localhost tempdir]# docker run myip
- 當前 IP:113.247.230.194 來自:湖南省長沙市 電信
嗯,這麼看起來好像可以直接把映象當做命令使用了,不過命令總有引數,如果我們希望加引數呢?比如從上面的 CMD 中可以看到實質的命令是curl ,那麼如果我們希望顯示HTTP頭資訊,就需要加上-i引數。那麼我們可以直接加 -i引數給 docker run myip麼?
- [root@localhost tempdir]# docker run myip -i
- container_linux.go:247: starting container process caused "exec: \"-i\": executable file not found in $PATH"
- docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"-i\": executable file not found in $PATH".
我們可以看到執行明後後輸出了 executable file not found的錯誤資訊,也就是"可執行檔案找不到"。之前我們說過,跟在映象名後面的是 command ,執行時會替換 CMD的預設值。因此這裡的-i替換了原來的CMD,而不是新增在原來的 curl -s http://ip.cn 後面。而 -i 根本不是命令,所以自然找不到。
那麼如果我們希望加入 -i 這引數,我們就必須重新完整的輸入這個命令:docker run myip curl -s http://ip.cn –i。這顯然不是很好的解決方案,而使用 ENTRYPOINT 就可以解決這個問題。現在改寫Dockerfile,使用ENTRYPOINT設定啟動命令:
- FROM centos
- RUN yum install curl
- ENTRYPOINT ["curl","-s","http://ip.cn"]
這次我們再來嘗試直接使用 docker run myip以及 docker run myip -i:可以看到,這次成功了。這是因為當存在 ENTRYPOINT 後,docker run命令ENTRYPOINT不會被覆蓋。它會作為引數傳給ENTRYPOINT,從而達到了我們預期的結果。
- [root@localhost tempdir]# docker run myip
- 當前 IP:113.247.230.194 來自:湖南省長沙市 電信
- [root@localhost tempdir]# docker run myip -i
- HTTP/1.1 200 OK
- Server: nginx/1.11.9
- Date: Wed, 09 Aug 2017 08:32:24 GMT
- Content-Type: text/html; charset=UTF-8
- Transfer-Encoding: chunked
- Connection: keep-alive
- 當前 IP:113.247.230.194 來自:湖南省長沙市 電信
本關的程式設計任務是補全step3/dockerfile3.sh檔案中的內容,要求使用Dockerfile構建一個名為mydisk:v1的映象,具體要求如下:
- 補全Dockerfile的內容,該Dockerfile的內容如下:
- 以busybox:latest為基礎映象
- 預設情況下,將啟動命令設定為df -Th。要求df命令不能被覆蓋,但-Th能夠被覆蓋。(df命令用來檢視磁碟的資訊)
- 使用docker build基於該Dockerfile構建一個名為mydisk:v1的映象。
- 注意命令後面要有空格。CMD之後有空格。ENTRYPOINT也是要有空格。
示例1
#建立一個空資料夾,並進入其中
mkdir newdir3
cd newdir3
#建立一個Dockerfile檔案
touch Dockerfile
#假設我的Dockerfile檔案為
#FROM ubuntu
#RUN mkdir dir1
#可以這麼寫:
# echo 'FROM ubuntu' > Dockerfile
# echo 'RUN mkdir dir1'>> Dockerfile
#輸入Dockerfile檔案內容
#********** Begin *********#
#以busybox為基礎映象
echo 'FROM busybox' > Dockerfile
#預設情況下,將啟動命令設定為df -Th。要求df命令不能被覆蓋,但-Th能夠被覆蓋。
echo 'CMD ["-T","-h"]'>> Dockerfile
echo 'ENTRYPOINT ["df","-Th"]'>> Dockerfile
#********** End **********#
#檔案內容完畢,在當前資料夾中執行
#********** Begin *********#
#以該Dockerfile構建一個名為mydisk:latest的映象
docker build -t mydisk:latest .
#********** End **********#
示例2
[root@dockerdevops newdir3]# more Dockerfile
FROM centos
ENTRYPOINT ["df","-Th"]
root@dockerdevops newdir3]# docker build -t mydisk:latest .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos
---> d123f4e55e12
Step 2/2 : ENTRYPOINT df -Th
---> Running in eb80aa1318ad
---> 5c74a196f882
Removing intermediate container eb80aa1318ad
Successfully built 5c74a196f882
Successfully tagged mydisk:latest
[root@dockerdevops newdir3]# docker run mydisk:latest
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 50G 9.1G 41G 19% /
tmpfs tmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/cl-root xfs 50G 9.1G 41G 19% /etc/hosts
shm tmpfs 64M 0 64M 0% /dev/shm
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/firmware
相關文章
- 『現學現忘』Docker基礎 — 36、CMD指令和ENTRYPOINT指令的區別Docker
- Dockerfile 中 RUN, CMD, ENTRYPOINT 的區別Docker
- dockerfile中ENTRYPOINT與CMD的結合Docker
- Dockerfile之CMD與ENTRYPOINT使用要點Docker
- CMD和ENTRYPOINT命令
- [轉帖]Dockerfile中CMD與ENTRYPOINT命令的區別Docker
- docker筆記15-Dockerfile案例-CMD、ENTRYPOINT案例Docker筆記
- Docker的Dockerfile指令Docker
- Dockerfile常用指令Docker
- Dockerfile指令詳解Docker
- Dockerfile中指令詳解Docker
- Dockerfile---指令碼自動化Docker指令碼
- 解讀三組容易混淆的Dockerfile指令Docker
- 映象的製作CMD與ENTRYPOINT區別
- Docker - 02 建立映象 Dockerfile 指令速查表Docker
- CMD 執行大檔案SQL指令碼SQL指令碼
- 017、RUN、CMD、ENTRYPOINT (2019-01-08 週二)
- 08 指令和程式
- Linux雲端計算教程全套影片合集:CMD指令講解Linux
- Django的下載和基本指令Django
- Dockerfile指令與Docker-compose容器編排-搭建docker私有倉庫Docker
- 『現學現忘』Docker基礎 — 38、COPY指令和ADD指令Docker
- 5.call和ret指令
- 史丹佛新作:無指令調優的指令遵循
- 指令
- 【軟體硬體】精簡指令集和複雜指令集的區別
- 操作符offset 和 jmp指令
- 常用的方便指令
- lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)
- nginx的gzip指令介紹,Nginx的gzip指令使用小結Nginx
- 硬體對同步的支援-TAS和CAS指令
- awk命令和指令碼的編寫啟蒙指令碼
- Linux 中 awk指令 sub和substr的區別Linux
- 基座模型、聊天模型和指令模型的區別模型
- shell的引數和指令碼流程改進指令碼
- Redis篇:事務和lua指令碼的使用Redis指令碼
- SCSS @for 指令CSS
- SCSS @if() 指令CSS
- MOV指令