将Docker容器更改提交到新映像
总览
Docker容器是短暂的,这意味着不会保留对正在运行的容器的更改。通常,建议继续使用Dockerfile生成映像,因为我们要确保基于映像的所有新容器都存在特定状态。但是,当我们需要修改运行中的Docker容器并保留这些更改时会发生什么?
在某些情况下,可能需要将更改从容器提交到新映像。一个示例是调试现有的容器,我们需要在其中修复错误或者错误的配置。
另一种情况可能是调查问题,我们需要准确确定正在运行的容器的状态。例如,检测到入侵,我们需要保留运行中的容器以对其进行彻底检查。
现在已经包含了该容器,我们需要对其进行分析,但是,容器的短暂特性意味着我们还应该立即更换运行中的容器。通过将损坏的容器提交到新映像,可以在安全的沙箱环境中对其进行调查,同时可以立即部署替换容器以消除任何损坏或者有效载荷。
Docker提交
引入了Docker commit命令以提供一种提交容器更改的机制。
如前所述,Docker commit可以创建容器的镜像。当图像中需要修补程序时,它可以修改指令,例如CMD或者ENV。
Docker层以及提交方式
Docker映像以及容器固有地由多层组成,每一层是一个单独的文件系统,彼此堆叠。
每个Dockerfile指令都会创建一个新层,并为其赋予唯一的哈希值,然后将其堆叠在下一个指令集的顶部。层实际上作为主机服务器上的目录存在,其哈希值用作名称。
执行Docker commit时,新创建的映像将引用原始映像使用的所有未更改的层,然后将临时层复制到永久存储中。
提交现有容器
要将更改从容器提交到新映像,请使用docker commit命令并指定源容器ID。
我们要提交的容器可以正在运行或者停止,该命令将以任何一种方式起作用。
docker commit <container id> <image-name>:<version>
例如,我们有一个在Docker主机上运行的Python Flask API。它已经运行了7天,并且出于审核原因需要返回。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 13c6e55583a5 theitroad/flask-api "python main.py" 7 days ago Up 7 days 0.0.0.0:5000->5000/tcp dreamy_grothendieck
要将容器提交到映像,我们将使用以下命令。
docker commit 13c6e55583a5 theitroad/flask-api-audit:20190612
将输出一个新的哈希,并将其分配给新创建的图像。
sha256:dcbb3c4f74fa5857bea801b27477fa54a92df4db2c59d95cc8e6eabf64a241f4
当我们使用docker image命令列出Docker映像时,可以看到我们新创建的映像。
储藏标签图像ID尺寸增加
theitroad / flask-api-audit 20190612 dcbb3c4f74fa大约一分钟前464MB
修改ENV指令
要更改Docker映像指令,例如在需要调整环境变量时更改ENV,请在docker commit中使用change标志。
例如,如果要更改用于设置容器环境的环境变量的ENV指令,则可以使用以下命令。
docker commit --change='ENV environment production' dcbb3c4 theitroad/flask-api:1.0.1
修改CMD指令
像上面的ENV指令一样,我们使用change标志来调整CMD指令。
例如,如果我们错误地直接使用Python而不是uwsgi服务器来运行Python Flask API,我们将运行以下命令。
docker commit --change='CMD ["uwsgi", "--ini", "myproject.ini"] dcbb3c4 theitroad/flask-api:1.0.2
修改多条指令
如果需要,使用commit命令可以修改多个指令。可以将带有指令更改的其他-c标志添加到命令中。
例如,要调整CMD指令和EXPOSE指令,可以使用以下命令。
docker commit --change='CMD ["uwsgi", "--ini", "myproject.ini"]' -c "EXPOSE 80" dcbb3c4 theitroad/flask-api:1.0.2