ECS 201 Workshop(四)通过CodeDeploy实现蓝绿发布

ECS是AWS自行研发的容器管理平台,相对于流行的K8S架构,ECS更加简单易用,学习门槛相对很低。此外,Fargate无服务器技术的支持,将ECS完全从管理底层架构中解放出来,用户不需要再去关心Node节点的EC2配置,而是只在乎启动的任务,非常便于高效、快速的将既有容器投入使用。

ECS 201 Workshop分成:

共四个部分。此外,在ECS实验之前,还有一个基础篇是如何Build容器镜像,请参考

下面开始第四篇。演示视频如下:

一、模拟应用升级 —— 修改Docker Image镜像新版本

首先登录到之前实验用于build容器的EC2环境上,找到从git上下载的源代码,进入src源代码目录,修改其中的index.php文件。

为了效果更醒目,可以把其中 background-color: #333 修改为 F80 的颜色代码,这样测试时候效果会更加明显。如下截图。

image-20210207140432033

退回到Dockerfile所在的目录,执行如下命令构建新版镜像,将容器镜像发布到ECR服务上,且版本号更新为2。

docker build -t phpdocker .
$(aws ecr get-login --no-include-email --region cn-north-1)
docker tag phpdocker:latest 420029960748.dkr.ecr.cn-north-1.amazonaws.com.cn/phpdemo:2
docker push 420029960748.dkr.ecr.cn-north-1.amazonaws.com.cn/phpdemo:2

由此,就在ECR上获得了新版镜像。进入ECR页面。可以看到新版的镜像。点击Copy URI按钮,可以将新版本镜像的下载地址复制下来。如下截图。

image-20210207141016998

至此更新镜像完成。

二、编辑ECS任务定义

进入ECS服务界面,从左侧选择任务定义,在右侧找到任务名称,点击后选中,点击上方第二个按钮,创建新的版本 Create new revision。如下截图。

image-20210207141320183

在设置任务定义的界面,将屏幕向下滚动,找到容器定义部分,这里可以看到上一个实验使用的容器地址。点击容器的名称编辑详细信息。如下截图。

image-20210207142401219

在任务的详细设置界面,找到Image部分,将其中的容器地址从之前的tag名为latest的修改为2,然后点击右下角Update按钮。注意只需要修改版本标签即可,地址前半部分不需要修改。如下截图。

image-20210207142529071

返回到编辑任务界面,可以看到容器定义位置显示的版本已经从latest变成了刚设置的号的标签2。此外,请记住容器名称Container name下的名字phpdocker,稍后的配置将会使用。点击右下角的Create完成新版本的任务定义。

image-20210207142654868

创建新的任务定义完成。

返回ECS服务的任务定义界面。点击任务名称。如下截图。

image-20210207142808641

在任务界面可以看到两个版本,其中版本2是新版本。请记住这个页面的task名称myphpdemo:2后续配置将会使用。如下截图。

image-20210207142845959

至此任务定义完成。

三、构建CodeDeploy发布定义

新建一个存储桶,名称可以使用诸如codedeploy-ecs-demo-bjs这样的名称。注意:本存储桶必须和ECS、Codeploy服务在同一个region。如果跨region将发布失败。此过程操作方式不在描述。

新建一个yaml配置文件,保存为 appspec.yml。修正其中的关键配置为与实验环境相符的配置。其中区域cn-north-1请替换为您的实验区域。数字420029960748替换为您做实验的AWS账号。后边的任务定义名称myphpdemo:2替换本实验第二步的任务定义名称和版本。ContainerName替换为本实验第一步的容器名称。如下内容

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws-cn:ecs:cn-north-1:420029960748:task-definition/myphpdemo:2"
        LoadBalancerInfo:
          ContainerName: "phpdocker"
          ContainerPort: 80

修改完成后,将本文件保存在S3存储桶内。至此发布配置文件修改完成。

四、定义CodeDeploy部署规则

CodeDeploy内置了集中发布规则,例如AllAtOnce立刻更新所有服务,以及每3分钟更新10%的服务等几种规则。为了让实验过程更加清晰易于观察,我们定义一个发布规则:每2分钟更新50%。注意:这种发布方式不适合生产环境使用,只是为了实验更清晰的看到发布效果。

进入CodeDeploy界面,点击Deploy下的发布配置Deployment configuraitons,点击右侧的创建新的发布规则。

image-20210207145626039

在创建新发布规则位置,名称填写为2mins-half,表示两分钟发布一半,当然也可以填写别的名字。在服务位置选择发布平台是ECS。在类型位置选择是线性发布Linear。在Step步长位置输入50,表示发布50%。在间隔Interval位置输入2表示2分钟。点击右下角的创建按钮完成发布规则的配置。如下截图。

image-20210207153434921

创建完成后,在搜索框中输入名称2mins,应该可以搜索到刚才创建的部署规则。如下截图。

image-20210207150511604

至此部署规则完成。

五、通过CodeDeploy控制台图形界面发起部署

新版本发布将基于上一个实验完成Autoscaling之后的基础来进行。Autoscaling缩减到实例数量为1的情况下也可以正常进行蓝绿发布。此时系统会新建额外的ECS容器,旧版本继续运行,并在新旧之前分配流量。因此前一个版本的实验环境将可以直接拿来使用。

进入CodeDeploy界面,点击左侧的应用程序Application菜单。这里可以看到一个默认的应用名称。此应用是在ECS中创建服务Service时候自动建立的。点击右侧的应用名称。如下截图。

image-20210207150914492

点击应用名称后进入应用详情在右侧可以看到应用部署组,点击Name可以看到部署组,点击部署组。如下截图。

image-20210207151041256

进入到部署组的详情之后,可以看到右侧显示的部署配置Deployment configurationsAllAtOnce的形式,并不是之前创建的2mins-half。这是因为在之前的实验创建ECS服务的时候,选择的是默认的AllAtOnce0方式。这里可以不用修改。稍后新创建一个版本发布的时候,可以指定 额外的发布方式。点击右上角的Create deployment创建发布。

image-20210207151443494

在创建部署页面,部署组的名称不要修改,在类型选择配置文件在S3,路径位置输入前文创建的S3桶的完成地址,例如s3://codedeploy-ecs-demo/appspec.yml 地址,并在下方的文件类型下拉框选择为 .yaml 格式。如下截图。

image-20210207151542089

向下滚动页面,在描述部分留空可以不填写。在部署配置下拉框中,选择上一步创建的发布规则 2mins-half。在回滚配置的位置选项保持默认即可,不需要修改。点击右下角Create deplopyment创建发布。

image-20210207152058624

创建任务成功。此时页面会自动跳转到部署菜单下,并显示当前部署进度。发起部署后需要等待几分钟,系统在ECS内完成第一批50%容器的部署。在部署没有生效前,可以看到屏幕右侧的流量切换指示,用户访问流量100%访问到旧的环境上。此页面会自动刷新,不要手动刷新。如下截图。

image-20210207152623542

此时打开ECS控制台,可以看到系统同时启动了版本标签为1和2的两个版本的环境,同时运行,分批接受流量。

image-20210207152845692

等待大概3分钟左右,新版本部署50%完成,可以看到右侧的环境提示已经部署完成,从现有系统接受50%的流量。如下截图。

image-20210207152900903

此时访问负载均衡器的入口,可以看到访问可能是显示V2。此时按强制刷新,MacOS是Command+R,Windows是Ctrl+F5,即可看到访问流量在显示V2和不现实V2之间跳转,其分流百分比接近50%,由此表示我们定义的蓝绿部署发布规则生效。

image-20210207152913006

在等待超过2分钟后,达到部署规则的预定时间,流量将100%的分配到新版本上,原来的版本不在获取流量。此时刷新负载均衡器的流量入口,将100%看到显示V2字样的网页。在新版本部署的容器正常运行的同时,旧版本的容器还将保留1个小时不删除,通过页面可以看到1小时的倒计时。满1小时后自动删除之前的容器。如下截图。

image-20210207154239048

如果不希望等待1小时,可以直接点击右上角的Terminate original task set来立刻终止上一个版本的容器运行。

至此CodeDeploy的ECS部署实验完成。