dockerfile

一、 根據 Dockerfile 構建出一個容器

1FROM(指定基礎 image

該指令有兩種格式:

FROM <image>   制定images號也可以

指定基礎 image 爲該 image 的最後修改的版本。

或者:

FROM <image>:<tag>

2MAINTAINER(用來指定鏡像創建者信息)

構建指令,用於將 image 的製作者相關的信息寫入到 image 中。當我們對該 image 執行 docker inspect 命令時,輸出中有相應的字段記錄該信息。

格式:

MAINTAINER <name>

3RUN(安裝軟件用)

構建指令, RUN 可以運行任何被基礎 image 支持的命令。如基礎 image 選擇了 ubuntu,那麼軟件管理部分只能使用 ubuntu 的命令。

該指令有兩種格式:

RUN <command> (the command is run in a shell - `/bin/sh -c`)

RUN ["executable", "param1", "param2" ... ] (exec form)

舉例:RUN ["touch","a.txt"]

前者將在 shell 終端中運行命令,即 /bin/sh -c ;後者則使用  exec 執行。指定使用其它終端可以通過第二種方式實現,例如 RUN ["/bin/bash", "-c", "echo hello"] 。每條 RUN 指令將在當前鏡像基礎上執行指定命令,並提交爲新的鏡像。當命令較長時可以使用 \ 來換行

4CMD(設置 container 啓動時執行的操作)

該指令有三種格式:

設置指令,用於 container 啓動時指定的操作。該操作可以是執行自定義腳本,也可以是執行系統命令。

CMD ["executable","param1","param2"] 使用 exec 執行,推薦方式;

Dockerfile 指定了 ENTRYPOINT,那麼使用下面的格式:

CMD ["param1","param2"] 提供給 ENTRYPOINT 的默認參數;

ENTRYPOINT 指定的是一個可執行的腳本或者程序的路徑,該指定的腳本或者程序將會以 param1 param2 作爲參數執行。所以如果 CMD 指令使用上面的形式,那麼 Dockerfile 中必須要有配套的 ENTRYPOINT

*指定啓動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最後一條會被執行。

*如果用戶啓動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。

5ENTRYPOINT(設置 container 啓動時執行的操作)

設置指令,指定容器啓動時執行的命令, 可以多次設置,但是隻有最後一個有效

兩種格式:

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2 shell 中執行)。

配置容器啓動後執行的命令,並且不可被 docker run 提供的參數覆蓋。

每個 Dockerfile 中只能有一個 ENTRYPOINT ,當指定多個時,只有最後一個起效。該指令的使用分爲兩種情況,一種是獨自使用,另一種和 CMD 指令配合使用。當獨自使用時,如果你還使用了 CMD 命令且 CMD 是一個完整的可執行的命令,那 麼 CMD 指 令 和 ENTRYPOINT 會 互 相 覆 蓋 只 有 最 後 一 個 CMD 或 者ENTRYPOINT 有效。

*CMD 指令將不會被執行,只有 ENTRYPOINT 指令被執行

CMD echo “Hello, World!”

ENTRYPOINT ls -l

另一種用法和 CMD 指令配合使用來指定 ENTRYPOINT 的默認參數,這時 CMD 指令不是一個完整的可執行命令,僅僅是參數部分; ENTRYPOINT 指令只能使用JSON 方式指定執行命令,而不能指定參數。

*FROM ubuntu

  CMD ["-l"]

  ENTRYPOINT ["/usr/bin/ls"]

兩者同時存在並運行時後面加命令了就只會執行外面加的

6USER(設置 container 容器的用戶,默認是 root 用戶)

格式爲

USER daemon

指定運行容器時的用戶名或 UID,後續的 RUN 也會使用指定用戶。

當服務不需要管理員權限時,可以通過該命令指定運行用戶。並且可以在之前創建所需要的用戶,例如:

RUN groupadd -r postgres&&useradd -r -g postgrespostgres

*指定 memcached 的運行用戶

ENTRYPOINT ["memcached"]

USER daemon

ENTRYPOINT ["memcached", "-u", "daemon"]

7EXPOSE(指定容器需要映射到宿主機器的端口)

格式爲 EXPOSE <port> [<port>...]

 EXPOSE 22 80

設置指令,該指令會將容器中的端口映射成宿主機器中的某個端口。當你需要訪問容器的時候,可以不是用容器的 IP 地址而是使用宿主機器的 IP 地址和映射後的端口。

要完成整個操作需要兩個步驟,首先在 Dockerfile 使用 EXPOSE 設置需要映射的容器端口,然後在運行容器的時候指定-p 選項加上 EXPOSE 設置的端口,這樣 EXPOSE 設置的端口號會被隨機映射成宿主機器中的一個端口號。也可以指定需要映射到宿主機器的那個端口,這時要確保宿主機器上的端口號沒有被使用。 EXPOSE 指令可以一次設置多個端口號,相應的運行容器的時候,可以配套的多次使用-p 選項。

映射一個端口

*EXPOSE port1

# 相應的運行容器使用的命令

docker run -p port1 image

*映射多個端口

EXPOSE port1 port2 port3

# 相應的運行容器使用的命令

*docker run -p port1 -p port2 - p port3 image

還可以指定需要映射到宿主機器上的某個端口號

docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image

 

端口映射是 docker 比較重要的一個功能,原因在於我們每次運行容器的時候容器的 IP 地址不能指定而是在橋接網卡的地址範圍內隨機生成的。宿主機器的 IP 地址是固定的,我們可以將容器的端口的映射到宿主機器上的一個端口,免去每次訪問容器中的某個服務時都要查看容器的 IP 的地址。

對於一個運行的容器,可以使用 docker port 加上容器中需要映射的端口和容器的ID 來查看該端口號在宿主機器上的映射端口。

8ENV(用於設置環境變量)

構建指令, 指定一個環境變量,會被後續 RUN 指令使用,並在容器運行時保持。

格式:

ENV <key> <value>

設置了後,後續的 RUN 命令都可以使用, container 啓動後,可以通過 docker
inspect 查看這個環境變量,也可以通過在 docker run --env key=value 時設置或
修改環境變量。
假如你安裝了 JAVA 程序,需要設置 JAVA_HOME,那麼可以在 Dockerfile 中這樣
寫:

ENV JAVA_HOME /path/to/java/dirent

例如:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC
/usr/src/postgress
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

9ADD(從 src 複製文件到 container dest 路徑)

構建指令,所有拷貝到 container 中的文件和文件夾權限爲 0755uid gid 0

如果是一個目錄,那麼會將該目錄下的所有文件添加到 container 中,不包括目錄;

如果文件是可識別的壓縮格式,則 docker 會幫忙解壓縮(注意壓縮格式);

如果<src>是文件且<dest>中不使用斜槓結束,則會將<dest>視爲文件, <src>的內容會寫入

<dest>

如果<src>是文件且<dest>中使用斜槓結束,則會<src>文件拷貝到<dest>目錄下。

格式:

ADD <src> <dest>

該命令將複製指定的<src>到容器中的<dest>

其中<src>可以是 Dockerfile 所在目錄的一個相對路徑;也可以是一個 URL;還可以是一個 tar 文件(自動解壓爲目錄)

<dest>container 中的絕對路徑

可以複製網址他就會自動幫你下載

ADD 隨便寫一個網址

這個命令的意思就是把Dockerfile目錄裏的文件幫你拷到容器中

10COPY

格式爲 COPY <src><dest>

複製本地主機的<src>(爲 Dockerfile 所在目錄的相對路徑)到容器中的<dest>

11VOLUME(指定掛載點)

設置指令,使容器中的一個目錄具有持久化存儲數據的功能,該目錄可以被容器本身使用,

也可以共享給其他容器使用。我們知道容器使用的是 AUFS,這種文件系統不能持久化數據,

當容器關閉後,所有的更改都會丟失。當容器中的應用有持久化數據的需求時可以在Dockerfile 中使用該指令。

格式:

VOLUME ["<mountpoint>"]

例如: FROM base

VOLUME ["/tmp/data"]

運行通過該 Dockerfile 生成 image 的容器, /tmp/data 目錄中的數據在容器關閉

後,裏面的數據還存在。例如另一個容器也有持久化數據的需求,且想使用上面容

器共享的/tmp/data 目錄,那麼可以運行下面的命令啓動一個容器:

docker run -t -i - rm -volumes- from container1 image2 bash

container1 爲第一個容器的 IDimage2 爲第二個容器運行 image 的名字。

12WORKDIR(切換目錄)

設置指令,可以多次切換(相當於 cd 命令),對 RUN,CMD,ENTRYPOINT 生效。 爲後續的 RUNCMDENTRYPOINT 指令配置工作目錄。

格式:

WORKDIR /path/to/workdir

例如: /p1/p2 下執行 vim a.txt

WORKDIR /p1

WORKDIR p2

RUN vim a.txt

可以使用多個 WORKDIR 指令,後續命令如果參數是相對路徑,則會基於之前命令指定的路徑。

例如

WORKDIR /a

WORKDIR b

WORKDIR c

RUN pwd

則最終路徑爲 /a/b/c

13ONBUILD(在子鏡像中執行)

ONBUILD <Dockerfile 關鍵字>

ONBUILD 指定的命令在構建鏡像時並不執行,而是在它的子鏡像中執行。

格式爲 ONBUILD [INSTRUCTION]

配置當所創建的鏡像作爲其它新創建鏡像的基礎鏡像時,所執行的操作指令。

例如, Dockerfile 使用如下的內容創建了鏡像 image-A

[...]

ONBUILD ADD . /app/src

ONBUILD RUN /usr/local/bin/python-build --dir /app/src

[...]

如果基於 image-A 創建新的鏡像時,新的 Dockerfile 中使用 FROM image-A 指定基礎鏡像

時,會自動執行 ONBUILD 指令內容。

等價於在後面添加了兩條指令。

FROM image-A

#Automatically run the following

ADD . /app/src

RUN /usr/local/bin/python-build --dir /app/src

使用  ONBUILD 指令的鏡像,推薦在標籤中註明,例如 ruby:1.9-onbuild

最後總結:

編寫完成 Dockerfile 之後,可以通過 docker build 命令來創建鏡像。

基本的格式爲 docker build [選項] 路徑,該命令將讀取指定路徑下的 Dockerfile,並將該路徑下所有內容發送給 Docker 服務端,由服務端來創建鏡像。因此一般建議放置 Dockerfile 的目錄爲空目錄。

要指定鏡像的標籤信息,可以通過 -t 選項,例如

$ sudodocker build –tmyrepo/myapp/tmp/test1/

docker 應用案例:使用 dockerfile 創建 sshd 鏡像模板並提供 http 訪問應用

1、建一個 sshd_dockerfile 工作目錄


編輯 run.sh 文件


在主機上生成 ssh 祕鑰對,並創建 authorized_keys 文件

2、寫 Dockerfile


以上選項的含義解釋:

FROM centos:centos6 選擇一個已有的 os 鏡像作爲基礎

MAINTAINER 鏡像的作者

RUN yum install -y openssh-server sudo 安裝 openssh-server sudo 軟件包

添加測試用戶 admin,密碼 admin,並且將此用戶添加到 sudoers

RUN useradd admin

RUN echo "admin:admin" | chpasswd

RUN echo "admin ALL=(ALL) ALL" >> /etc/sudoers

下面這兩句比較特殊,在 centos6 上必須要有,否則創建出來的容器 sshd 不能登錄

RUN ssh-keygen -t dsa - f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -t rsa - f /etc/ssh/ssh_host_rsa_key

注意: centos7 上必須要有,否則創建出來的容器 sshd 不能登錄

RUN ssh-keygen -t dsa - f /etc/ssh/ssh_host_dsa_key

RUN ssh-keygen -t rsa - f /etc/ssh/ssh_host_rsa_key

RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key

RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key

將公鑰信息上傳到遠程連接用戶的宿主目錄的.ssh

ADD authorized_keys /home/admin/.ssh/authorized_keys

啓動 sshd 服務並且暴露 22 端口

RUN mkdir /var/run/sshd

EXPOSE 22 80

CMD [ "/run.sh"] 也可以寫成這種方式 CMD ["/usr/sbin/sshd", "-D"]

sshd_dockerfile 目錄下,使用 docker build 命令來創建鏡像,注意:在最後還有一個”.”,表示使用當前目錄中的 dockerfile



執行 docker images 查看新生成的鏡像


使用剛纔建好的鏡像運行一個容器,將容器的端口映射到主機的 10122



在宿主主機打開一個終端,連接剛纔新建的容器


注: admin 用戶是容器中的用戶, 192.168.1.102 地址是宿主機的地址。

測試 sudo 執行授權命令:


發佈了28 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章