创建ECS
创建自定义存储库(Amazon Elastic Container Registry)以下称ECR
进入到ECS控制台,选择ECR。

选择Repositories,然后选择创建存储库

可见性选择为私有,名称自定义,然后单击创建存储库。

创建任务定义、
容器名称自定义,镜像URl去ECR中复制自己的镜像。

其余的选项,如果自己测试选择默认就可以,在这里会创建一个新的角色,后面讲CodePipeline中ECS任务定义的时候会用到这个角色我的名称为ecsTaskExecutionRole。

创建默认集群
首先切换到经典控制台,单击开始使用,创建默认的集群,全选择默认(我们主要是为了默认集群创建的VPC子网,负载均衡器)。

容器定义选择第一个,其余默认选项

创建目标群组
切换到EC2的目标群组,创建一个新的目标群组,类型选择为IP地址,名称自定义,端口号为443

VPC选择刚刚默认集群创建的VPC,之后下一步,创建目标组

切换到负载均衡器选项中,选择刚刚默认集群创建的负载均衡器,然后创建侦听器,端口443,转发到刚刚创建的目标群组中。

创建ECS服务
回到ECS,删除默认集群创建的任务,然后单击创建任务。
在创建任务页面,只需要选中FARGATE复选框,以及输入服务名称,其余均为默认选项。

在本页面中,输入任务数为1(集群所运行的任务数),!!!部署类型选择为蓝绿部署,其余默认。

在网络配置页面,选择刚刚默认集群创建的VPC以及子网,安全组可以默认选项

在负载均衡部分,选择ALB,名称选择默认集群创建的ALB,然后负载均衡的容器选择,添加到负载均衡器

生产监听端口选择80(这是默认集群创建的目标群组),测试选择443(这是我们刚刚自己创建的端口)

在Additional configuration部分,目标组1名称选择为默认集群创建的目标组,目标组名称2选择为刚刚我们自己创建的目标组名称也就是test

其余选项均选择为默认,然后创建服务
运行新任务
在任务选项卡下,单击运行新任务,在部署配置页面,需要选择系列(就是刚刚我们创建的任务定义的名称),其中手动指定修订不需要勾选,这样默认运行最新的任务,由于我在前面已经搭建过了,所以在修订这里为27,正常这里不需要勾选某人就好,预期任务数选择为1,其余均为默认选择。

创建CodeBuild
具体操作步骤同CodePipeline部署本地Ec2,但是其中配置文件有所修改,由于我们这次用的自己的镜像,所以需要Docker,一下为CodeBuild配置文件以及DockerFile文件内容。
DockerFile文件内容,这个DockerFile文件内容为aws上参考内容(文件名称Dockerfile)。
FROM ubuntu:18.04
# Install dependencies
RUN apt-get update && \
apt-get -y install apache2
# Install apache and write hello world message
RUN echo 'Hello' > /var/www/html/index.html
# Configure apache
RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && \
echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh && \
echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh && \
echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh && \
chmod 755 /root/run_apache.sh
EXPOSE 80
CMD /root/run_apache.sh
此处为CodeBuild配置文件(buildspec.yml),以下代码需要自己修改指定的账户ID以及自己服务在的区域,其中aws ecr、docker build、docker tag、docker push这四段代码可以登录到自己的ECR中,选单击推送命令自己复制,如下图。

在配置文件中,printf这句表示需要指定告诉CodePipeline镜像的具体地址在哪(具体内容参考aws官方文档https://docs.aws.amazon.com/zh_cn/codepipeline/latest/userguide/file-reference.html#file-reference-ecs-bluegreen)。
version: 0.2
phases:
install:
runtime-versions:
java: corretto11
pre_build:
commands:
- aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin aws账户ID.dkr.自己的区域.amazonaws.com
build:
commands:
- mvn package
- docker build -t docker .
post_build:
commands:
- docker tag docker:latest aws账户ID.dkr.ecr.服务的区域.amazonaws.com/docker:Hellow
- docker push aws账户ID.dkr.ecr.服务的区域.amazonaws.com/docker:Hellow
- printf '{"ImageURI":"aws账户ID.dkr.ecr.服务的区域.amazonaws.com/docker:Hellow"}' > imageDetail.json
artifacts:
files:
- appspec.yml
- taskdef.json
- imageDetail.json
discard-paths: yes
CodeDeploy(在通过经典控制台创建ECS服务时,已经自动创建过了,所这里直接略过)
创建CodePipeline
创建管道,名称自定义,其余默认选项。

源选择为S3,存储桶以及对象都选择自己要上传的位置以及文件名称

在构建阶段选我们创建的项目名称,其余默认。

构建阶段,提供程序选择ECS蓝绿,应用名称以及部署组选择默认集群创建的,其中ECS任务定义,以及AppSpec文件后面单独有提,同时后面如果不写文件路径默认为根目录下,这里先带过,任务定义中的占位符后面也会讲,单击下一步之后创建管道。

CodePipeline中ECS任务定义
先看代码,其中executionRoleArn需要修改自己的账户ID同时后面的ecsTaskExecutionRole为前面创建任务定义时创建的新角色。name为容器的名称,image为CodePipeline在部署阶段所定义的占位符的名称,这个在运行时会自动便储层最新镜像的路径
{
"executionRoleArn": "arn:aws:iam::账户ID:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "Hello",
"image": <IMAGE1_NAME>,
"essential": true,
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
]
}
],
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc",
"cpu": "256",
"memory": "512",
"family": "Hello"
}
AppSpec文件
<TASK_DEFINITION>为占位符无需修改,ContainerName为容器的名称,ContainerPort为容器向外暴露的端口。
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: "Hello"
ContainerPort: 80
目录结构,src为源码,scripts忽略。

遇到的错误

检查AppSpec文件中容器名称是否正确,以及buildspec.yml文件中print语句,后面是否为自己的镜像名称

错误CannotPullContainerError
参考网站https://aws.amazon.com/cn/premiumsupport/knowledge-center/ecs-pull-container-error/
错误(service AWS-Service) (port 8080) is unhealthy in
参考网站https://aws.amazon.com/cn/premiumsupport/knowledge-center/ecs-fargate-health-check-failures/
错误在(目标组 arn:aws:elasticloadbalancing:us-east-1:111111111111:targetgroup/aws-targetgroup/123456789)

参考网站https://aws.amazon.com/cn/premiumsupport/knowledge-center/troubleshoot-unhealthy-checks-ecs/
An AppSpec file is required, but could not be found in the revision
我的问题出现在CodePipeline,文件名写错了。

The ECS service cannot be updated due to an unexpected error: The container latest does not exist in the task definition. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: 9aa06817-51a3-4678-8e74-a19cc2ff7328; Proxy: null). Check your ECS service status.
建议查看appspec配置文件中容器名称,以及taskdef文件 中容器的名称是否相同。
如果在CodeDeploy阶段长时间卡在Install阶段建议去服务-》部署事件-》事件中查看可能的问题。
