【问题标题】:How to pass docker swarm manager token to worker nodes in AWS using Terraform如何使用 Terraform 将 docker swarm manager 令牌传递给 AWS 中的工作节点
【发布时间】:2019-12-13 23:22:24
【问题描述】:

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

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

我有多项限制,因为我无法为此特定任务请求新服务。

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

【问题讨论】:

    标签: amazon-web-services docker terraform docker-swarm terraform-provider-aws


    【解决方案1】:

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

    您需要通过 IAM 实例配置文件授予 swarm manager 实例权限,以将令牌写入 /swarm/token/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,然后使用 userdata 脚本在工作节点上检索它。这可能会为您提供有关如何让 Swarm 集群在 AWS 上良好运行的更多提示。

    【讨论】:

    • 非常感谢上述建议,不幸的是我无法引入 SSM 来创建 Docker Swarm,因为我只有有限的访问权限并且无法请求为此任务进行配置。我通读了社区模块中的代码,可能会发现可以在我们的代码中调用的东西。
    • 你可以使用 S3 吗?它不是特别适合这个,但是自从 SSM 参数存储和大于 4kb 的对象之前,人们就一直在使用它。
    • 感谢@ydaetskcoR,我想S3 是我继续前进的正确选择。
    【解决方案2】:

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

    • AWS 中主节点的静态 ip。
    • 我在nodejs 中创建了在主服务器上运行的简单api rest 应用程序。这个api 接受其他节点的请求并返回token key。

    这是我使用的基本代码:

    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(我在 userdata 中插入了代码来检查节点是否已经在 Swarm 中,否则请求令牌)。

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

    【讨论】:

    • 感谢@VersilioB 不幸的是,由于整个环境是使用动态 IP 构建的,因此我无法继续为主服务器请求静态 IP。如上所述,我要么使用 S3 存储密钥并在我的工作节点中调用,要么必须使用 remote_exec 来捕获输出并在工作节点中使用它,否则考虑将 ansible 用于 Docker Swarm 集群设置
    猜你喜欢
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 2015-05-13
    • 2021-10-23
    • 1970-01-01
    • 2020-11-10
    • 2020-08-19
    • 1970-01-01
    相关资源
    最近更新 更多