• docker commit其实是干了这些事情?



    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,就可控,可追踪每个层的变化及导致变化的原因。

     

    4、你要小心啦!

     

    如果是通过下面的命令运行的容器

    而不是,容器的默认启动命令

    [root@nccztsjb-node-01 ~]# docker run -it 172.20.58.152/middleware/nginx:1.21.4 bash
    root@8f8d7f304b53:/# 

     

    修改文件

     

    root@8f8d7f304b53:/# echo testcommit > commit.file
    root@8f8d7f304b53:/# 
    root@8f8d7f304b53:/# cat commit.file 
    testcommit
    root@8f8d7f304b53:/# 

     

    这个时候commit

     

    [root@nccztsjb-node-01 ~]# docker ps
    CONTAINER ID   IMAGE                                   COMMAND                  CREATED              STATUS              PORTS     NAMES
    8f8d7f304b53   172.20.58.152/middleware/nginx:1.21.4   "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    condescending_antonelli
    [root@nccztsjb-node-01 ~]# docker commit 8f8d7f304b53 commited_nginx:3.0
    sha256:5d0c07c61adb65e094b5e44ad89ff54a119fa184242b3a1dc140c18d1f5f0296
    [root@nccztsjb-node-01 ~]# 

     

    查看镜像,发现启动命令CMD,变成了

     

    [root@nccztsjb-node-01 ~]# docker inspect -f "{{ .Config.Cmd }}" commited_nginx:3.0
    [bash]
    [root@nccztsjb-node-01 ~]# 

     

    而不是默认的

     

    [root@nccztsjb-node-01 ~]# docker inspect -f "{{ .Config.Cmd }}" 172.20.58.152/middleware/nginx:1.21.4
    [nginx -g daemon off;]
    [root@nccztsjb-node-01 ~]# 

     

    这个要十分的注意!

     

  • 相关阅读:
    数值的整数次方
    二进制中1的个数
    SpingBoot 启动自动给MongoDB建库
    Java 依赖冲突的解决办法
    Http协议
    你被限流了吗?
    LeetCode 783. 二叉搜索树节点最小距离
    Leetcode 687. 最长同值路径
    LeetCode 784. 字母大小写全排列
    LeetCode 面试题 08.06. 汉诺塔问题
  • 原文地址:https://www.cnblogs.com/chuanzhang053/p/16787549.html
Copyright © 2020-2023  润新知