前言
在前面的文章裡我們已經詳細介紹了建構鏡像的兩種常用方式,下面我們将具體看看如何實際操作,以及鏡像的優化方式。
一、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
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
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]:/#
可以看到,重建立立的容器裡沒有之前建立的檔案
那麼問題來了:如果我們得到一個原始的鏡像後,需要往上百台的之機上建構容器并部署相關服務,做好的鏡像沒辦法儲存打包,那将是一件非常痛苦的事情;這個時候我們可以使用commit指令将容器建構成一個新的鏡像
4.commit封裝鏡像
commit建構鏡像三部曲:
- 運作容器
- 修改容器
- 将容器儲存為新的鏡像
我們直接使用上面建構的容器vm1,對它進行修改
使用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
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]:/#
二、編寫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中的打開參數
3.編寫yum.repo(在目前目錄下,也就是放置Dockerfile的目錄中)
4.封裝鏡像,并測試能否正常使用
[[email protected] docker]# docker build -t rhel7:v1 . ##注意指令後有一個點,表示目前目錄下
出現報錯,Dokerfile内容有誤
修改後重試
鏡像建構成功
5.建構容器
[[email protected] docker]# docker run -d --name vm1 rhel7:v1
7fdb6ab9155b8f2afeb44b949107f685192d43f84ac98dfaf2c848565b670f53
查詢IP位址
[[email protected] docker]# docker inspect vm1
書寫預設釋出檔案,導入容器内部
[[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
建構鏡像,并添加資料卷挂載位置(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 -
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
直接在資料卷中編寫釋出檔案
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
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
隻讀挂載
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#