如何在 ECS Auto Scaling 环境中的 EC2 实例上自动更新 OS/ECS 代理?

如何在 ECS Auto Scaling 环境中的 EC2 实例上自动更新 OS/ECS 代理?

首先:我觉得我仍然不了解 AWS 的一些基本概念,所以如果这个问题是新手难以理解的,请耐心等待。

我在AWS中有以下设置:

  • 1 个 ECS 集群,包含 1 个单一服务
  • 该集群配置为使用 1 个 EC2 实例
  • 此 EC2 实例是 AutoScaling 组的一部分,该组基于特定的启动配置。(集群设置是这样配置的,我想这是有道理的。)

我形成了一些先入之见/状况

  • 我不关心 EC2 实例,因为我的服务与机器无关
  • 我的服务每次只需要在 1 个实例上运行。我仅使用 ECS 来以简单的方式运行 dockerized 应用程序。
  • 我并不关心特定时间的停机时间。
  • 有一个预定义的弹性 IP 必须与服务一起使用。
  • 我希望这项服务尽可能自动化。当出现问题时,我们可以修复问题(正常运行时间并不那么重要),但我从不想通过 SSH 连接到 EC2 实例或类似的东西。

在……的帮助下云监控拉姆达,我设置了以下任务:

实例由集群名称标识,该名称会自动添加到名称标签中。

  • 一个星期一次,集群实例重新启动。这会更新证书和配置,因为服务在启动时会执行此操作。(我可能还可以安排以某种方式在集群内终止并重新启动服务...)
  • 每次集群的新 EC2 实例启动时,它将被分配预定义的弹性 IP。
  • 每月一次,EC2 实例被终止并被自动扩展组启动的新实例自动替换。

现在我的希望是,一旦 Auto Scaling Group 创建新实例,它将拥有最新、最好的 AMI,包括最新的 ECS 代理。

如果我错了,请纠正我,但是当我查看此自动缩放组的启动配置时,我认为情况并非如此,因为它始终采用配置的 AMI。


我的问题是:当我需要每隔一段时间(具体什么时候?)手动签入以更新启动配置中的 AMI,然后终止实例以使用新实例替换它时,这种设置有什么用呢?

我明白许多人可能不想在生产集群中自动更新操作系统,因为他们想先进行测试。但是,人们可能仍然希望拥有一个临时环境,其中操作系统更新会自动应用。为什么我使用高度自动化的平台,而我仍然需要手动推出操作系统更新。这是我概念上的误解吗?

答案1

我创建了一个 Lambda 函数来更新所有 ECS 集群中的实例代理:

var AWS = require('aws-sdk');
AWS.config.update({ region: 'sa-east-1' });

exports.handler = async(event, context) => {
    var ecs = new AWS.ECS();

    var responseArray = [];

    const clusters = await ecs.listClusters({}).promise();

    for (var i = 0; i < clusters.clusterArns.length; i++) {
        const clusterArn = clusters.clusterArns[i];

        const clusterInstances = await ecs.listContainerInstances({
            cluster: clusterArn
        }).promise();

        for (var j = 0; j < clusterInstances.containerInstanceArns.length; j++) {
            const containerInstanceArn = clusterInstances.containerInstanceArns[j];

            try {
                const response = await ecs.updateContainerAgent({
                    containerInstance: containerInstanceArn,
                    cluster: clusterArn
                }).promise();

                responseArray.push({
                    cluster: clusterArn,
                    containerInstance: containerInstanceArn,
                    response: response
                });
            }
            catch (e) {
                responseArray.push({
                    cluster: clusterArn,
                    containerInstance: containerInstanceArn,
                    response: e
                });
            }
        }
    }

    return responseArray;
};

然后我创建了一个 CloudWatch 事件规则来每天执行 lambda 函数。对我来说效果很好。

相关内容