silinternational / ecs-deploy
用于在亚马逊弹性容器服务(ECS)上启动蓝绿部署的简单shell脚本
- dev-develop
- 3.10.17
- 3.10.16
- 3.10.15
- 3.10.14
- 3.10.13
- 3.10.11
- 3.10.10
- 3.10.9
- 3.10.8
- 3.10.7
- 3.10.6
- 3.10.5
- 3.10.4
- 3.10.3
- 3.10.2
- 3.10.1
- 3.10.0
- 3.9.1
- 3.9.0
- 3.8.0
- 3.7.1
- 3.7.0
- 3.6.0
- 3.5.1
- 3.5.0
- 3.4.0
- 3.3.0
- 3.2
- 3.1.1
- 3.1
- 3.0
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.0
- 2.4.1
- 2.4.0
- 2.3.1
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.1
- 2.0
- 1.0
- dev-master
- dev-awinder-develop
This package is auto-updated.
Last update: 2024-09-02 18:33:17 UTC
README
此脚本使用亚马逊ECS的任务定义和服务实体来启动自动蓝绿部署。
注意:仅维护
ecs-deploy
现在处于维护模式。换句话说,我们认为它“功能完善”,通常只会考虑修复错误或添加对新的AWS CLI功能支持的PR。
使用方法
One of the following is required:
-n | --service-name Name of service to deploy
-d | --task-definition Name of task definition to deploy
Required arguments:
-k | --aws-access-key AWS Access Key ID. May also be set as environment variable AWS_ACCESS_KEY_ID
-s | --aws-secret-key AWS Secret Access Key. May also be set as environment variable AWS_SECRET_ACCESS_KEY
-r | --region AWS Region Name. May also be set as environment variable AWS_DEFAULT_REGION
-p | --profile AWS Profile to use - If you set this aws-access-key, aws-secret-key and region are not needed
| --aws-instance-profile Use the IAM role associated with the current AWS instance. Can only be used from within a running AWS instance. If you set this, aws-access-key and aws-secret-key are not needed
-c | --cluster Name of ECS cluster
-n | --service-name Name of service to deploy
-i | --image Name of Docker image to run, ex: repo/image:latest
Format: [domain][:port][/repo][/][image][:tag]
Examples: mariadb, mariadb:latest, private.registry.com:8000/repo/image:tag
Optional arguments:
-a | --aws-assume-role ARN for AWS Role to assume for ecs-deploy operations.
-D | --desired-count The number of instantiations of the task to place and keep running in your service.
-m | --min minumumHealthyPercent: The lower limit on the number of running tasks during a deployment. (default: 100)
-M | --max maximumPercent: The upper limit on the number of running tasks during a deployment. (default: 200)
-t | --timeout Default is 90s. Script monitors ECS Service for new task definition to be running.
-e | --tag-env-var Get image tag name from environment variable. If provided this will override value specified in image name argument.
-to | --tag-only New tag to apply to all images defined in the task (multi-container task). If provided this will override value specified in image name argument.
--max-definitions Number of Task Definition Revisions to persist before deregistering oldest revisions.
Note: This number must be 1 or higher (i.e. keep only the current revision ACTIVE).
Max definitions causes all task revisions not matching criteria to be deregistered, even if they're created manually.
Script will only perform deregistration if deployment succeeds.
--task-definition-file File used as task definition to deploy
--enable-rollback Rollback task definition if new version is not running before TIMEOUT
--use-latest-task-def Will use the most recently created task definition as it's base, rather than the last used.
--force-new-deployment Force a new deployment of the service. Default is false.
--skip-deployments-check Skip deployments check for services that take too long to drain old tasks
--run-task Run created task now. If you set this, service-name are not needed.
--wait-for-success Wait for task execution to complete and to receive the exitCode 0.
--launch-type The launch type on which to run your task. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
--platform-version The Fargate platform version on which to run your task. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
--network-configuration The network configuration for the task. This parameter is required for task definitions that use
the awsvpc network mode to receive their own elastic network interface, and it is not supported
for other network modes. (https://docs.aws.amazon.com/cli/latest/reference/ecs/run-task.html)
--copy-task-definition-tags Copy the existing task definition tags to the new task definition revision
-v | --verbose Verbose output
--version Display the version
Requirements:
aws: AWS Command Line Interface
jq: Command-line JSON processor
Examples:
Simple deployment of a service (Using env vars for AWS settings):
ecs-deploy -c my-cluster-name -n my-service-name -i my.private.repo.com/frontend_container:latest
All options:
ecs-deploy -k ABC123 -s SECRETKEY -r us-east-1 -c my-cluster-name -n my-service-name -i my.private.repo.com/frontend_container -m 50 -M 100 -t 240 -D 2 -e CI_TIMESTAMP -v
Updating a task definition with a new image:
ecs-deploy -d my-task-definition -i my.private.repo.com/frontend_container:17
Using profiles (for STS delegated credentials, for instance):
ecs-deploy -p my-profile -c my-cluster-name -n my-service-name -i my.private.repo.com/frontend_container -t 240 -e CI_TIMESTAMP -v
Update just the tag on whatever image is found in ECS Task (supports multi-container tasks):
ecs-deploy -c staging -n core-service -to 0.1.899 -i ignore
Notes:
- If a tag is not found in image and an ENV var is not used via -e, it will default the tag to "latest"
安装
curl https://raw.githubusercontent.com/silinternational/ecs-deploy/master/ecs-deploy | sudo tee /usr/bin/ecs-deploy
sudo chmod +x /usr/bin/ecs-deploy
工作原理
注意:以下段落中的一些名词首字母大写,以表示它们在AWS中有特定含义的单词
请记住,在EC2容器服务中,提供有用应用程序(例如数据库、网络前端以及可能的一些维护/计划任务)的容器组之间的关系在任务定义中指定。然后,任务定义充当运行该组容器的一种模板。结果容器组被称为任务。由于Docker实施网络的方式,通常每个容器实例(提供集群基础设施的虚拟机)只能运行一个任务定义的任务。
任务定义自动进行版本控制——任务定义的实际名称由两部分组成,家族名称和版本号,例如:phpMyAdmin:3
由于任务应该是更广泛应用程序的完全自包含的“工作单元”,因此亚马逊使用另一个配置实体,服务,来管理任何给定时间运行的任务数量。由于任务只是任务定义的实例化,因此服务只是指定版本的任务定义和应从中运行的任务数量的绑定。
方便的是,亚马逊允许此绑定更新,无论是更改运行的任务数量还是更改它们构建的任务定义。在前一种情况下,服务将通过构建或终止任务来响应,以将计数调整到规定值。然而,在后一种情况下,它将执行蓝绿部署,也就是说,在终止任何旧任务之前,它将首先确保启动一个新的任务并准备好使用,这样就不会丢失服务。
当然,ECS集群必须具备足够的计算资源才能使所有这些工作。
因此,部署应用程序新版本所需的所有内容只是更新运行其任务的服务的配置,使其指向新的任务定义版本。ecs-deploy
使用python的aws
工具来完成此操作。它,
- 获取正在使用的任务定义的JSON表示形式;如果使用
--use-latest-task-def
,则获取最新创建的 - 编辑它
- 定义一个新的版本,包含更改
- 更新服务以使用新版本
- 等待,查询亚马逊API以确保服务已成功创建新任务
第二步需要更多解释:由于任务定义[可能]定义多个容器,因此问题出现了,“要创建新修订版需要更改什么?”从经验上看,令人惊讶的答案是没有任何改变;亚马逊允许你创建一个与任务定义完全相同的新版本,并且服务仍然会执行相同任务的蓝绿部署。
尽管如此,由于该系统使用Docker,假设应用程序的改进已集成到其容器镜像中,然后推送到仓库(公共或私有),然后再由ECS拉取使用。因此,该脚本使用指定的image
参数作为修改键来更改容器镜像使用的标签。它寻找与指定参数相同的仓库名称的镜像,并将其标签更新为指定参数中的标签。
这一点的直接后果是,如果你在任务定义中定义了多个容器使用相同的镜像,所有这些容器都会更新为指定的标签,即使你最初将它们设置为使用不同的标签。但这被认为是一个不太可能的使用场景。
这种行为允许指定两种可能的过程来指定哪些镜像以及相应的配置要部署。首先,你可以将标签设置为始终是latest
(或某个其他静态值),如下所示
ecs-deploy -c my-cluster-name -n my-service-name -i my.private.repo.com/frontend_container:latest
这将导致创建相同的新版本的任务定义,但服务仍然会执行蓝绿部署,因此会拉取最新版本(如果你之前将其推送到注册表)。
或者,你可以指定其他获取标签的方法,因为脚本eval
了镜像字符串。你可以使用git标签作为docker标签的映射
ecs-deploy -c my-cluster-name -n my-service-name -i 'my.private.repo.com/frontend_container:`git describe`'
或者可能只是从你的开发中的另一个文件中读取docker标签
ecs-deploy -c my-cluster-name -n my-service-name -i 'my.private.repo.com/frontend_container:$(< VERSION)'
无论如何,只需确保在运行此脚本之前构建、标记并推送你使用的Docker镜像到仓库。
使用环境变量指定标签名称值
在某些情况下,你可能想使用环境变量来指定图像的标签名称。例如,我们希望为每个任务定义使用唯一的Docker镜像/标签。这使我们能够通过仅选择先前任务定义并更新服务来撤销/回滚更改。
使用-e
参数,你可以提供包含你希望使用的标签值的变量的名称。
例如
ecs-deploy -c my-cluster-name -n my-service-name -i my.private.repo.com/frontend_container -e CI_TIMESTAMP
AWS IAM策略配置
以下是一个适用于AWS IAM的适当自定义策略的示例
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:DeregisterTaskDefinition", "ecs:DescribeServices", "ecs:DescribeTaskDefinition", "ecs:DescribeTasks", "ecs:ListTasks", "ecs:ListTaskDefinitions", "ecs:RegisterTaskDefinition", "ecs:StartTask", "ecs:StopTask", "ecs:UpdateService", "iam:PassRole" ], "Resource": "*" } ] }
故障排除
-
你必须提供AWS凭证之一。如果没有,你将看到AWS CLI的错误输出,例如
You must specify a region. You can also configure your region by running "aws configure".
测试
使用bats执行自动测试。测试的目的是确保更新/更改不会破坏核心功能。不幸的是,由于部分与AWS API交互执行操作,因此不是所有ecs-deploy
都是可测试的。因此,目前对本地数据解析/处理进行测试。
任何新的功能以及拉取请求都应该附带测试(如果可能)。
GitHub Actions支持
GitHub Actions支持可用。将类似以下代码块添加到你的actions yaml文件中。参数通过'with'部分传递给ecs-deploy工具。对于每个参数,参数名称后跟_cmd必须调用适当的参数选项,例如'--aws-access-key',以及提供参数aws_access_key的适当值。
deploy_to_ecs:
name: 'Deploy updated container image via blue/green deployment to ECS service.'
runs-on: ubuntu-18.04
steps:
- uses: silinternational/ecs-deploy@master
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
with:
aws_access_key_cmd: '--aws-access-key'
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key_cmd: '--aws-secret-key'
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
cluster_cmd: '--cluster'
cluster: 'cluster-name'
image_cmd: '--image'
image: '{amazon_id}.dkr.ecr.us-east-1.amazonaws.com/cluster-name/image_name:latest'
region_cmd: '--region'
region: 'us-east-1'
service_name_cmd: '--service-name'
service_name: 'aws-service-name'
timeout_cmd: '--timeout'
timeout: '360'