【发布时间】:2015-11-27 22:56:28
【问题描述】:
我想用不同的命令启动一个停止的 Docker 容器,因为默认命令会崩溃——这意味着我无法启动容器然后使用“docker exec”。
基本上我想启动一个 shell,以便检查容器的内容。
幸运的是,我使用 -it 选项创建了容器!
【问题讨论】:
标签: docker
我想用不同的命令启动一个停止的 Docker 容器,因为默认命令会崩溃——这意味着我无法启动容器然后使用“docker exec”。
基本上我想启动一个 shell,以便检查容器的内容。
幸运的是,我使用 -it 选项创建了容器!
【问题讨论】:
标签: docker
docker ps -a
此命令将修改后的容器状态保存到新图像user/test_image
docker commit $CONTAINER_ID user/test_image
docker run -ti --entrypoint=sh user/test_image
入口点参数说明:https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime
上面的步骤只是启动一个具有相同文件系统状态的已停止容器。这非常适合快速调查。但是环境变量、网络配置、附加卷和其他人员不是继承的,您应该明确指定所有这些参数。
已从此处借用启动已停止容器的步骤:(最后一条评论)https://github.com/docker/docker/issues/18078
【讨论】:
inspect 输出转换为用于后续运行的配置?
编辑此文件(对应于您停止的容器):
vi /var/lib/docker/containers/923...4f6/config.json
更改“路径”参数以指向您的新命令,例如/bin/bash。您还可以设置“Args”参数以将参数传递给命令。
重启 docker 服务(注意这会停止所有正在运行的容器):
service docker restart
列出您的容器并确保命令已更改:
docker ps -a
启动容器并附加到它,你现在应该在你的 shell 中!
docker start -ai mad_brattain
使用 Docker 1.7.1 在 Fedora 22 上工作。
注意:如果您的 shell 不是交互式的(例如,您没有使用 -it 选项创建原始容器),您可以将命令改为“/bin/sleep 600”或“/ bin/tail -f /dev/null" 给你足够的时间来做 "docker exec -it CONTID /bin/bash" 作为获取 shell 的另一种方式。
注意 2: 较新版本的 docker 有 config.v2.json,您需要在其中更改 Entrypoint 或 Cmd(感谢 user60561)。
【讨论】:
..."Path":"tail","Args":["-f","/dev/null"]... 上取得了成功
config.v2.json,您需要在其中更改 Entrypoint 或 Cmd。
Docker 确实需要将此作为一项新功能来实现,但这里有另一个解决方法选项,适用于您的入口点在成功或失败后终止的情况,这会使调试变得困难。
如果您还没有入口点脚本,请创建一个运行容器所需的任何命令的脚本。然后,在该文件的顶部,将这些行添加到entrypoint.sh:
# Run once, hold otherwise
if [ -f "already_ran" ]; then
echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
cat
fi
touch already_ran
# Do your main things down here
为确保cat 保持连接,您可能需要提供 TTY。我正在使用我的入口点脚本运行容器,如下所示:
docker run -t --entrypoint entrypoint.sh image_name
这将导致脚本运行一次,创建一个表明它已经运行的文件(在容器的虚拟文件系统中)。然后可以重启容器进行调试:
docker start container_name
当您重新启动容器时,将找到 already_ran 文件,从而导致入口点脚本与 cat 一起停止(它只是永远等待永远不会出现的输入,但使容器保持活动状态)。然后您可以执行调试bash 会话:
docker exec -i container_name bash
在容器运行时,如果需要以这种方式进行调试,您还可以删除 already_ran 并手动执行 entrypoint.sh 脚本重新运行它。
【讨论】:
/bin/sh 而不是cat——然后您总是可以在重新启动时进入。您的解决方案非常棒!
cat 和 /bin/sh 并没有为我停止执行,我最终无限期地循环/休眠。 while : do sleep 3600 done
我接受了@Dmitriusan 的回答并将其设为别名:
别名 docker-run-prev-container='prev_container_id="$(docker ps -aq | head -n1)" && docker commit "$prev_container_id" "prev_container/$prev_container_id" && docker run -it --entrypoint= bash "prev_container/$prev_container_id"'
将此添加到您的 ~/.bashrc 别名文件中,您将拥有一个漂亮的新 docker-run-prev-container 别名,它会将您放入前一个容器中的外壳中。
帮助调试失败docker builds.
【讨论】:
我的问题:
docker run <IMAGE_NAME> 启动了一个容器
docker ps -a 时,我可以看到两个容器。 docker run <IMAGE_NAME> 命令时,都会创建新图像解决方案: 要在您首先创建的同一个容器上运行,请按照以下步骤操作
docker ps 获取容器的容器docker container start <CONTAINER_ID> 启动现有容器docker exec -it <CONTAINER_ID> /bin/bash
【讨论】:
docker run <containerID> 中使用的参数不同
这并不完全符合您的要求,但如果您只想检查文件,则可以在已停止的容器上使用 docker export。
mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR
【讨论】:
我找到了一个简单的命令
docker start -a [container_name]
这样就可以了
或者
docker start [container_name]
然后
docker exec -it [container_name] bash
【讨论】:
docker exec 不会让容器保持活动状态。
docker-compose run --entrypoint /bin/bash cont_id_or_name
(对于 conven,将您的 env、vol 挂载在 docker-compose.yml 中)
或使用 docker run 并手动指定所有参数
【讨论】:
对我来说,Docker 总是给人一种它是为一个爱好系统创建的印象,它很适合这个。
如果某些事情失败或不起作用,不要指望有专业的解决方案。
也就是说:Docker 不仅不支持这些基本的管理任务,它还试图阻止它们。
解决方案:
cd /var/lib/docker/overlay2/
find | grep somechangedfile
# You now can see the changed file from your container in a hexcoded folder/diff
cd hexcoded-folder/diff
创建一个entrypoint.sh(如果存在,请确保备份一个现有的)
cat > entrypoint.sh
#!/bin/bash
while ((1)); do sleep 1; done;
Ctrl+C
chmod +x entrypoint.sh
docker stop
docker start
你现在让你的 docker 容器运行一个无限循环而不是原来的条目,你可以执行 bash 进入它,或者做任何你需要的事情。 完成后停止容器,删除/重命名您的自定义入口点。
【讨论】:
似乎 docker 在容器启动后无法更改入口点。但是你可以设置一个自定义入口点,下次重启时修改入口点的代码。
例如,您运行这样的容器:
docker run --name c --entrypoint "/boot" -v "./boot":/boot $image
这里是启动入口点:
#!/bin/bash
command_a
当您需要使用不同的命令重新启动 c 时,您只需更改启动脚本:
#!/bin/bash
command_b
然后重启:
docker restart c
【讨论】:
我有一个 docker 容器,其中 MariaDB 容器在启动时由于 InnoDB 表损坏而不断崩溃。
我为解决我的问题所做的是:
【讨论】: