-
編寫 DockerFile
從 Dockerfile 構(gòu)建鏡像
本次實(shí)驗的需求是完成一個Dockerfile,通過該Dockerfile創(chuàng)建一個Web應(yīng)用,該web應(yīng)用為apache托管的一個靜態(tài)頁面網(wǎng)站,換句話說,
我們寫一個Dockerfile,用來創(chuàng)建一個實(shí)驗樓公司的網(wǎng)站應(yīng)用,就是http://www.simplecloud.cn這個站點(diǎn)。這個站點(diǎn)是純靜態(tài)的頁面,我們也可以直接下載得到。
-
一、實(shí)驗準(zhǔn)備
-
-
1、創(chuàng)建 Dockerfile 文件
-
首先,需要創(chuàng)建一個目錄來存放 Dockerfile 文件,目錄名稱可以任意,在目錄里創(chuàng)建Dockerfile文件:
cd /home/shiyanlou
mkdir shiyanloutest
cd shiyanloutest
touch Dockerfile
使用vim/gedit編輯Dockerfile文件,根據(jù)我們的需求輸入內(nèi)容。
-
二、Dockerfile 基本框架
-
Dockerfile一般包含下面幾個部分:
基礎(chǔ)鏡像:以哪個鏡像作為基礎(chǔ)進(jìn)行制作,用法是FROM 基礎(chǔ)鏡像名稱
維護(hù)者信息:需要寫下該Dockerfile編寫人的姓名或郵箱,用法是MANITAINER 名字/郵箱
鏡像操作命令:對基礎(chǔ)鏡像要進(jìn)行的改造命令,比如安裝新的軟件,進(jìn)行哪些特殊配置等,常見的是RUN 命令
容器啟動命令:當(dāng)基于該鏡像的容器啟動時需要執(zhí)行哪些命令,常見的是CMD 命令或ENTRYPOINT
在本節(jié)實(shí)驗中,我們依次先把這四項信息填入文檔。Dockerfile中的#標(biāo)志后面為注釋,可以不用寫,另外實(shí)驗樓的環(huán)境不支持中文輸入,比較可惜。
依次輸入下面的基本框架內(nèi)容:
# Version 0.1
# 基礎(chǔ)鏡像
FROM ubuntu:latest
# 維護(hù)者信息
MAINTAINER shiyanlou@shiyanlou.com
# 鏡像操作命令
RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean
# 容器啟動命令
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
上面的Dockerfile非常簡單,創(chuàng)建了一個apache的鏡像。包含了最基本的四項信息。
其中FROM指定基礎(chǔ)鏡像,如果鏡像名稱中沒有制定TAG,默認(rèn)為latest。RUN命令默認(rèn)使用/bin/sh Shell執(zhí)行,默認(rèn)為root權(quán)限。如果命令過長需要換行,需要在行末尾加\。CMD命令也是默認(rèn)在/bin/sh中執(zhí)行,并且默認(rèn)只能有一條,如果是多條CMD命令則只有最后一條執(zhí)行。用戶也可以在docker run命令創(chuàng)建容器時指定新的CMD命令來覆蓋Dockerfile里的CMD。
這個Dockerfile已經(jīng)可以使用docker build創(chuàng)建新鏡像了,先構(gòu)建一個版本shiyanloutest:0.1:
cd /home/shiyanlou/shiyanloutest
docker build -t shiyanloutest:0.1 .
構(gòu)建需要安裝apache2,會花幾分鐘,最后查看新創(chuàng)建的鏡像:
docker images
使用該鏡像創(chuàng)建容器web1,將容器中的端口80映射到本地80端口:
docker run -p 80:80 --name httpd shiyanloutest
-
三、Dockerfile 編寫常用命令
-
在上述基本的架構(gòu)下,我們根據(jù)需求可以增加新的內(nèi)容到Dockerfile中。后續(xù)的擴(kuò)展操作都需要放置在Dockerfile的鏡像操作部分。其中部分命令在本實(shí)驗中并不會用到,但需要有所了解。
-
1、指定容器運(yùn)行的用戶
-
該用戶將作為后續(xù)的RUN命令執(zhí)行的用戶。這個命令本實(shí)驗不需要,但在一些需要指定用戶來運(yùn)行的應(yīng)用部署時非常關(guān)鍵,比如提供hadoop服務(wù)的容器通常會使用hadoop用戶來啟動服務(wù)。
命令使用方式,例如使用shiyanlou用戶來執(zhí)行后續(xù)命令:
USER shiyanlou
-
2、指定后續(xù)命令的執(zhí)行目錄
-
由于我們需要運(yùn)行的是一個靜態(tài)網(wǎng)站,將啟動后的工作目錄切換到/var/www/html目錄:
WORKDIR /var/www/html
-
3、對外連接端口號
-
由于內(nèi)部服務(wù)會啟動Web服務(wù),我們需要把對應(yīng)的80端口暴露出來,可以提供給容器間互聯(lián)使用,可以使用EXPOSE命令。
在鏡像操作部分增加下面一句:
EXPOSE 80
-
4、設(shè)置容器主機(jī)名
-
ENV命令能夠?qū)θ萜鲀?nèi)的環(huán)境變量進(jìn)行設(shè)置,我們使用該命令設(shè)置由該鏡像創(chuàng)建的容器的主機(jī)名為shiyanloutest,向Dockerfile中增加下面一句:
ENV HOSTNAME shiyanloutest
-
5、向鏡像中增加文件
-
向鏡像中添加文件有兩種命令:COPY 和ADD。
COPY simplecloudsite /var/www/html
ADD 命令支持添加本地的tar壓縮包到容器中指定目錄,壓縮包會被自動解壓為目錄,也可以自動下載URL并拷貝到鏡像,例如:
ADD html.tar /var/www
ADD http://www.shiyanlou.com/html.tar /var/www
根據(jù)實(shí)驗需求,我們把需要的一個網(wǎng)站放到鏡像里,需要把一個tar包添加到apache的/var/www目錄下,因此選擇使用 ADD命令:
ADD html.tar /var/www
-
四、CMD 與 ENTRYPOINT
-
ENTRYPOINT 容器啟動后執(zhí)行的命令,讓容器執(zhí)行表現(xiàn)的像一個可執(zhí)行程序一樣,與CMD的區(qū)別是不可以被docker run覆蓋,會把docker run后面的參數(shù)當(dāng)作傳遞給ENTRYPOINT指令的參數(shù)。Dockerfile中只能指定一個ENTRYPOINT,如果指定了很多,只有最后一個有效。docker run命令的-entrypoint參數(shù)可以把指定的參數(shù)繼續(xù)傳遞給ENTRYPOINT。
在本實(shí)驗中兩種方式都可以選擇。
-
五、掛載數(shù)據(jù)卷
-
將apache訪問的日志數(shù)據(jù)存儲到宿主機(jī)可以訪問的數(shù)據(jù)卷中:
VOLUME ["/var/log/apche2"]
-
六、設(shè)置容器內(nèi)的環(huán)境變量
-
使用ENV設(shè)置一些apache啟動的環(huán)境變量:
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如果只有一個命令,那如果我們需要運(yùn)行多個服務(wù)怎么辦呢?最好的辦法是分別在不同的容器中運(yùn)行,通過link進(jìn)行連接,比如先前實(shí)驗中用到的web,app,db容器。如果一定要在一個容器中運(yùn)行多個服務(wù)可以考慮用Supervisord來進(jìn)行進(jìn)程管理,方式就是將多個啟動命令放入到一個啟動腳本中。
首先安裝Supervisord,添加下面內(nèi)容到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下,文件內(nèi)容如下:
[supervisord]
nodaemon=true
[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"
如果有多個服務(wù)需要啟動可以在文件后繼續(xù)添加[program:xxx],比如如果有ssh服務(wù),可以增加[program:ssh]。
修改CMD命令,啟動Supervisord:
CMD ["/usr/bin/supervisord"]
-
八、從 Dockerfile 創(chuàng)建鏡像
-
將上述內(nèi)容完成后放入到/home/shiyanlou/shiyanloutest/Dockerfile文件中,最終得到的Dockerfile文件如下:
# Version 0.2
# 基礎(chǔ)鏡像
FROM ubuntu:latest
# 維護(hù)者信息
MAINTAINER shiyanlou@shiyanlou.com
# 鏡像操作命令
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"]
復(fù)制代碼
同時在/home/shiyanlou/shiyanloutest目錄下,添加supervisord.conf文件:
[supervisord]
nodaemon=true
[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"
并下載靜態(tài)頁面文件壓縮包:
cd /home/shiyanlou/shiyanloutest
wget http://labfile.oss.aliyuncs.com/courses/498/html.tar
將http://simplecloud.cn網(wǎng)站的頁面tar包下載到/home/shiyanlou/shiyanloutest目錄:
docker build 執(zhí)行創(chuàng)建,-t參數(shù)指定鏡像名稱:
docker build -t shiyanloutest:0.2 /home/shiyanlou/shiyanloutest/
由該鏡像創(chuàng)建新的容器web2,并映射本地的80端口到容器的80端口:
docker run -d -p 80:80 --name web2 shiyanloutest:0.2
最后打開桌面上的firefox瀏覽器,輸入本地地址訪問127.0.0.1,看到我們克隆的琛石科技的網(wǎng)站:
abba