1. 程式人生 > >編寫dockerfile

編寫dockerfile

文件 其中 virtual per lba port ecb ports root

參考:http://www.cnblogs.com/liuyansheng/p/6098470.html

一、dockerfile介紹

  是一種被Docker程序解釋的腳本,Dockerfile由一條一條的指令組成,每條指令對應Linux下面的一條命令。Docker程序將這些Dockerfile指令翻譯真正的Linux命令。Dockerfile有自己書寫格式和支持的命令,Docker程序解決這些命令間的依賴關系,類似於Makefile。Docker程序將讀取Dockerfile,根據指令生成定制的image。相比image這種黑盒子,Dockerfile這種顯而易見的腳本更容易被使用者接受,它明確的表明image是怎麽產生的。有了Dockerfile,當我們需要定制自己額外的需求時,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻煩。

二、實驗準備:

  1、創建 Dockerfile 文件

  首先,需要創建一個目錄來存放 Dockerfile 文件,目錄名稱可以任意,在目錄裏創建Dockerfile文件:

[[email protected] ~]# mkdir wangmo
[[email protected] ~]# cd wangmo/
[[email protected] wangmo]# touch dockerfile

  使用vim/gedit編輯Dockerfile文件,根據我們的需求輸入內容。

三、Dockerfile 基本框架

  Dockerfile一般包含下面幾個部分:

    基礎鏡像:以哪個鏡像作為基礎進行制作,用法是FROM 基礎鏡像名稱
    維護者信息:需要寫下該Dockerfile編寫人的姓名或郵箱,用法是MANITAINER 名字/郵箱
    鏡像操作命令:對基礎鏡像要進行的改造命令,比如安裝新的軟件,進行哪些特殊配置等,常見的是RUN 命令
    容器啟動命令:當基於該鏡像的容器啟動時需要執行哪些命令,常見的是CMD 命令或ENTRYPOINT
    在本節實驗中,我們依次先把這四項信息填入文檔。Dockerfile中的#標誌後面為註釋,可以不用寫,另外實驗樓的環境不支持中文輸入,比較可惜。

  依次輸入下面的基本框架內容:

# Version 0.1
# 基礎鏡像 FROM ubuntu:latest # 維護者信息 MAINTAINER [email protected] # 鏡像操作命令 RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean # 容器啟動命令 CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

  上面的Dockerfile非常簡單,創建了一個apache的鏡像。包含了最基本的四項信息。

  其中FROM指定基礎鏡像,如果鏡像名稱中沒有制定TAG,默認為latest。RUN命令默認使用/bin/sh Shell執行,默認為root權限。如果命令過長需要換行,需要在行末尾加\。CMD命令也是默認在/bin/sh中執行,並且默認只能有一條,如果是多條CMD命令則只有最後一條執行。用戶也可以在docker run命令創建容器時指定新的CMD命令來覆蓋Dockerfile裏的CMD。

  這個Dockerfile已經可以使用docker build創建新鏡像了,先構建一個版本shiyanloutest:0.1:

[[email protected] wangmo]# docker build -t wangmotest:0.1 .        #構建鏡像
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:latest
latest: Pulling from ubuntu
576b12d1aa01: Pull complete 
b5ce920a148c: Pull complete 
274da7f89b05: Pull complete 
0346cecb4e51: Pull complete 
2e36b30057ab: Pull complete 
f5bb94a8fac4: Pull complete 
Digest: sha256:7c8894a0f32d3f1fadf086d18d12441ce0cd19295075af8dee34ce5e1f6c3ed1
Status: Downloaded newer image for ubuntu:latest
 ---> f5bb94a8fac4
Step 1 : MAINTAINER [email protected]
 ---> Running in 191d22125b22
 ---> c703996f3e87
Removing intermediate container 191d22125b22
Step 2 : RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean
 ---> Running in 18ff8781a66c
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libatm1:amd64.
(Reading database ... 4764 files and directories currently installed.)
Preparing to unpack .../libatm1_1%3a2.5.1-1.5_amd64.deb ...
Unpacking libatm1:amd64 (1:2.5.1-1.5) ...
Selecting previously unselected package libmnl0:amd64.
...
...
...
Step 3 : CMD /usr/sbin/apache2ctl -D FOREGROUND
 ---> Running in 569852d0bdb1
 ---> 787a3ee0813e
Removing intermediate container 569852d0bdb1
Successfully built 787a3ee0813e

[[email protected] wangmo]# docker images        #查看鏡像
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
wangmotest          0.1                 787a3ee0813e        14 hours ago        254.3 MB
ubuntu              latest              f5bb94a8fac4        10 days ago         117.3 MB
centos              latest              6cc2eba34ef6        4 weeks ago         192.5 MB
nginx               latest              cbfa3eb33c93        4 weeks ago         182.5 MB
registry            latest              6e757ddb42c5        4 weeks ago         33.17 MB
<none>              <none>              093e606554fe        10 months ago       301 MB
training/webapp     latest              02a8815912ca        24 months ago       348.7 MB

使用該鏡像創建容器web1,將容器中的端口80映射到本地80端口:

[[email protected] wangmo]# docker run -d -p 80:80 --name web1 wangmotest:0.1
44e51d913f3de3df28a4765685973900f5e953c0e6c98082a3e5a542da846947
[[email protected] wangmo]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                NAMES
44e51d913f3d        wangmotest:0.1      "/usr/sbin/apache2ct   16 seconds ago      Up 15 seconds       0.0.0.0:80->80/tcp   web1

使用實驗環境桌面上的瀏覽器打開localhost進行測試,查看是否apache已運行:

技術分享

三、Dockerfile 編寫常用命令

在上述基本的架構下,我們根據需求可以增加新的內容到Dockerfile中。後續的擴展操作都需要放置在Dockerfile的鏡像操作部分。其中部分命令在本實驗中並不會用到,但需要有所了解。

1、指定容器運行的用戶

該用戶將作為後續的RUN命令執行的用戶。這個命令本實驗不需要,但在一些需要指定用戶來運行的應用部署時非常關鍵,比如提供hadoop服務的容器通常會使用hadoop用戶來啟動服務。

命令使用方式,例如使用shiyanlou用戶來執行後續命令:

USER shiyanlou

2、指定後續命令的執行目錄

由於我們需要運行的是一個靜態網站,將啟動後的工作目錄切換到/var/www/html目錄:

WORKDIR /var/www/html

3、對外連接端口號

由於內部服務會啟動Web服務,我們需要把對應的80端口暴露出來,可以提供給容器間互聯使用,可以使用EXPOSE命令。

在鏡像操作部分增加下面一句:

EXPOSE 80

4、設置容器主機名

ENV命令能夠對容器內的環境變量進行設置,我們使用該命令設置由該鏡像創建的容器的主機名為shiyanloutest,向Dockerfile中增加下面一句:

ENV HOSTNAME shiyanloutest

5、向鏡像中增加文件

向鏡像中添加文件有兩種命令:COPYADD

COPY simplecloudsite /var/www/html

ADD 命令支持添加本地的tar壓縮包到容器中指定目錄,壓縮包會被自動解壓為目錄,也可以自動下載URL並拷貝到鏡像,例如:

ADD html.tar /var/www
ADD http://www.shiyanlou.com/html.tar /var/www

根據實驗需求,我們把需要的一個網站放到鏡像裏,需要把一個tar包添加到apache的/var/www目錄下,因此選擇使用 ADD命令:

ADD html.tar /var/www

四、CMD 與 ENTRYPOINT

ENTRYPOINT 容器啟動後執行的命令,讓容器執行表現的像一個可執行程序一樣,與CMD的區別是不可以被docker run覆蓋,會把docker run後面的參數當作傳遞給ENTRYPOINT指令的參數。Dockerfile中只能指定一個ENTRYPOINT,如果指定了很多,只有最後一個有效。docker run命令的-entrypoint參數可以把指定的參數繼續傳遞給ENTRYPOINT

在本實驗中兩種方式都可以選擇。

五、掛載數據卷

將apache訪問的日誌數據存儲到宿主機可以訪問的數據卷中:

VOLUME ["/var/log/apche2"]

六、設置容器內的環境變量

使用ENV設置一些apache啟動的環境變量:

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apche2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apche2

七、使用 Supervisord

CMD如果只有一個命令,那如果我們需要運行多個服務怎麽辦呢?最好的辦法是分別在不同的容器中運行,通過link進行連接,比如先前實驗中用到的web,app,db容器。如果一定要在一個容器中運行多個服務可以考慮用Supervisord來進行進程管理,方式就是將多個啟動命令放入到一個啟動腳本中。

首先安裝Supervisord,添加下面內容到Dockerfile:

RUN apt-get install -yqq supervisor
RUN mkdir -p /var/log/supervisor

拷貝配置文件到指定的目錄:

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

其中supervisord.conf文件需要放在/home/shiyanlou/shiyanloutest下,文件內容如下:

[supervisord]
nodaemon=true

[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"

如果有多個服務需要啟動可以在文件後繼續添加[program:xxx],比如如果有ssh服務,可以增加[program:ssh]

修改CMD命令,啟動Supervisord

CMD ["/usr/bin/supervisord"]

八、從 Dockerfile 創建鏡像

將上述內容完成後放入到/home/shiyanlou/shiyanloutest/Dockerfile文件中,最終得到的Dockerfile文件如下:

技術分享
# Version 0.2

# 基礎鏡像
FROM ubuntu:latest

# 維護者信息
MAINTAINER [email protected]

# 鏡像操作命令
RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean
RUN apt-get install -yqq supervisor
RUN mkdir -p /var/log/supervisor

VOLUME ["/var/log/apche2"]

ADD html.tar /var/www
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

WORKDIR /var/www/html

ENV HOSTNAME shiyanloutest
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apche2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apche2

EXPOSE 80

# 容器啟動命令
CMD ["/usr/bin/supervisord"]
技術分享

同時在/home/shiyanlou/shiyanloutest目錄下,添加supervisord.conf文件:

[supervisord]
nodaemon=true

[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"

並下載靜態頁面文件壓縮包:

cd /home/shiyanlou/shiyanloutest
wget http://labfile.oss.aliyuncs.com/courses/498/html.tar

http://simplecloud.cn網站的頁面tar包下載到/home/shiyanlou/shiyanloutest目錄:

docker build 執行創建,-t參數指定鏡像名稱:

docker build -t shiyanloutest:0.2 /home/shiyanlou/shiyanloutest/

技術分享

docker images 查看創建的新鏡像已經出現在了鏡像列表中:

技術分享

docker inspect shiyanloutest:0.2 查看該鏡像的詳細信息:

技術分享

由該鏡像創建新的容器web2,並映射本地的80端口到容器的80端口:

docker run -d -p 80:80 --name web2 shiyanloutest:0.2

最後打開桌面上的firefox瀏覽器,輸入本地地址訪問127.0.0.1,看到我們克隆的琛石科技的網站:

技術分享

編寫dockerfile