正在复制用于调试的docker容器



我有一个正在运行的docker容器。我在正在运行的docker容器中做了一些有用的工作。我做的这些工作不是码头文件的一部分,我是在集装箱里做的。[例如:我在容器内安装了ping,而不是从docker文件]

现在,我被困在一个地方。我不确定我是否在同一个容器中调试,我可能会在该容器中丢失迄今为止所做的事情。

因此,我想用运行容器中的所有可用内容创建一个重复的副本[就像我不想从映像构建容器,重复运行容器中实现的所有成功步骤,然后开始调试。我不想在第二个容器中重新安装ping]。

完全,我怎样才能复制一个容器?如果没有,所有的可能性是什么?

  1. 创建一个基本映像并运行

    docker run -it <base_image> /bin/bash
    
  2. 进行必要的更改

    yum install ping
    
  3. 使用新名称提交

    docker commit <hash tag of running container> new_image
    

现在,如果您通过运行打开new_image

docker run -it new_image /bin/bash

你可以看到ping安装在里面

打开base_image,但其中没有安装ping

希望它能回答你的问题。

如果您想保存您的修改,可以使用docker commit,请参阅文档http://docs.docker.com/reference/commandline/cli/#commit你也可以保存一个容器,http://docs.docker.com/reference/commandline/cli/#save

当前再次断开

以下仅适用于2017年12月20日左右的版本。1月18日之后,我还没有对此进行调查。

docker commit可以将文件更改保存到新图像中,但它不会保留内存、打开进程等中的更改。与流行的观点相反,后者在docker checkpoint中是可行的。文档和示例。

注意:现在,--checkpoint-dir选项已断开:issue,pull。这就是为什么像checkpoint_dir(参见代码)这样的变通方法在这里是必要的。这个答案可能会在几周后更新。

无法检查TTY。这种情况可能很快就会改变。但是,您可以使用exec在恢复过程之后附加一个新的TTY

你需要安装criu。在之后

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无法以本机方式创建X11应用程序的蓝图。

CCD_ 12仅在内部冻结容器。对于一个暂停的容器,除了取消暂停之外,你什么都做不了。

从docker实现1.0.1(Server/client API 1.12)开始,只支持暂停/恢复操作。

但就进程的快照(提交+推送)而言,这些不起作用(不支持,尽管我没有查看文档)

总之,1) 无法保持正在运行的进程的状态!2) 对文件系统(持久存储)所做的所有更改都可以保存(并且可以提交+推送到存储库)。

如果你有一个容器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

最新更新