【问题标题】:Using lambda's for ECS auto deployment使用 lambda 进行 ECS 自动部署
【发布时间】:2019-11-30 04:13:11
【问题描述】:

我对此一无所知。我目前正在为 aws 应用程序设置自动部署。该应用程序在没有负载均衡器的情况下在 ECS 内部运行。

这里的想法是,当一个新的 docker 映像被推送到 ECR 时,cloudTrail 会获取日志,cloudWatch 触发和警报,说警报会发送到 SNS,并且 SNS 会触发一个 lambda 进行部署。到目前为止,除了 lambda 之外,我一切都在工作。

我使用的代码是python,如下:

import boto3
import pprint
import os

region = "us-east-2"
client = boto3.client('ecs', region_name=region)


response = client.list_task_definitions(familyPrefix= 'stage-dcs-task-000', status='ACTIVE')

def lambda_handler(event, context):
    response = client.register_task_definition(
        family='stage-dcs-task-000',
        networkMode='bridge',
        containerDefinitions=[
            {
                'name': 'dcs-stage-container-000',
                'image': 'ecrUrlHere:latest',
                'cpu': 10,
                'memory': 500,
                'portMappings': [
                    {
                        'containerPort': 8080,
                        'hostPort': 80,
                        'protocol': 'tcp'
                    },
                ],
                'essential': True,
            },
        ],
    )
    taskDefinitionRev = response['taskDefinition']['family'] + ':' + str(response['taskDefinition']['revision'])


    response = client.update_service(
        cluster='stage-secretName-conversation-service',
        service='stage-dcs-service-000',
        desiredCount=1,
        taskDefinition=taskDefinitionRev,
        deploymentConfiguration={
            'maximumPercent': 200,
            'minimumHealthyPercent': 100
        },
        forceNewDeployment=True
    )

现在,这个 lambda 失败并出现错误

  "errorMessage": "An error occurred (InvalidParameterException) when calling the UpdateService operation: The container stage-dcs-container-000is not valid. The value for 'containerName' must already be specified in the task definition. Registry: ARN-LINK-HERE"

查看在 AWS 中创建的内容,任务定义已正确创建,容器已正确命名和配置。根据我从文档中了解到的信息,我对 update-service 的调用是正确的,我只是不知道为什么容器名称会无效。

需要注意的一点是,容器名称可能必须是唯一的。因此,我开始将任务修订号添加到容器名称的末尾以代替 000,但是,我总是将 stage-dcs-container-000 作为无效名称返回,并且不知道它可能来自哪里。这里有什么想法吗?

在进行更多调试后,我发现是当前任务定义中的容器名称引发了错误。根据容器名称规则,我不能有破折号,所以我将它们改为下划线,但同样的问题仍然存在。

资源:这是我一直关注的教程https://medium.com/@YadavPrakshi/automate-zero-downtime-deployment-with-amazon-ecs-and-lambda-c4e49953273d

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-ecs


    【解决方案1】:

    我花了一点时间来解决这个问题,但我最终解决了这个问题。说实话,我不是 100% 确定修复是什么,但我知道至少有两个错误。

    第一个事实是,我不知何故陷入了这样一种状态:堆栈不同部分的名称中有非法字符。举一个明确的例子,我在容器名称中有破折号 (-),这是一个非法字符。为了解决这个问题,我们只能使用驼峰式外壳重新创建整个技术堆栈。

    第二个是我在 lambda 函数中出现了一些错误,特别是在创建任务修订版时。我最终注意到,当我通过 cli 创建东西时,我不知何故错过了 docker 要求。我如何解决这个问题是我在 AWS 领事中创建了任务修订,然后将 json 复制到 lambda 内的 register_task_definition 方法中。这就是我开始的那个没有用的。

    response = client.register_task_definition(
            family='stage-dcs-task-000',
            networkMode='bridge',
            containerDefinitions=[
                {
                    'name': 'dcs-stage-container-000',
                    'image': 'ecrUrlHere:latest',
                    'cpu': 10,
                    'memory': 500,
                    'portMappings': [
                        {
                            'containerPort': 8080,
                            'hostPort': 80,
                            'protocol': 'tcp'
                        },
                    ],
                    'essential': True,
                },
            ],
        )
    

    这就是我完成的工作。

    response = client.register_task_definition(
            containerDefinitions=[
                {
                    "portMappings": [
                        {
                            "hostPort": 80,
                            "protocol": "tcp",
                            "containerPort": 8080
                        }
                    ],
                    "cpu": 10,
                    "environment": [],
                    "mountPoints": [],
                    "memoryReservation": 500,
                    "volumesFrom": [],
                    "image": "image uri here",
                    "essential": True,
                    "name": "productionDCSContainer"
                }
            ],
            family="productionDCSTask",
            requiresCompatibilities=[
                "EC2"
            ],
            networkMode="bridge"
        )
    

    需要注意的是,很容易陷入死锁的状态,也就是说你有minPercentage = 100, maxPercentage = 100 和desired = 1。在这种情况下,AWS永远不会杀死正在运行的实例来开始更新。解决这个问题的方法是让 minInstance = 0、maxInstance = 200% 并让 forceNewDeployment = True。

    【讨论】:

      猜你喜欢
      • 2019-04-29
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 2015-10-05
      • 2016-05-20
      • 2022-07-17
      相关资源
      最近更新 更多