【问题标题】:How can I remotely connect to docker swarm?如何远程连接到 docker swarm?
【发布时间】:2017-10-18 18:49:23
【问题描述】:

是否可以从我的本地 mac 在托管在云中的 docker swarm 集群上执行命令?如果是,怎么做?

我想在本地的 docker swarm 上执行如下命令:

docker create secret my-secret <address to local file>
docker service create --name x --secrets my-secret image

【问题讨论】:

    标签: docker docker-swarm docker-swarm-mode docker-secrets


    【解决方案1】:

    这是在远程 docker 引擎上运行命令的最简单方法:

    docker context create --docker host=ssh://myuser@myremote myremote
    docker --context myremote ps -a
    docker --context myremote create secret my-secret <address to local file>
    docker --context myremote service create --name x --secrets my-secret image
    

    docker --host ssh://myuser@myremote ps -a
    

    您需要使用基于密钥的身份验证才能完成此工作(您应该已经在使用它)。其他选项包括设置基于 tls 证书的套接字或 ssh 隧道。

    【讨论】:

    • 或者更好:export DOCKER_HOST=ssh://myuser@myremote 然后像往常一样使用 docker 命令。
    【解决方案2】:

    问题的答案可以在here找到。

    对于ubuntu机器需要做的是在路径/etc/docker定义daemon.json文件,内容如下:

    {
      "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
    }
    

    上述配置不安全,如果服务器是公开托管的,则不应使用。

    对于安全连接,请使用以下配置:

    {
      "tls": true,
      "tlscert": "/var/docker/server.pem",
      "tlskey": "/var/docker/serverkey.pem",
      "hosts": ["tcp://x.x.x.y:2376", "unix:///var/run/docker.sock"]
    }
    

    生成证书的详细信息可以在@BMitch 提到的here 中找到。

    【讨论】:

      【解决方案3】:

      如果您从头开始,您可以使用generic docker-machine driver 创建管理器节点。之后,您将能够在 docker-machine env 命令的帮助下从本地计算机连接到该 docker 引擎。

      【讨论】:

        【解决方案4】:

        一个选项是提供对 docker 守护程序的直接访问,如前面的答案中所建议的那样,但这需要设置 TLS 证书和密钥,这本身可能很棘手且耗时。当 docker machine 用于创建节点时,Docker machine 可以自动执行该过程。

        我遇到了同样的问题,因为我想在 swarm 上创建秘密而不将包含秘密的文件上传到 swarm 管理器。此外,我希望能够运行部署堆栈文件(例如 docker-compose.yml),而无需先上传堆栈文件。

        我希望能够创建一些我需要的服务器,例如DigitalOcean,不一定使用 docker 机器,并且能够可重复地创建秘密并运行堆栈文件。在 DigitalOcean 和 AWS 等环境中,不使用单独的 TLS 证书集,而是使用本地计算机上的 ssh 密钥通过 ssh 访问远程节点。

        对我有用的解决方案是在 ssh 上使用单独的命令运行 docker 命令,这允许我使用标准输入管道传输秘密和/或堆栈文件。

        为此,您首先需要创建 DigitalOcean 液滴并在其上安装 docker,可能来自自定义映像或快照,或者只需运行命令在每个液滴上安装 docker。然后,将液滴加入一个集群:ssh 进入将成为管理器节点的那个,键入 docker swarm init(如果该节点上有多个 IP,则可能使用 --advertise-addr 选项,例如当你想要保持私有网络上的集群内流量)并取回集群的加入命令。然后ssh 进入其他每个节点并发出 join 命令,你的 swarm 就创建好了。

        然后,导出ssh 命令,您将需要在管理器节点上发出命令,例如

        export SSH_CMD='ssh root@159.89.98.121'
        

        现在,您有几个选择。您可以发出单独的 docker 命令,例如:

        $SSH_CMD docker service ls
        

        您可以在 swarm 上创建一个秘密,而无需将秘密文件复制到 swarm 管理器:

        $SSH_CMD docker create secret my-secret - < /path/to/local/file
        $SSH_CMD docker service create --name x --secrets my-secret image
        

        (使用- 表示docker create secret 应该接受stdin 上的秘密,然后使用ssh 将文件通过管道传输到stdin)

        您还可以创建一个脚本,以便能够以可重复的方式运行命令来创建您的机密,并仅在您的本地计算机上使用机密文件和堆栈文件启动您的堆栈。这样的脚本可能是:

        $SSH_CMD docker secret create rabbitmq.config.01 - < rabbitmq/rabbitmq.config
        $SSH_CMD docker secret create enabled_plugins.01 - < rabbitmq/enabled_plugins
        $SSH_CMD docker secret create rmq_cacert.pem.01 - < rabbitmq/cacert.pem
        $SSH_CMD docker secret create rmq_cert.pem.01 - < rabbitmq/cert.pem
        $SSH_CMD docker secret create rmq_key.pem.01 - < rabbitmq/key.pem
        $SSH_CMD docker stack up -c - rabbitmq_stack < rabbitmq.yml
        

        其中秘密用于证书和密钥,以及配置文件rabbitmq.config和enabled_plugins,堆栈文件是rabbitmq.yml,可以是:

        version: '3.1'
        services:
          rabbitmq:
            image: rabbitmq
            secrets:
              - source: rabbitmq.config.01
                target: /etc/rabbitmq/rabbitmq.config
              - source: enabled_plugins.01
                target: /etc/rabbitmq/enabled_plugins
              - source: rmq_cacert.pem.01
                target: /run/secrets/rmq_cacert.pem
              - source: rmq_cert.pem.01
                target: /run/secrets/rmq_cert.pem
              - source: rmq_key.pem.01
                target: /run/secrets/rmq_key.pem
            ports: 
              # stomp, ssl:
              - 61614:61614
              # amqp, ssl:
              - 5671:5671
              # monitoring, ssl:
              - 15671:15671
              # monitoring, non ssl:
              - 15672:15672
          # nginx here is only to show another service in the stackfile
          nginx:
            image: nginx
            ports: 
              - 80:80
        secrets:
          rabbitmq.config.01:
            external: true
          rmq_cacert.pem.01:
            external: true
          rmq_cert.pem.01:
            external: true
          rmq_key.pem.01:
            external: true
          enabled_plugins.01:
            external: true
        

        (这里,rabbitmq.config 文件为 stomp、amqp 和监控接口设置 ssh 侦听端口,并告诉 rabbitmq 在 /run/secrets 中查找证书和密钥。此特定图像的另一种选择是是使用图像提供的环境变量来指向机密文件,但我想要一个更通用的解决方案,不需要在图像中进行配置)

        现在,如果您想启动另一个 swarm,一旦您设置了 SSH_CMD 环境变量,您的脚本将与该 swarm 一起工作,您既不需要设置 TLS,也不需要将您的秘密或堆栈文件复制到 swarm 文件系统。

        因此,这并不能解决创建 swarm 的问题(它的存在是您的问题的前提),但是一旦创建,使用环境变量(如果您想在脚本中使用它就导出)将允许您几乎完全使用您列出的命令,并以该环境变量为前缀。

        【讨论】:

          【解决方案5】:

          要连接到远程 docker 节点,您应该在 docker 主机和客户端上都设置 TLS,从同一个 CA 签名。请注意限制您使用此 CA 签署的密钥,因为它用于控制对 docker 主机的访问。

          Docker 在此处记录了设置 CA 和创建/安装密钥的步骤:https://docs.docker.com/engine/security/https/

          配置完成后,您可以使用在 docker 主机上本地运行的相同 docker 命令连接到较新的 swarm 模式环境,只需在 shell 中更改 $DOCKER_HOST 的值即可。

          【讨论】:

          • 不设置TLS连接docker daemon是否可行?
          • 不推荐。任何有权访问未加密服务的人(请记住,客户端也将拥有 TLS 密钥)无需密码即可在系统上获得 root 访问权限。