docker學習筆記6:利用dockerfile創建鏡像介紹(生成簡單web服務器鏡像)


本文介紹如何利用dockerfile來創建鏡像。下面介紹具體的操作過程:

一、創建構建環境

操作示例如下:

xxx@ubuntu:~$ pwd
/home/xxx
xxx@ubuntu:~$ mkdir myweb
xxx@ubuntu:~$ cd myweb
xxx@ubuntu:~/myweb$ touch Dockerfile

上面命令在當前用戶(xxx)的主目錄下創建了一個myweb目錄,並在該目錄下建立了一個空的文件名為Dockerfile文件。
這個目錄就是我們的構建環境(或上下文)。

二、編寫Dockerfile文件內容

Dockerfile文件中,是一系列的指令組成。每條指令,包括指令名(必須大寫)和指令所需的參數。看一個例子:

# version:0.0.1
FROM ubuntu
MAINTAINER XXX "xxx@test.com"
RUN  apt-get update
RUN  apt-get install -y nginx
RUN  echo 'hello, i am a web image'  > /usr/share/nginx/html/index.html
EXPOSE 80

文件的第一行是一條注釋,在dockfile文件中,以#開頭的表示注釋。
當執行dockerfile文件時(如何執行,后面會介紹),其流程如下:

1、從基礎鏡像運行一個容器(第一條FROM指令的參數用於指定一個已經存在的基礎鏡像,每個dockerfile文件的第一條指令都是FROM)

2、在上面創建的容器中,執行一條指令,對容器做出修改(一般指令總會對容器進行一些改變,否則該指令就不需要了)

3、執行類似docker commit命令,提交一個新的鏡像層(該層的內容就是上面指令造成的變化內容)

4、基於剛提交的鏡像運行一個新的容器。

5、重復2~4步驟,逐個執行dockerfile中的所有指令。

看到這里大家可以有個疑問,為何每條指令都要創建鏡像和容器呢,而不是只只在開始創建一次容器,然后基於該容器執行所有指令,完成所有修改后,再提交生成一個鏡像呢?

這正是docker鏡像分層特點的優勢。可以想象一下,采用這種放的好處是,即使因為某種原因導致某條指令失敗,但我們還是可以得到一個可用的鏡像,然后我們就可以通過該鏡像運行一個容器,在該容器中執行失敗的指令,從而方便的進行調試,找到失敗原因。

下面我們來介紹上面dokcerfile文件中每一行的意義:

1、第一行上面已經介紹,以#開頭,是注釋。

2、第二行FROM指令,用於指定基礎鏡像。是所有dockerfile的第一條命令。因為所有新的鏡像都會基於該基礎鏡像基礎上變化來的。

3、第三行 MAINTAINER指令,是標識鏡像的作者和聯系方式(這里是電子郵件),以方便鏡像使用者和作者聯系。

4、第四~六行RUN指令,用於在容器中執行參數指定的命令。上面的例子第4行是更新已經安裝的APT倉庫,第5行是下載安裝nginx包,第6行是生成一個html文件,文件中只包含簡單的一句話。

5、最后一行EXPOSE指令,告訴docker守護進程,容器的應用將使用指定的端口號(EXPOSE指令的參數,這個例子是80)。

 

三、構建鏡像

通過docker build命令運行dockerfile文件,最后生成需要的鏡像。命令如:

docker build -t="jene/myweb" .

參數-t指定生成鏡像的所屬用戶名和倉庫名,也可以有tag標識(這個例子沒寫,默認為latest)。 命令的最后點 不是結束符,而是表示Dockerfile文件在當前路徑下。也可以指定一個git倉庫的地址(只要該地址下有Dockerfile),則會利用git倉庫中的dockerfile文件來構建鏡像。

執行的過程會詳細 輸出每條指令執行的詳細信息。

構建成功后,我們就可以用 docker images命令查看新構建的鏡像,也可以用docker history命令查看新構建鏡像的構建歷史。

 

四、創建容器和啟動容器中的web服務

docker run -d -p 80 --name myweb 1311399350/myweb nginx -g "daemon off;"

上面命令創建和運行了容器,並將nginx服務啟動了。

上面命令除 -p參數外,其它參數前面文章都介紹過了。-d表示是 容器。 --name指定容器名,這里是myweb。 后面的是鏡像名。以及要執行的命令(這里是啟動nginx服務)。 -p參數我們下面詳細介紹。

下面我們來通過curl工具測試這個web服務是否可用。

1、先進入容器內訪問

docker exec -i -t myweb /bin/bash    //進入容器的交互式shell

curl localhost:80   //可能容器中沒有curl工具

輸出如下內容
hello, i am a web image

2、在主機上訪問容器內的服務

首先查看容器內的80端口與主機上的端口的映射關系

運行 docker port myweb 80 顯示信息如下

0.0.0.0:32768

這里可以看出,映射的端口是32768.

我們在主機執行:

curl localhost:32768

輸出
hello, i am a web image

3、在主機以外的局域網內的其它機器訪問

先用ifconfig查看dokcer主機的ip地址,如 192.168.142.138

在其它機器上通過  http://192.168.142.138:32768/ 一樣可以訪問到 index.html網頁。

 

五、容器的端口配置

方法一:自動映射

docker run -d -p 80 --name myweb 1311399350/myweb nginx -g "daemon off;"

上面的 -p 80 ,將在docker主機上隨機打開一個端口(可利用docker port命令查看,或者docker ps也能看到,這里是32768)映射到容器中的80端口上。

方法二:指定映射

除了自動映射外,還可以指定映射關系,如:

docker run -d -p 80:80 --name myweb 1311399350/myweb nginx -g "daemon off;"

docker port myweb 80
0.0.0.0:80

可以看出,主機上的80端口映射到容器的80端口。

這樣指定的方式有好有懷,壞處是,第一無法運行多個同樣的容器,第二容易與主機上的應用沖突。好處是端口是已知的。需要小心使用。

方法三:公開dockerfile中EXPOSE指令指定的端口

docker run -d -P --name myweb 1311399350/myweb nginx -g "daemon off;"

 利用大些的-P參數,將dockerfile中EXPOSE指令指定的端口(容器內端口)對本地宿主主機公開,並隨機綁定到本地宿主主機的端口上。

docker port myweb 80
0.0.0.0:32771

注意: 在docker run命令中通過 -p標記暴露的容器端口,並不一定需要在dockerfile文件中用EXPOSE指令配置。

在dockerfile文件中用EXPOSE指令配置端口,其好處是在docker run命令中可以用-P標記來全部暴露,省去了在docker run命令中用-p來逐個指定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM