Amazon EC2容器服务(ECS)是Amazon用于运行和编排Docker容器的解决方案。 它提供了一个接口,用于定义和部署可在EC2实例集群上运行的Docker容器。
ECS群集的初始设置和配置并不是一件容易的事,但是一旦配置好,它就能很好地工作,并使基于容器的应用程序的运行和扩展相对容易。 ECS还支持内置的蓝绿色部署,但是首先我们将介绍有关设置ECS的一些基础知识。
在ECS中,您可以创建任务定义 ,该定义与docker-compose.yml文件非常相似。 任务定义是容器定义的集合,每个容器定义都有一个名称,要运行的Docker映像以及用于覆盖映像的入口点和命令的选项 。 您还可以在容器定义中定义环境变量,端口映射,要安装的卷,内存和CPU分配,以及是否应将特定容器视为必不可少的部分,这是ECS知道任务是否正常或需要重新启动的方式。 。
您可以在任务定义中为多容器应用程序设置多个容器定义。 ECS知道默认情况下如何从官方Docker Hub提取信息,也可以配置为从私有注册表提取信息。 但是,私有注册表需要对EC2主机实例上安装的Docker客户端进行其他配置。
一旦有了任务定义,就可以从中创建服务 。 服务允许您定义要运行的任务数量,并与Elastic Load Balancer(ELB)关联。 当任务映射到特定端口(例如443)时,ECS群集中的每个EC2实例只能运行一个任务实例。 因此,您运行的任务不能超过EC2实例。 实际上,您需要确保运行的任务至少比EC2实例的数量少,以便利用蓝绿色部署。 任务定义已版本化,并且服务已配置为使用任务定义的特定版本。
什么是蓝绿色部署?
蓝绿色,黑红色,紫红色长春花,使用什么颜色真的没关系。 关键是存在两个独立但相等的环境。
在任何给定的时刻,您的应用程序都在一个环境中运行,而另一个环境要么被破坏以节省资源,要么处于空闲状态等待下一次更新。 第二个环境使您可以在不中断当前活动环境的情况下部署更新。 部署准备就绪后,可以更新负载均衡器/路由器,以将流量路由到新环境。
这个概念不是新概念,但是由于第二环境的要求,尚未被广泛采用。 根据您的应用程序体系结构的大小和复杂性,第二个环境可能非常昂贵且难以管理。 利用Docker容器和微服务架构可以帮助缓解这一挑战。 使用ECS在EC2上管理容器可以进一步减轻这种负担。
Amazon ECS如何处理蓝绿色部署
当服务更新为使用任务定义的较新版本时,ECS有助于进行蓝绿色部署。 当您定义服务并设置应运行的任务数时,假设您有足够的容量执行任务,ECS将确保许多任务正在运行。 当服务更新为使用任务定义的新版本时,只要集群中有剩余容量,它将从新定义启动新任务。 启动新任务时,它将耗尽旧任务的连接并杀死它们。
看一个最基本的示例,考虑在一个ECS群集中有两个EC2实例。 您已定义了运行单个任务实例的服务。 该任务将仅在其中一个EC2实例上运行。 更新任务定义并更新服务以使用新的任务定义时,ECS将在第二个EC2实例上启动一个新任务,将其注册到ELB中,从第一个EC2实例中删除连接,然后终止旧任务。
如前所述,您将要确保集群中至少有一个额外的EC2实例,而不是您在服务中设置的任务数。 如果在此基本示例中运行了两个任务,则每个EC2实例上将有一个任务,ECS将没有备用容量来启动新任务,因此将无法进行蓝绿色部署。 您将必须手动终止至少一项任务才能启动该过程。
还值得注意的是,每当ECS启动任务时,它将拉出定义中指定的Docker映像。 因此,当您构建映像的新版本并将其推送到注册表时,在ECS中启动的下一个任务将提取该版本。 因此,从持续集成和交付的角度来看,您只需要构建映像,推送到注册表并在ECS上触发蓝绿色部署,即可使更新的应用程序上线。
以下是一系列图,它们说明了ECS上简化的蓝绿色部署过程。
- 首先,我们有一个运行两个任务的服务。 这两个任务在EC2实例1和EC2实例2之间划分。
- 已创建更新的任务定义,并且已更新服务以使用新的任务定义。 ECS在EC2实例3上启动一个新任务,并开始消耗以前任务的连接。
- 随着连接从现有任务中耗尽,ECS将一次杀死一个并启动其他任务,直到达到所需的数量为止。
- 当ECS达到所需的运行任务数时,它将杀死仍在运行该任务的先前版本的所有剩余任务。
就是这样。 该应用程序的更新版本在新的“绿色”环境中运行。 使用ECS,将蓝色和绿色环境分开的概念有点虚幻和流畅,但是由于容器是隔离的,所以实际上没关系。
ECS部署:触发蓝绿色部署的简单而优雅的方法
在ECS上触发蓝绿色部署非常简单:创建任务定义的新版本(无需更改)并更新服务以使用新定义。 但是,每次要部署时都手动进行此操作有点麻烦,尤其是在不需要更改任务定义的情况下。
作为开发团队,我们喜欢运行一个持续的集成和交付过程,该过程使我们能够通过将代码与git repo中的适当分支合并来轻松触发部署。 与development的合并意味着应该将其部署到我们的登台环境中,而与master的合并意味着应该将其部署到生产中。 除了合并并推送到git之外,我们不需要任何其他手动处理。
我们的持续集成过程会克隆我们的存储库,构建我们的Docker映像,针对该映像执行单元测试,将该映像推送到我们的私有注册表(在ECS上运行),最后触发在ECS上的蓝绿色部署。 当我们寻找用于触发ECS更新/部署的解决方案时,选项非常复杂。 我们可以使用Amazon的CodeDeploy或Elastic Beanstalk,但是它们需要一个不同的构建过程,该过程与我们在CI中运行的过程不匹配。
由于触发蓝绿色部署所需的全部工作就是对任务定义和服务的更新,因此我们编写了一个包含一些参数的shell脚本,然后与AWS命令行工具一起使用以获取当前任务定义,创建一个新版本,并更新服务以使用它。 它工作得很好,非常简单。 触发更新后,它会监视服务以确保它在退出之前正在运行更新的版本。 如果看到新版本正在运行,它将以正常的零状态代码退出; 否则退出并出现错误。 这样,我们的CI / CD流程就会知道部署是否成功,并且可以通知我们部署失败。
顺便说一句, 我们的脚本是带有MIT许可证的开源软件。
ecs-deploy
可作为外壳脚本和Docker映像使用。 该脚本使用sed之类的Linux实用程序,它们在Linux和Mac上的行为不同,更不用说Windows了。 使用Docker映像可能会给您带来更多的一致性。
ecs-deploy的要求
ecs-deploy
使用其他软件来执行其工作。 值得注意的是,它使用AWS CLI工具,通常通过运行pip install awscli
通过pip install awscli
。 它还使用jq
,它是命令行JSON解析器。
尽管该脚本不需要您设置任何环境变量,但强烈建议您以这种方式设置AWS API凭据,以使它们不在您的shell历史记录和进程列表中。 还可以通过环境变量设置AWS区域,以将命令行选项保持在最低水平。
使用shell脚本
如果您已克隆存储库或将ecs-deploy
脚本下载到路径中,则可以运行它以获取完整的使用选项。 这是一个例子:
$ ecs-deploy -c clusterName -n serviceName -i repo/name:tag
该示例假设您已经为AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
和AWS_DEFAULT_REGION
配置了环境变量。
使用Docker映像
如果您不想安装jq
和AWS CLI
(或依赖的Python工具,如easy_install
),则可以运行Docker映像。
使用Docker映像的最佳方法是克隆ecs-deploy
项目存储库,并使用提供的docker-compose.yml配置。 通过使用Docker Compose运行映像,您可以通过文件提供与AWS相关的环境变量,以将其排除在命令行参数之外。 克隆存储库时,将local.env.dist文件复制到local.env并将凭据添加到该文件中。 然后,您可以使用docker-compose run ecsdeploy
来运行映像。
Docker镜像使用ecs-deploy
脚本的入口点,因此您只需要以与Shell脚本相同的方式提供参数即可。 这是一个例子:
$ git clone https://github.com/silinternational/ecs-deploy.git
$ cd ecs-deploy/
$ cp local.env.dist local.env (edit local.env to add your credentials and default region)
$ docker pull silintl/ecs-deploy:latest
$ docker-compose run --rm ecsdeploy \ -c clusterName -n serviceName -i repo/name:tag
如果要将ecs-deploy
合并到自己的docker-compose项目中,则可以使用以下命令添加另一个服务:
ecsdeploy:
image: silintl/ecs-deploy:latest
env_file:
- local.env
确保使用您的AWS凭证配置了env_file以便安全操作。
结论
蓝绿色部署提供了一种在发行期间最大程度地降低生产影响的好方法,并且Amazon的EC2容器服务简化了许多复杂性。 我认识到,我们的用例相对简单,并且以这种方式部署的应用程序可能不那么庞大和复杂,但是绝对值得研究。 我们对由代码更改触发的部署进行自动化的舒适性确实使我们的行为和开发过程变得更好。 它使我们更加敏捷,并且我们的开发人员更高兴没有大量的构建和发布过程。
我们发现我们的ecs-deploy
脚本对于ecs-deploy
非常有用,易于使用且可靠,我希望您也能从中受益。 感谢您提出的改进建议,也欢迎提出新功能的要求。 在下面发布您的评论和问题,以保持对话的进行。
资源资源
翻译自: https://www.javacodegeeks.com/2015/09/easy-blue-green-deployments-on-amazon-ec2.html