首页 > 解决方案 > 如何在现有的 docker swarm 中生成交互式容器?

问题描述

注意:我已经尝试以我能想到的任何方式搜索现有答案,但我不相信那里有任何关于如何实现我所追求的信息

语境

我有一个现有的集群在多个主机上运行一堆网络服务。部署是通过docker-compose build && docker stack deploy. 一些服务包含此堆栈所针对的主要服务的功能所必需的重要状态,包括通过 CLI 与其交互时。

目标

如何在我的 swarm 上运行的现有堆栈中创建一个临时容器,以对我的主要服务进行交互式诊断和故障排除?该服务有一个 CLI 接口,但它需要访问其他组件才能使该 CLI 运行,因此它需要像在内部声明的服务一样运行docker-compose.yml。要求:

到目前为止,我能做的最好的是:

  1. 查找运行我的服务映像的现有容器
  2. 通过 SSH 连接到运行它的 swarm 主机
  3. docker exec -ti进入它以调用 CLI

然而,这有许多缺点:

我真正想要的是一个版本,docker run我可以指向堆栈并说“在那里运行”,或者docker stack run,但我找不到任何类似的东西。这样做的正确方法是什么?

标签: dockerdocker-composedocker-swarmdocker-stack

解决方案


选项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

此容器可用于在正在运行的服务任务的上下文中执行诊断,然后在不影响它的情况下关闭它。


推荐阅读