如何使用 Terraform 将 docker 群管理器令牌传递给 AWS 中的工作节点

How to pass docker swarm manager token to worker nodes in AWS using Terraform

我正在尝试使用 Terraform 创建一个 Docker Swarm 集群,我创建了 1 个管理节点和 3 个工作节点。我安装了 Docker 并启动了 Docker Swarm 并创建了管理器令牌。

如何将密钥从我的管理器转发到工作节点、AWS 中的所有服务器 运行,以及 运行 我本地计算机上的 terrafrom apply 命令?

我有多项限制,因为我不能为这个特定任务请求新服务。

抱歉没有提到,我必须使用动态 IP,因为整个环境都是使用动态 IP 构建的,没有 IP 锁定到任何特定资源。

Swarm 管理器需要一种在初始化后将工人令牌传递给工人的方法。最好的方法是让 swarm manager 的 userdata 触发器生成令牌并将其放入他们都可以访问的共享存储中。在 AWS 中,最简单的做法是使用 AWS SSM Parameter Store,它允许您存储较小的字符串,可选择加密并由普通 IAM 权限支持。

您需要通过 IAM 实例配置文件授予 swarm 管理器实例权限,以便将令牌写入 /swarm/token/worker 之类的内容,然后允许 worker 实例读取相同令牌的权限。

然后在您的经理的用户数据脚本中,您需要如下内容:

WORKER_TOKEN=$(docker swarm join-token worker)
aws ssm put-parameter --region us-west-2 --name '/swarm/token/worker' --type SecureString --value "${WORKER_TOKEN}"

在您的工作人员的用户数据脚本中,您希望进行等效的读取和执行:

WORKER_TOKEN=$(aws ssm get-parameter --region us-west-2 --name '/swarm/token/worker' --with-decryption --query 'Parameter.Value' --output text)
eval "${WORKER_TOKEN}"

还有一个 community module that has an example of how to run Docker Swarm on AWS 依赖于将秘密令牌放入 S3,然后使用用户数据脚本在工作节点上检索它。这可能会为您提供更多关于如何在 AWS 上很好地获得 Swarm 集群的提示。运行。

我通过以下步骤解决了这个问题:

  • AWS.
  • 主节点的静态 ip
  • 我在 nodejs 中创建了在主服务器上运行的简单 api rest 应用程序。此 api 接受来自其他节点的请求和 returns 令牌密钥。

这是我使用的基本代码:

const { exec } = require("child_process");

    const execFunction = (command, res, returnOutput) => {
        exec(command, (error, stdout, stderr) => {
            if (stdout) {
                returnOutput ? res.status(200).send(stdout) : res.sendStatus(204);
            }
            else if (stderr) {
                res.status(400).send({ error: stderr });
            }
            else if (error !== null) {
                res.status(400).send({ error: error });
            }
            else {
                res.sendStatus(500);
            }
        });
    };

    app.get("/api/dockerswarm/token/:type", (req, res) => {
        const { type } = req.params;

        if (!type || (type !== "worker" && type !== "manager")) {
            res.status(400).send({ message: 'invalid token type supplied (manager|worker)' });
        }
        else {
            const dockerCommand = `docker swarm join-token ${type} | sed -n 3p | grep -Po 'docker swarm join --token \K[^\s]*'`;
            execFunction(dockerCommand, res, true);
        }
    });

现在其他机器可以向主节点请求令牌并可以连接到 Swarm(我在用户数据中插入代码检查节点是否已经在 Swarm 中,否则请求令牌)。

Here 完整代码(包括我在 AWS Swarm 中使用的一些其他文件)。