天天看點

Docker學習(8)——建構鏡像(Dockerfile、commit)

前言

在前面的文章裡我們已經詳細介紹了建構鏡像的兩種常用方式,下面我們将具體看看如何實際操作,以及鏡像的優化方式。

一、commit封裝鏡像

以ubuntu的鏡像為例:

1.導入ubuntu鏡像

[[email protected] ~]# docker load -i ubuntu.tar 
56abdd66ba31: Loading layer [==================================================>]  196.8MB/196.8MB
9468150a390c: Loading layer [==================================================>]  208.9kB/208.9kB
11083b444c90: Loading layer [==================================================>]  4.608kB/4.608kB
5f70bf18a086: Loading layer [==================================================>]  1.024kB/1.024kB
Loaded image: ubuntu:latest
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

2.建立容器vm1,運作ubuntu,并建立檔案,然後ctrl+p+q退出

[[email protected] ~]# docker run -it --name vm1 ubuntu
[email protected]:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[email protected]:/# mkdir test
[email protected]:/# cd test/
[email protected]:/test# ls
[email protected]:/test# touch file{1..10}
[email protected]:/test# ls
file1  file10  file2  file3  file4  file5  file6  file7  file8  file9
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

3.在上面的基礎上我們删除vm1容器,然後重建立立,檢視建立的檔案是否還存在

[[email protected] ~]# docker rm -f vm1
vm1
[[email protected] ~]# 
[[email protected] ~]# docker run -it --name vm1 ubuntu
[email protected]:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[email protected]:/# cd test
bash: cd: test: No such file or directory
[email protected]:/# 
           

可以看到,重建立立的容器裡沒有之前建立的檔案

Docker學習(8)——建構鏡像(Dockerfile、commit)

那麼問題來了:如果我們得到一個原始的鏡像後,需要往上百台的之機上建構容器并部署相關服務,做好的鏡像沒辦法儲存打包,那将是一件非常痛苦的事情;這個時候我們可以使用commit指令将容器建構成一個新的鏡像

4.commit封裝鏡像

commit建構鏡像三部曲:

  • 運作容器
  • 修改容器
  • 将容器儲存為新的鏡像

我們直接使用上面建構的容器vm1,對它進行修改

Docker學習(8)——建構鏡像(Dockerfile、commit)

使用commit指令進行封裝

[[email protected] ~]# docker commit vm1 ubuntu:vm1
[[email protected] ~]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
ubuntu                     vm1                 9363b7554e70        11 seconds ago      188MB
           
Docker學習(8)——建構鏡像(Dockerfile、commit)
Docker學習(8)——建構鏡像(Dockerfile、commit)

5.使用新封裝的鏡像建構容器,儲存了之前操作的痕迹

[[email protected] ~]# docker run -it --name vm2 ubuntu:vm1 
[email protected]:/# 
[email protected]:/# 
[email protected]:/# ls
bin   dev  file1   file2  file4  file6  file8  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  file10  file3  file5  file7  file9  lib   media  opt  root  sbin  sys  usr
[email protected]:/# 
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

二、編寫Dockerfile建構鏡像

準備工作:

删除前面建構的鏡像和容器

[[email protected] ~]# docker rm -f vm1
vm1
[[email protected] ~]# docker rm -f vm2
vm2
[[email protected] ~]# docker rmi ubuntu:vm1 
Untagged: ubuntu:vm1
Deleted: sha256:9363b7554e709c67de4baaef54c8b8ce2f0403f1f745eed41d3524492c1f88b3
Deleted: sha256:9e3d8f56343aee0afac55ab4dc21e1ee0c6f2780cebcd58583565ae1e7126079
           

開始建構:編寫DockFile實作安裝httpd服務

1.導入鏡像

[[email protected] ~]# docker load -i rhel7.tar
           

2.編寫Dockerfile

(1)建立放置dockfile的目錄

mkdir docker
           

(2)編寫Dockerfile檔案

vim Dockerfile
           
FROM rhel7      # 源鏡像是rhel7,最好将名為rhel7的鏡像放在本地
COPY yum.repo /etc/yum.repo.d		#将本地的yum源檔案複制到容器中的/etc/yum.repo.d/目錄下
RUN  rpmdb --rebuilddb && yum install -y httpd
# 執行指令安裝httpd并清除yum緩存
# rpmdb 指令用于初始化和重建rpm資料庫
# --rebuilddb:從已安裝的標頭檔案,反向重建RPM資料庫
EXPOSE 80    # 定義端口為80
CMD ["/usr/share/httpd","-D","FOREGROUND"]
# 打開apach服務
# -D 是全局檔案/etc/sysconfig/httpd中的打開參數
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

3.編寫yum.repo(在目前目錄下,也就是放置Dockerfile的目錄中)

Docker學習(8)——建構鏡像(Dockerfile、commit)

4.封裝鏡像,并測試能否正常使用

[[email protected] docker]# docker build  -t rhel7:v1 .		##注意指令後有一個點,表示目前目錄下
           

出現報錯,Dokerfile内容有誤

Docker學習(8)——建構鏡像(Dockerfile、commit)

修改後重試

Docker學習(8)——建構鏡像(Dockerfile、commit)
Docker學習(8)——建構鏡像(Dockerfile、commit)

鏡像建構成功

5.建構容器

[[email protected] docker]# docker run -d --name vm1 rhel7:v1
7fdb6ab9155b8f2afeb44b949107f685192d43f84ac98dfaf2c848565b670f53
           

查詢IP位址

[[email protected] docker]# docker inspect vm1
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

書寫預設釋出檔案,導入容器内部

[[email protected] docker]# ls
Dockerfile  index.html  yum.repo
[[email protected] docker]# cat index.html 
snow snow snow
snow snow snow
snow snow snow
snow snow snow
snow snow snow
[[email protected] docker]# 
[[email protected] docker]# docker container cp index.html vm1:/var/www/html
           

通路測試

curl 172.17.0.2
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

建構鏡像,并添加資料卷挂載位置(VOLUME [“var/www/html”])

1.編寫Dockerfile

[[email protected] docker]# vim Dockerfile
FROM rhel7
COPY yum.repo /etc/yum.repos.d/
RUN rpmdb --rebuilddb  && yum install -y httpd
EXPOSE 80
VOLUME ["/var/www/html"]
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
           

2.Build建構鏡像

[[email protected] docker]# docker build -t rhel7:v2 .
Sending build context to Docker daemon  4.096kB
Step 1/6 : FROM rhel7
 ---> 0a3eb3fde7fd
Step 2/6 : COPY yum.repo /etc/yum.repos.d/
 ---> Using cache												##使用了緩存
 ---> db0ce1a7fb77
Step 3/6 : RUN rpmdb --rebuilddb  && yum install -y httpd
 ---> Using cache												##使用了緩存
 ---> ba007361f210
Step 4/6 : EXPOSE 80
 ---> Using cache												##使用了緩存
 ---> 554977c12e37
Step 5/6 : VOLUME ["/var/www/html"]
 ---> Running in 4fbea9452763
Removing intermediate container 4fbea9452763
 ---> 7094cf717b4c
Step 6/6 : CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
 ---> Running in 0efba909bae5
Removing intermediate container 0efba909bae5
 ---> 6d1e0dbaa3ff
Successfully built 6d1e0dbaa3ff
Successfully tagged rhel7:v2
           
這就要提到一個重要點:鏡像的緩存特性

此時可以看到 rhel7:v2比 rhel7:v1多了一層

[[email protected] docker]# docker history rhel7:v1
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
73f8e04e06ce        About an hour ago   /bin/sh -c #(nop)  CMD ["/usr/sbin/httpd" "-…   0B                  
554977c12e37        About an hour ago   /bin/sh -c #(nop)  EXPOSE 80                    0B                  
ba007361f210        About an hour ago   /bin/sh -c rpmdb --rebuilddb  && yum install…   52.8MB              
db0ce1a7fb77        About an hour ago   /bin/sh -c #(nop) COPY file:09c92a5038a23196…   71B                 
0a3eb3fde7fd        5 years ago                                                         140MB               Imported from -
[[email protected] docker]# docker history rhel7:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
6d1e0dbaa3ff        5 minutes ago       /bin/sh -c #(nop)  CMD ["/usr/sbin/httpd" "-…   0B                  
7094cf717b4c        5 minutes ago       /bin/sh -c #(nop)  VOLUME [/var/www/html]       0B                  
554977c12e37        About an hour ago   /bin/sh -c #(nop)  EXPOSE 80                    0B                  
ba007361f210        About an hour ago   /bin/sh -c rpmdb --rebuilddb  && yum install…   52.8MB              
db0ce1a7fb77        About an hour ago   /bin/sh -c #(nop) COPY file:09c92a5038a23196…   71B                 
0a3eb3fde7fd        5 years ago                                                         140MB               Imported from -
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

3.生成容器,并測試是否可以正常通路

[[email protected] docker]# ls
Dockerfile  index.html  yum.repo
[[email protected] docker]# mkdir web
[[email protected] docker]# mv index.html web/
[[email protected] docker]# docker run -d --name vm2 -v /docker/web:/var/www/html rhel7:v2
f661d7785db9ce69e256cbe79f9c48743a4139084e4655f43ad3fc942b0d3e1f
[[email protected] docker]# curl 172.17.0.2
snow snow snow
snow snow snow
snow snow snow
snow snow snow
snow snow snow
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

直接在資料卷中編寫釋出檔案

1.重新生成容器

[[email protected] docker]# docker rm -f vm2
vm2
[[email protected] docker]# docker run -d --name vm2 rhel7:v2
87e5580c7a26c9eebdd23e0da5c2394620311b0b86585814b8e40bf26dd4048d
           

2.檢視vm2的資料卷位置

[[email protected] docker]# docker inspect vm2
           
Docker學習(8)——建構鏡像(Dockerfile、commit)
Docker學習(8)——建構鏡像(Dockerfile、commit)

3.進入資料卷位置并編寫釋出檔案并測試

[[email protected] ~]# cd /var/lib/docker/volumes/6494e9585bee0906ca1533af3ada8d35134d2b560b3c454a114b0962604555d5/_data
[[email protected] _data]# ls
[[email protected] _data]# vim index.html
[[email protected] _data]# cat index.html 
snow snow snow
snow snow snow
hello,world
           
Docker學習(8)——建構鏡像(Dockerfile、commit)

隻讀挂載

1.建立挂載目錄

[[email protected] ~]# mkdir -p /tmp/docker/web/
[[email protected] ~]# cd /tmp/docker/web/
[[email protected] web]# vim index.html 
           

2.建立容器,并測試

[[email protected] ~]# docker run -d --name vm2 -v /tmp/docker/web:/data:ro rhel7:v2
[[email protected] ~]# docker inspect vm2
"Source": "/var/lib/docker/volumes/5da320924640e96fc6878df2d50436c532d4166acc31db2e2130624b516b6e9d/_data",
[[email protected] ~]# docker exec -it vm2 bash
bash-4.2# cd data/
bash-4.2# ls
index.html
bash-4.2# rm -rf index.html 
rm: cannot remove 'index.html': Read-only file system			##隻讀
bash-4.2# 
bash-4.2# cat index.html 
snow snow snow
snow snow snow
snow snow snow
snow snow snow
bash-4.2# 
           
Docker學習(8)——建構鏡像(Dockerfile、commit)