0、导读
如果我问你,docker commit是干什么的,你或许可以立马告诉我,docker commit是将一个正在运行的容器制作成镜像
没错,说的很对,但是·······docker commit到底是将容器的哪些东西制作成镜像?
你是不是就有些迟疑了呢,如果是的话,接下的部分,你要仔细的看,最好跟着一起实验。
1、docker commit的作用
非常简单:就是基于容器的变化,创建一个新的镜像。
哪些变化?
- 文件的变化
- 设置的变化
但是,哪些变化不会用来制作镜像?
- 容器中挂载的任何卷中包含的数据
下面的部分,通过示例来展示,到底啥是文件的变化,啥叫设置的变化,卷中的变化又是怎么回事?
2、示例
2.1、查看现有镜像的层数
docker history 172.20.58.152/middleware/nginx:1.21.4
可以看到,这个镜像包括 6 层
2.2、运行这个容器
挂载了数据卷(bind mount)
[root@nccztsjb-node-01 ~]# docker run -d --name nginx -v /root/nginx_data:/data 172.20.58.152/middleware/nginx:1.21.4 2171e355291ca98a5ac9c8659f02a049d1fca7188de8b281cd3cd323ba712cc5 [root@nccztsjb-node-01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2171e355291c 172.20.58.152/middleware/nginx:1.21.4 "/docker-entrypoint.…" 2 seconds ago Up 1 second 80/tcp nginx
2.3、进入容器
做如下的操作:
- 加环境变量
- 增加文件
- 向挂载目录写数据
[root@nccztsjb-node-01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2171e355291c 172.20.58.152/middleware/nginx:1.21.4 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp nginx [root@nccztsjb-node-01 ~]# [root@nccztsjb-node-01 ~]# docker exec -it 2171e355291c bash root@2171e355291c:/# export commit=test root@2171e355291c:/# root@2171e355291c:/# env |grep commit commit=test root@2171e355291c:/# root@2171e355291c:/# root@2171e355291c:/# pwd / root@2171e355291c:/# echo testcommit > commit.file root@2171e355291c:/# cat commit.file testcommit root@2171e355291c:/# root@2171e355291c:/# root@2171e355291c:/# df -h Filesystem Size Used Avail Use% Mounted on overlay 49G 20G 27G 43% / tmpfs 64M 0 64M 0% /dev tmpfs 7.6G 0 7.6G 0% /sys/fs/cgroup shm 64M 0 64M 0% /dev/shm /dev/vda2 49G 20G 27G 43% /data tmpfs 7.6G 0 7.6G 0% /proc/acpi tmpfs 7.6G 0 7.6G 0% /proc/scsi tmpfs 7.6G 0 7.6G 0% /sys/firmware root@2171e355291c:/# cd /data root@2171e355291c:/data# ls root@2171e355291c:/data# echo volumedata > volume.file root@2171e355291c:/data# root@2171e355291c:/data# cat volume.file volumedata root@2171e355291c:/data#
常见的变更的数据都有了,接下来就是提交操作
2.4、commit容器
[root@nccztsjb-node-01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2171e355291c 172.20.58.152/middleware/nginx:1.21.4 "/docker-entrypoint.…" 11 minutes ago Up 11 minutes 80/tcp nginx [root@nccztsjb-node-01 ~]# docker commit nginx commited_nginx:1.0 sha256:27eb39cf4bcaa44ae6b252ea2e0477eccf01b98faaef7c180b1306a3bb7f0567 [root@nccztsjb-node-01 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE commited_nginx 1.0 27eb39cf4bca 7 seconds ago 141MB 172.20.58.152/middleware/nginx <none> 9a8e1ec1235e 10 months ago 309MB 172.20.58.152/middleware/nginx 1.21.4 ea335eea17ab 10 months ago 141MB 172.20.58.152/middleware/nginx <none> 9754879619f2 11 months ago 233MB 172.20.58.152/middleware/redis <none> d4deec2c521c 6 years ago 151MB [root@nccztsjb-node-01 ~]#
2.5、运行提交的镜像
# 没有之前容器中的环境变量 [root@nccztsjb-node-01 ~]# docker run -it --rm commited_nginx:1.0 bash root@d934f7305931:/# env | grep commit root@d934f7305931:/# root@d934f7305931:/# # 修改的文件有 root@d934f7305931:/# ls bin boot commit.file data dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@d934f7305931:/# cat commit.file testcommit # 数据卷挂载点/data有,里面的文件没有 root@d934f7305931:/# df -h Filesystem Size Used Avail Use% Mounted on overlay 49G 20G 27G 43% / tmpfs 64M 0 64M 0% /dev tmpfs 7.6G 0 7.6G 0% /sys/fs/cgroup shm 64M 0 64M 0% /dev/shm /dev/vda2 49G 20G 27G 43% /etc/hosts tmpfs 7.6G 0 7.6G 0% /proc/acpi tmpfs 7.6G 0 7.6G 0% /proc/scsi tmpfs 7.6G 0 7.6G 0% /sys/firmware root@d934f7305931:/# cd /data root@d934f7305931:/data# ls root@d934f7305931:/data# root@d934f7305931:/data# root@d934f7305931:/data#
OK,已经看到,只有文件的变化,进入到新的镜像里面了,环境变量,数据卷都没有。
那要基于容器创建镜像的时候,修改容器的环境变量?启动命令,怎么做?
非常的简单,docker commit 的 --change (-c) 参数
2.6、commit,设置环境变量
docker commit --change "ENV DEBUG=true" --change "ENV DEBUG2=false" nginx commited_nginx:2.0
查看镜像的环境变量
docker inspect -f "{{ .Config.Env }}" commited_nginx:2.0
增加了2个环境变量,每个都用 --change "ENV env=value",这个里面就是dockerfile构建的命令
这样,环境变量就在commit的时候,就进入镜像了。
2.7、commit,设置启动命令
就是和dockerfile中是一样的操作。
--change='CMD ["apachectl", "-DFOREGROUND"]' ,修改CMD
-c "EXPOSE 80",修改暴露的端口号
当然,其他的也是一样的。
注意:不支持RUN命令,否则报错
[root@nccztsjb-node-01 ~]# docker commit --change 'RUN mkdir commit ' nginx commited_nginx:2.0 Error response from daemon: run is not a valid change command [root@nccztsjb-node-01 ~]#
2.8、查看镜像层的变化
commited_nginx:1.0 这个镜像,主要是创建了文件,并且是由运行的容器创建,所以是nginx -g daemon off创建的这个层。
之前的镜像
commited_nginx:2.0,这个镜像是在运行的nginx容器中增加了文件,同时又更新了环境变量。
所以,
- docker commit就是基于运行的容器创建的镜像,主要是对文件的修改的保存。
- 如果要设置环境变量,需要在commIt中使用--change参数
3、为啥不建议commit制作镜像
作为制作镜像的手段没有问题。
测试使用、调试都没有问题。
但是,容器运行时,最上层,产生的数据比较多,会导致镜像变大。这是一个原因。
另外的原因:就是不知道什么操作导致的容器文件状态的变化。
但是······如果使用dockerfile,就可控,可追踪每个层的变化及导致变化的原因。
标签:nginx,2171e355291c,7.6,commit,docker,root,其实 From: https://www.cnblogs.com/chuanzhang053/p/16787549.html