我有一个正在运行的docker容器。我在运行的docker容器中做了一些有用的工作。我做过这些工作不是dockerfile的一部分,我已经在容器内完成了。[例如:我在容器内安装了ping,而不是在docker文件中安装]
现在,我被困在一个地方。我不确定我是否在同一个容器中进行调试,我可能会松开到目前为止我在容器内所做的事情。
所以我想用正在运行的容器中的所有可用东西创建它的副本[就像我不想从图像构建容器并重复在运行容器中实现的所有成功步骤然后开始我的调试。我不想在我的第二个容器中重新安装ping。
总的来说,我如何复制容器?如果不是所有的可能性?
答案 0 :(得分:49)
创建基本图像并运行它
docker run -it <base_image> /bin/bash
进行必要的更改
yum install ping
使用新名称
提交docker commit <hash tag of running container> new_image
现在,如果你通过运行
打开new_imagedocker run -it new_image /bin/bash
您可以看到ping
已安装在其中。
打开base_image,其中没有安装ping
。
希望它能回答你的问题。
答案 1 :(得分:3)
如果您想保存修改,可以使用docker commit
,查看文档http://docs.docker.com/reference/commandline/cli/#commit,还可以保存容器http://docs.docker.com/reference/commandline/cli/#save
答案 2 :(得分:2)
以下仅适用于17年12月20日左右的版本。我在1月18日之后还没有调查过这个问题。
docker commit
适用于将文件更改保存到新图像中,但它不会保留内存,打开进程等的更改。与流行的观点相反,后者对于docker checkpoint
是可行的。 Documentation和example。
注意:现在,--checkpoint-dir
选项已损坏:issue,pull。这就是为什么需要checkpoint_dir
(参见代码)这样的解决方法。这个答案可能会在几周后更新。
检查TTY是not possible。这很快might change。但是,您可以使用exec在恢复过程后附加新的TTY 。
你need to have criu installed。之后,首先,
echo "{\"experimental\": true}" >> /etc/docker/daemon.json
systemctl restart docker
,然后
#!/bin/bash
# tty (-t) not supported
docker run -i -d --name sleeper\
busybox sh -c 'sleep 10000'
# Makes a snapshot and stops the container (except if --leave-running is active). --checkpoint-dir is broken.
docker checkpoint create sleeper cp
# sleeper container exited
# Create the clone
docker create -i --rm --name clone\
busybox
# Start the clone
checkpoint_dir="/var/lib/docker/containers/$(docker ps -aq --no-trunc -f name=sleeper)/checkpoints"
docker start --checkpoint-dir=$checkpoint_dir --checkpoint=cp clone
# Attach new TTY
docker exec -it clone sh
现在在tty中输入ps -e
,您将看到从sleeper
容器中开始的流程,现在继续在clone
。
checkpoint
为硬盘提供了一个完整的容器蓝图,可以在机器之间进行交换。此功能使用criu并且是实验性的。 Criu本身不能create a blueprint of X11申请。
pause
仅在内部冻结容器。暂停容器除了取消暂停之外没有什么可以做的。
答案 3 :(得分:1)
自Docker实现1.0.1(服务器/客户端API 1.12)起,只支持暂停/恢复操作。
但就进程快照(提交+推送)而言,这些不起作用(不支持,但我没有检查文档)
总之, 1)不可能保持运行进程的状态! 2)可以保存对文件系统(持久存储)所做的所有更改(并且可以提交+推送到存储库)。
答案 4 :(得分:0)
如果您有一个容器my-cont
并且想要对其进行调试,则无需在其中安装调试工具。相反,您可以做的是使用调试映像中的另一个容器,例如xyz_docker_img
然后让它与my-cont
容器共享相同的名称空间,并具有调试所需的额外功能。
$ docker run -it \
--pid=container:my-cont
--net:container:my-cont
--cap-add NET_RAW
--cap-add NET_ADMIN
--cap-add SYS_PTRACE
xyz_docker_image bash