docker - 如何在现有的 docker swarm 中生成交互式容器?
问题描述
注意:我已经尝试以我能想到的任何方式搜索现有答案,但我不相信那里有任何关于如何实现我所追求的信息
语境
我有一个现有的集群在多个主机上运行一堆网络服务。部署是通过docker-compose build && docker stack deploy
. 一些服务包含此堆栈所针对的主要服务的功能所必需的重要状态,包括通过 CLI 与其交互时。
目标
如何在我的 swarm 上运行的现有堆栈中创建一个临时容器,以对我的主要服务进行交互式诊断和故障排除?该服务有一个 CLI 接口,但它需要访问其他组件才能使该 CLI 运行,因此它需要像在内部声明的服务一样运行docker-compose.yml
。要求:
- 我需要以临时方式运行它。这是由操作员进行故障排除的,所以我不知道我什么时候需要它
- 它需要是交互式的,因为它是由人工进行故障排除的
- 它需要能够运行任意图像(通常是为主服务及其 CLI 构建的图像,但有时可能需要通过其他容器进行其他诊断,我不会提前知道)
- 它需要完全访问为堆栈设置的网络和其他资源,就好像它是其中的常规预定义服务一样
到目前为止,我能做的最好的是:
- 查找运行我的服务映像的现有容器
- 通过 SSH 连接到运行它的 swarm 主机
docker exec -ti
进入它以调用 CLI
然而,这有许多缺点:
- 我不想弄乱一个已经在运行的容器,它有一项重要的工作,我不想意外中断,而且它的状态可能与我需要做的事情无关,我不想破坏它
- 它依赖于安装了 CLI 的服务映像。如果我想将两者分开,我就不走运了
- 它依赖于一些已经在运行的容器。如果我的服务完全关闭并处于重新启动循环中,我将完全被淹没,因为我无处可执行和运行我的 CLI
- 我只能在我已经声明和运行的上下文中执行。如果我需要事先没有想到要添加的东西,很遗憾我很不走运
- 找到运行容器的特定主机并手动去那里真的很烦人
我真正想要的是一个版本,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 run 并通过诊断容器连接到网络:-
docker -c manager run --rm --network <stack>_default -it nicolaka/netshoot
选项 3
第三个选项没有解决直接访问运行服务的节点的需要,也没有解决运行服务实例的需要,但它确实允许您在不影响其状态且不需要工具的情况下调查服务在容器中。
首先执行常用命令以发现感兴趣的服务任务的节点和容器名称和 id:
docker service ps ${service} --no-trunc --format '{{.Node}} {{.Name}}.{{.ID}}' --filter desired-state=running
然后,假设您有 docker 上下文来匹配您的节点名称: - 从 {{.Node}}、{{.Name}}.{{.ID}} 和运行 ubuntu 或 netshoot 等容器,将其附加到目标容器的网络命名空间。
docker -c ${node} run --rm -it --network container:${container} nicolaka/netshoot
此容器可用于在正在运行的服务任务的上下文中执行诊断,然后在不影响它的情况下关闭它。
推荐阅读
- python - 拆分并打印 *n 行的 \ 前后的单词,从一个 txt 到两个不同的 txt
- kubernetes - 如何找到所有带有包含某个单词的标签的 k8s 对象?
- windows - 运行“VS 2019 的开发人员命令提示符”时出现多个“系统找不到指定的路径”消息
- javascript - 如何替换部分json字符串
- javascript - 如何使用 UTF-8 到 jsPDF - autotable
- python - Python API调用未写入文件
- json - 如何让杰克逊读取这个无效的 JSON?
- php - 反转列表项顺序的最佳方法
- c# - XmlSerializer 缺少一个元素
- sql - 为什么它不能像使用绝对数字“风速”那样使用平均值?