【Docker 系列】docker 學習七,DockerFile 編寫和實戰
我們開始來一起學習 DockerFile 的知識點
DcokerFile 是用來構建 docker 映象的檔案,是一個命令引數指令碼
一般 docker 映象的構建步驟:
1、編寫一個 dockerfile 檔案
2、docker build 構建成為一個映象
3、docker run 執行映象
4、docker push 釋出映象(咱們可以釋出到 DockerHub,也可以釋出到阿里雲上面)
我們來看看官方的映象是咋玩的
例如我們在 DockerHub 上搜索 ubuntu ,看看官網的 DockerFile 是啥樣子的
https://hub.docker.com/_/ubuntu
點選連結我們會進入到 git 倉庫上,也是 DockerFile
咱們看到就 3 行 Docker 命令,是官方做成映象的 DockerFile,所以這個官方的 ubuntu 映象是非常簡單的,閹割版本的,甚至連 clear
命令都沒有,ll
命令也沒有
很多的官方映象包都是非常簡單的,很多功能都是沒有的,我們通常會自己搭建自己的映象來滿足我們的各種需求
DockerFile 的構建過程
官方能構建映象,我們也可以自己的映象
DockerFile 的基礎知識:
- 每個 DockerFile 的保留字(指令),都必須是大寫的
- DockerFile 指令碼執行是按照順序執行的
#
表示註釋- 每一個指令都會建立提交一個新的映象層,並提交
可以在網路上找到這樣的圖片,可以看到映象是一層一層的,可以在瀏覽器上搜索到 DockerFile 裡面的指令解釋
dockerfile 是面向開發的,我們以後在做專案的時候,是直接釋出一個映象,交付的是一個映象,就需要編寫 DockerFile 檔案,這個檔案非常的簡單!
咱們必須要掌握 Docker 映象,逐漸成為企業交付的標準了。
咱們學習的過程是先會使用別人的東西,再去研究別人是怎麼寫的,進而我們也學會如何去寫,去開發
例如:
我們先學習使用了,
DockerImages:通過 DockerFile 構建生產的映象,最終釋出和執行的產品
Docker 容器:容器服務就是映象執行起來的伺服器
現在我們開始詳細學習 DockerFIle : 構建檔案,定義了一切的步驟,這是原始碼
DockerFile 的指令
圖片來源於網路,我們一一解釋一波
- FROM
基礎的映象,一切都是從這裡開始的
- MAINTAINER
指明映象是誰寫的,寫下自己的姓名和郵箱
- RUN
映象構建的時候需要執行的命令
- ADD
加入某些配置,例如加入 mysql 的壓縮包,新增內容
- WORKDIR
映象的工作目錄
- VOLUME
掛載目錄
- EXPOSE
暴露埠 和 -p
是一個效果
- CMD
指定這個容器啟動的時候執行的命令,只會是最優一個指令進行生效,會被替代
- ENTRYPOINT
指定這個容器啟動的時候執行的命令,可以追加
- ONBUILD
當構建一個被繼承的 DockerFIle ,這個時候就會執行 ONBUILD 的指令,觸發相應的動作
- COPY
與 ADD 類似,此命令是將檔案拷貝到映象中
- ENV
構建的時候設定環境變數
乍一看感覺 CMD
和 ENTRYPOINT
功能好像差不多,但是還是不太清楚具體區別在哪裡,文章末尾會有詳細說明
實戰
我們自己來做一個自定一個 ubuntu
映象
官方的ubuntu
是閹割版本的,很多工具和命令都是不支援的,那麼我們就自己加進去,自給自足
自己寫一個 DockerFile
這裡需要注意的是,基本上 99%
的映象,都是基於這個基礎映象 scratch
,我們可以看到官方的 DockerFIle 也是基於這個映象來玩的
那麼我們可以基於這個 ubuntu 來進行自定義,加入一些我們需要的工具,如vim
,ifconfig
等
FROM ubuntu
RUN apt-get update # 更新源
RUN apt-get install -y vim # 安裝 vim
RUN apt-get install -y net-tools # 安裝 net-tools
ENV MYPATH /usr/local # 設定環境變數
WORKDIR $MYPATH # 設定映象工作目錄
EXPOSE 8888 # 暴露埠
CMD echo "----- end -----" # 執行 echo 命令
CMD /bin/bash
開始構建
docker build -f dockerfile2 -t xmtubuntu .
如果不在 DockerFile 中寫入 apt-get update
更新源,會出現下面這個問題,這個要注意
執行上述命令,會看到如下列印資訊,最終會看到Successfully
,即為構建成功
通過上圖我們可以看出, DokerFile 中寫了 9 個步驟,執行的時候也是分了 9 步,知道全部成功才算成功
最終構建成功後我們可以看到
Successfully built a6f88c9f245b
Successfully tagged xmtubuntu:latest
驗證結果
docker images 檢視我們的映象
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xmtubuntu latest a6f88c9f245b 13 minutes ago 172MB
docker inspect a6f88c9f245b 檢視我們映象的構建過程
# docker history a6f88c9f245b
IMAGE CREATED CREATED BY SIZE COMMENT
a6f88c9f245b 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
3c0d23b8188f 14 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
ffb019142fc7 14 minutes ago /bin/sh -c #(nop) EXPOSE 8888 0B
8867e6d97670 14 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
c9d0141ec3b0 14 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
41e73f7e314d 14 minutes ago /bin/sh -c apt-get install -y net-tools 1.52MB
52013ca51f1d 14 minutes ago /bin/sh -c apt-get install -y vim 68.2MB
5ea7d553d403 14 minutes ago /bin/sh -c apt-get update 29.7MB
1318b700e415 11 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 11 days ago /bin/sh -c #(nop) ADD file:524e8d93ad65f08a0… 72.8MB
xmtubuntu 這個映象的構建過程我們可以清晰的看出都執行了哪些步驟,當然,同樣的方式,我們也可以看看官方的映象是如何構建的,我們來看看官方 ubuntu 的
# docker history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
1318b700e415 11 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 11 days ago /bin/sh -c #(nop) ADD file:524e8d93ad65f08a0… 72.8MB
官方的就很簡單,閹割了很多東西,我們可以看出官方的 ubuntu 就 2 個步驟,第一個是加入ubuntu
壓縮包,第二個就是 /bin/bash
我們檢視我們的自定義映象 xmtubuntu
果然,我們的自定義ubuntu映象,有了vim
,ifconfig
工具,實戰成功
CMD 和 ENTRYPOINT 的區別
- CMD
指定這個容器啟動的時候執行的命令,只會是最優一個指令進行生效,會被替代
- ENTRYPOINT
指定這個容器啟動的時候執行的命令,可以追加
如何理解呢?我們來做一個對比試驗就可以很好的理解上述的解釋說明,docker 裡面有很多命令會有這樣的微小區別,我們可以舉一反三,慢慢深入學習
CMD 的例子
寫一個簡單的 DockerFile 檔名為 dockerfile-cmd
FROM xmtubuntu
CMD ["ls","-a"]
構建映象
e# docker build -f dockerfile-cmd -t dockerfile-cmd .
Sending build context to Docker daemon 1.346GB
Step 1/2 : FROM xmtubuntu
---> a6f88c9f245b
Step 2/2 : CMD ["ls","-a"]
---> Running in 101670af4290
Removing intermediate container 101670af4290
---> 1697fc03b8ce
Successfully built 1697fc03b8ce
Successfully tagged dockerfile-cmd:latest
建立並啟動容器
docker run 101670af4290
,可以看到如下效果
我們嘗試在啟動容器時候追加命令
docker run 101670af4290 -l
,就會有如下報錯
# docker run 1697fc03b8ce -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
原因如下:
使用 CMD
指令是(例如我們的例子是 ls -a
),我們在啟動容器的時候,後面追加的命令(-l
)會把 ls -a
替換掉,由於-l
不是一個命令,因此報錯
ENTRYPOINT 的例子
寫一個簡單的 DockerFile 檔名為 dockerfile-entrypoint
FROM xmtubuntu
ENTRYPOINT ["ls","-a"]
構建映象,建立並啟動容器和 CMD
的例子一模一樣,咱們直接啟動容器的效果和 CMD
的例子也是一模一樣,我們直接來看啟動容器並追加引數的例子
可以看出使用 ENTRYPOINT
是可以在後面追加引數的,使用CMD
若指令後面追加引數,那麼會覆蓋CMD
指定的指令
那麼,對於以後遇到相關的指令,我們也可以舉一反三,做對比試驗,這樣我們就會理解的更加清楚
如何釋出我們的映象
1、登入 dockerhub
沒有註冊的 xdm 可以註冊一個,https://hub.docker.com/
# docker login -u xxxx使用者名稱
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
2、修改我們的映象 tag
docker tag 我們的映象id 我們的docker使用者名稱/映象名字:版本
3、將映象推到我們自己的倉庫中
釋出映象的時候,也是按照一層一層的提交的
最後補充一個網路上找到的圖片,現在看這張圖就能更清晰的明白其中的原理了
參考資料:
歡迎點贊,關注,收藏
朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力
好了,本次就到這裡
技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是小魔童哪吒,歡迎點贊關注收藏,下次見~