使用docker commit将修改后的容器保存为镜像及其使用注意事项
docker commit使用示例
我們修改了容器的文件,也就是改動了容器的存儲層。我們可以通過 docker diff 命令看到具體的改動。
$ docker diff webserver C /root A /root/.bash_history C /run C /usr C /usr/share C /usr/share/nginx C /usr/share/nginx/html C /usr/share/nginx/html/index.html C /var C /var/cache C /var/cache/nginx A /var/cache/nginx/client_temp A /var/cache/nginx/fastcgi_temp A /var/cache/nginx/proxy_temp A /var/cache/nginx/scgi_temp A /var/cache/nginx/uwsgi_temp現在我們定制好了變化,我們希望能將其保存下來形成鏡像。
要知道,當我們運行一個容器的時候(如果不使用卷的話),我們做的任何文件修改都會被記錄于容器存儲層里。而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保存下來成為鏡像。換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,并構成新的鏡像。以后我們運行這個新鏡像的時候,就會擁有原有容器最后的文件變化。
docker commit 的語法格式為:
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標簽>]]我們可以用下面的命令將容器保存為鏡像:
$ docker commit \--author "Tao Wang <twang2218@gmail.com>" \--message "修改了默認網頁" \webserver \nginx:v2 sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214其中 --author 是指定修改的作者,而 --message 則是記錄本次修改的內容。這點和 git 版本控制相似,不過這里這些信息可以省略留空。
我們可以在 docker image ls 中看到這個新定制的鏡像:
$ docker image ls nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx v2 07e334659748 9 seconds ago 181.5 MB nginx 1.11 05a60462f8ba 12 days ago 181.5 MB nginx latest e43d811ce2f4 4 weeks ago 181.5 MB我們還可以用 docker history 具體查看鏡像內的歷史記錄,如果比較 nginx:latest 的歷史記錄,我們會發現新增了我們剛剛提交的這一層。
$ docker history nginx:v2 IMAGE CREATED CREATED BY SIZE COMMENT 07e334659748 54 seconds ago nginx -g daemon off; 95 B 修改了默認網頁 e43d811ce2f4 4 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon 0 B <missing> 4 weeks ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0 B <missing> 4 weeks ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx/ 22 B <missing> 4 weeks ago /bin/sh -c apt-key adv --keyserver hkp://pgp. 58.46 MB <missing> 4 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.11.5-1 0 B <missing> 4 weeks ago /bin/sh -c #(nop) MAINTAINER NGINX Docker Ma 0 B <missing> 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:23aa4f893e3288698c 123 MB新的鏡像定制好后,我們可以來運行這個鏡像。
docker run --name web2 -d -p 81:80 nginx:v2這里我們命名為新的服務為 web2,并且映射到 81 端口。訪問 http://localhost:81 看到結果,其內容應該和之前修改后的 webserver 一樣。
至此,我們第一次完成了定制鏡像,使用的是 docker commit 命令,手動操作給舊的鏡像添加了新的一層,形成新的鏡像,對鏡像多層存儲應該有了更直觀的感覺。
慎用 docker commit
使用 docker commit 命令雖然可以比較直觀的幫助理解鏡像分層存儲的概念,但是實際環境中并不會這樣使用。
首先,如果仔細觀察之前的 docker diff webserver 的結果,你會發現除了真正想要修改的 /usr/share/nginx/html/index.html 文件外,由于命令的執行,還有很多文件被改動或添加了。這還僅僅是最簡單的操作,如果是安裝軟件包、編譯構建,那會有大量的無關內容被添加進來,將會導致鏡像極為臃腫。
此外,使用 docker commit 意味著所有對鏡像的操作都是黑箱操作,生成的鏡像也被稱為 黑箱鏡像,換句話說,就是除了制作鏡像的人知道執行過什么命令、怎么生成的鏡像,別人根本無從得知。而且,即使是這個制作鏡像的人,過一段時間后也無法記清具體的操作。這種黑箱鏡像的維護工作是非常痛苦的。
而且,回顧之前提及的鏡像所使用的分層存儲的概念,除當前層外,之前的每一層都是不會發生改變的,換句話說,任何修改的結果僅僅是在當前層進行標記、添加、修改,而不會改動上一層。如果使用 docker commit 制作鏡像,以及后期修改的話,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西并不會丟失,會一直如影隨形的跟著這個鏡像,即使根本無法訪問到。這會讓鏡像更加臃腫。
參考鏈接:https://www.kancloud.cn/docker_practice/docker_practice/469784
總結
以上是生活随笔為你收集整理的使用docker commit将修改后的容器保存为镜像及其使用注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux /bin/sh -c的用途
- 下一篇: linux sed命令:查看gitlab