如何在现有 docker 集群中生成交互式容器?
How to spawn an interactive container in an existing docker swarm?
注意:我已经尝试以任何我能想到的方式搜索现有答案,但我认为没有关于如何实现我所追求的目标的任何信息
上下文
我有一个现有的 swarm 运行 跨多个主机的一堆网络服务。部署是通过 docker-compose build && docker stack deploy
完成的。一些服务包含此堆栈所针对的主要服务运行所必需的重要状态,包括通过 CLI 与其交互时。
目标
如何在我的 swarm 上的现有堆栈 运行ning 中创建临时容器 以对我的主要服务进行交互式诊断和故障排除?该服务有一个 CLI 接口,但它需要访问其他组件才能使该 CLI 运行,因此它需要 运行 就像它是在 docker-compose.yml
内声明的服务一样。要求:
- 我需要以临时方式 运行 它。这是为了让操作员进行故障排除,所以我不知道我什么时候需要它
- 它需要交互,因为它是由人工进行故障排除
- 它需要能够 运行 任意图像(通常是为主要服务及其 CLI 构建的图像,但有时可能需要通过其他容器进行其他诊断,我不会提前知道)
- 它需要完全访问网络和为堆栈设置的其他资源,就好像它是其中的常规预定义服务一样
到目前为止我能做的最好的是:
- 查找现有容器运行使用我的服务映像
- 通过 SSH 连接到 运行ning
所在的 swarm 主机
docker exec -ti
进入其中以调用 CLI
但这有一些缺点:
- 我不想弄乱已经 运行ning 的容器,它有一项重要的工作,我不想不小心打断它,而且它的状态可能与我需要做的事情无关而且我不想破坏它
- 它依赖于同样安装了 CLI 的服务镜像。如果我想把两者分开,我运气不好
- 它已经 运行 依赖 一些 容器。如果我的服务完全停止运行并处于重启循环中,我将完全崩溃,因为我无处可执行,运行 我的 CLI
- 我只能在我已经声明和 运行ning 的上下文中执行。如果我需要一些我事先没有想过要添加的东西,很遗憾我运气不好
- 找到容器所在的特定主机 运行ning 并手动去那里真的很烦人
我真正想要的是 docker run
的一个版本,我可以指向堆栈并说“那里有 运行”,或者 docker stack run
,但我做不到找到任何类似的东西。这样做的正确方法是什么?
选项 1
将诊断服务部署为堆栈的一部分 - 一个包含有用工具的容器,入口点为 tail -f /dev/null
- 使用放置约束将其部署到已知节点。
services:
diagnostics:
image: nicolaka/netshoot
command: tail -f /dev/null
deploy:
placement:
constraints:
- node.hostname == host1
注意。您不必使用普通堆栈部署此服务。它可以在单独的 stack.yml 文件中。您可以稍后将此文件stack deploy
简单地添加到您的堆栈中,只要不使用--prune
,服务就会累积。
选项 2
要允许常规容器访问您的服务 - 使您的网络可连接。如果您没有明确指定网络,您可以直接明确声明默认网络。
networks:
default:
driver: overlay
attachable: true
现在您可以使用 docker 运行 并使用诊断容器连接到网络 :-
docker -c manager run --rm --network <stack>_default -it nicolaka/netshoot
选项 3
第三个选项没有解决直接访问节点 运行ning 服务的需要,也没有解决拥有服务实例 运行ning 的需要,但是它确实允许您在不影响其状态且不需要容器中的工具的情况下调查服务。
首先执行常用命令来发现感兴趣的服务任务的节点和容器名称和 ID:
docker service ps ${service} --no-trunc --format '{{.Node}} {{.Name}}.{{.ID}}' --filter desired-state=running
然后,假设您有 docker 个上下文来匹配您的节点名称:- 从 {{.Node}}、{{.Name} 的列表中选择一个 ${node}、${container} }.{{.ID}} 和 运行 容器,例如 ubuntu 或 netshoot,将其附加到目标容器的网络命名空间。
docker -c ${node} run --rm -it --network container:${container} nicolaka/netshoot
此容器可用于在 运行ning 服务任务的上下文中执行诊断,然后在不影响它的情况下关闭。
注意:我已经尝试以任何我能想到的方式搜索现有答案,但我认为没有关于如何实现我所追求的目标的任何信息
上下文
我有一个现有的 swarm 运行 跨多个主机的一堆网络服务。部署是通过 docker-compose build && docker stack deploy
完成的。一些服务包含此堆栈所针对的主要服务运行所必需的重要状态,包括通过 CLI 与其交互时。
目标
如何在我的 swarm 上的现有堆栈 运行ning 中创建临时容器 以对我的主要服务进行交互式诊断和故障排除?该服务有一个 CLI 接口,但它需要访问其他组件才能使该 CLI 运行,因此它需要 运行 就像它是在 docker-compose.yml
内声明的服务一样。要求:
- 我需要以临时方式 运行 它。这是为了让操作员进行故障排除,所以我不知道我什么时候需要它
- 它需要交互,因为它是由人工进行故障排除
- 它需要能够 运行 任意图像(通常是为主要服务及其 CLI 构建的图像,但有时可能需要通过其他容器进行其他诊断,我不会提前知道)
- 它需要完全访问网络和为堆栈设置的其他资源,就好像它是其中的常规预定义服务一样
到目前为止我能做的最好的是:
- 查找现有容器运行使用我的服务映像
- 通过 SSH 连接到 运行ning 所在的 swarm 主机
docker exec -ti
进入其中以调用 CLI
但这有一些缺点:
- 我不想弄乱已经 运行ning 的容器,它有一项重要的工作,我不想不小心打断它,而且它的状态可能与我需要做的事情无关而且我不想破坏它
- 它依赖于同样安装了 CLI 的服务镜像。如果我想把两者分开,我运气不好
- 它已经 运行 依赖 一些 容器。如果我的服务完全停止运行并处于重启循环中,我将完全崩溃,因为我无处可执行,运行 我的 CLI
- 我只能在我已经声明和 运行ning 的上下文中执行。如果我需要一些我事先没有想过要添加的东西,很遗憾我运气不好
- 找到容器所在的特定主机 运行ning 并手动去那里真的很烦人
我真正想要的是 docker run
的一个版本,我可以指向堆栈并说“那里有 运行”,或者 docker stack run
,但我做不到找到任何类似的东西。这样做的正确方法是什么?
选项 1
将诊断服务部署为堆栈的一部分 - 一个包含有用工具的容器,入口点为 tail -f /dev/null
- 使用放置约束将其部署到已知节点。
services:
diagnostics:
image: nicolaka/netshoot
command: tail -f /dev/null
deploy:
placement:
constraints:
- node.hostname == host1
注意。您不必使用普通堆栈部署此服务。它可以在单独的 stack.yml 文件中。您可以稍后将此文件stack deploy
简单地添加到您的堆栈中,只要不使用--prune
,服务就会累积。
选项 2
要允许常规容器访问您的服务 - 使您的网络可连接。如果您没有明确指定网络,您可以直接明确声明默认网络。
networks:
default:
driver: overlay
attachable: true
现在您可以使用 docker 运行 并使用诊断容器连接到网络 :-
docker -c manager run --rm --network <stack>_default -it nicolaka/netshoot
选项 3
第三个选项没有解决直接访问节点 运行ning 服务的需要,也没有解决拥有服务实例 运行ning 的需要,但是它确实允许您在不影响其状态且不需要容器中的工具的情况下调查服务。
首先执行常用命令来发现感兴趣的服务任务的节点和容器名称和 ID:
docker service ps ${service} --no-trunc --format '{{.Node}} {{.Name}}.{{.ID}}' --filter desired-state=running
然后,假设您有 docker 个上下文来匹配您的节点名称:- 从 {{.Node}}、{{.Name} 的列表中选择一个 ${node}、${container} }.{{.ID}} 和 运行 容器,例如 ubuntu 或 netshoot,将其附加到目标容器的网络命名空间。
docker -c ${node} run --rm -it --network container:${container} nicolaka/netshoot
此容器可用于在 运行ning 服务任务的上下文中执行诊断,然后在不影响它的情况下关闭。