我们的团队由一名开发人员和一名DevOps工程师组成。 我负责将应用程序部署到Amazon ECS集群。 作为CI / CD服务器,我使用Bamboo。 在本文中,我将详细描述如何在开发环境中部署应用程序。


构建一个Docker镜像
在这里,我按照以下步骤操作:
- 步骤1:安装和配置Docker;
- 步骤2:在Bamboo中配置工件;
- 步骤3:配置Amazon ECR存储库;
- 步骤4:在Bamboo中构建Docker映像。
步骤1:安装和配置Docker
首先,我升级安装Bamboo的服务器,安装必要的软件包,并设置Docker存储库。 应该注意的是,我在CentOS 7操作系统上安装了Bamboo,有关在其他操作系统上安装
docker的信息可以在
www.docker.com上找到。
$ sudo yum update $ sudo yum install -y yum-utils device-mapper-persistent-data lvm2 $ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
然后安装Docker应用程序并启动服务:
$ sudo yum install docker-ce docker-ce-cli containerd.io $ sudo systemctl enable docker $ sudo systemctl start docker
然后,将Bamboo用户添加到Docker组:
$ sudo usermod -aG docker bamboo $ sudo su - bamboo $ docker run hello-world
如果在运行这些命令后,docker响应消息“ Hello from Docker!”,则表明我的安装正常。
步骤2.在Bamboo中配置工件
Grails正在开发应用程序。 编译应用程序时,将创建扩展名为war的文件。 用Bamboo术语,此文件是工件。 配置Bamboo以在后续任务中使用此文件。 为此,我转到“
任务”选项卡:

我设置了Grails任务,如下所示:

我们看到Grails首先清除build文件夹,然后运行测试,最后为dev环境创建war文件。
之后,单击“
工件”选项卡和“
创建工件”按钮:

我定义了一个工件,如下所示:

Grails将war文件放置在
build / libs目录中。 我将检查
Shared参数,因为稍后将需要此工件。
现在,我正在创建一个部署项目,并指定要在构建计划中使用的工件:


我还在部署项目中设置了
Artifact下载任务:

因此,Bamboo现在配置为使用战争文件。
步骤3.配置Amazon ECR存储库
Amazon ECR是用于图像的Docker存储和管理服务。 要进行配置,请打开AWS控制台并选择ECR:

创建存储库后,我得到以下地址:
aws_account_id.dkr.ecr.us-east-2.amazonaws.com/onboard
完成配置后,您还可以在此处找到有关如何登录,如何从存储库下载映像以及将映像上传到存储库的说明。
步骤4:在Bamboo中构建Docker映像
现在,我需要配置触发器以开始构建Docker映像。 为此,我转到“
触发器”选项卡,然后单击“
添加触发器”按钮:

在这里,我选择“
在成功构建计划后构建”选项,以便在编译项目后构建Docker映像。
现在我们需要添加Docker映像构建任务。 为此,请转到“
任务”选项卡,单击“
添加任务” ,选择
Docker类型。 输入描述,然后从下拉菜单中选择
构建Docker映像 。 在
存储库字段中,输入
aws_account_id.dkr.ecr.us-east-2.amazonaws.com/onboard:latest.
至于Dockerfile,可以如下图所示:
FROM openjdk:8-jre COPY *.war /usr/src/onboard.war WORKDIR /usr/src CMD ["/bin/bash", "-c", "java -DdataSource.url=$DATASOURCE_URL -DdataSource.username=$DATASOURCE_USERNAME -DdataSource.password=$DATASOURCE_PASSWORD -jar onboard.war"]
启动应用程序时,必须指定数据库。 环境变量DATASOURCE_URL,DATASOURCE_USERNAME,DATASOURCE_PASSWORD用于将此信息传输到应用程序,但是在容器启动时将设置它们的值。
这样就完成了将Docker映像与应用程序组装在一起的设置过程。 下一步是配置将此映像下载到Amazon ECR存储库。

将图像上传到Elastic Container Registry
您可以使用弹性容器注册表来存储使用Bamboo收集的图像。 为此,请按照下列步骤操作:
- 步骤1.安装Amazon ECR Docker凭证帮助器
- 步骤2.将IAM角色连接到Bamboo服务器
- 步骤3:配置Docker映像启动作业
步骤1.安装Amazon ECR Docker凭证帮助器
要将Docker映像下载到Amazon ECR,您必须具有凭证。 这些凭证可以通过运行以下命令获得
aws ecr get-login
但是,这些凭据仅有效12个小时。 因此,您可以在将映像上传到ECR之前每次运行上述命令,或者安装ECR Docker凭证帮助器,以使临时凭证保持最新状态并登录到ECR。 请按照以下步骤安装ECR Docker Credential Helper。
首先,您需要安装
git ,然后克隆github存储库:
$ sudo yum install git $ sudo su - bamboo $ git clone https://github.com/awslabs/amazon-ecr-credential-helper.git $ make docker
然后,需要
将以下行放入/home/bamboo/.docker/config.json文件中:
{ "credsStore": "ecr-login" }
并将已编译的应用程序复制到
/ usr / bin目录 :
$ exit $ sudo cp /home/bamboo/docker-credential-ecr-login /usr/bin/
步骤2.将IAM角色连接到Bamboo服务器
为了使Bamboo服务器能够使用ECR,您需要创建一个角色,将
AmazonEC2ContainerRegistryPowerUser策略添加到该角色,然后将该角色附加到EC2 Bamboo实例。 打开AWS控制台,然后选择IAM。 接下来,单击
创建角色按钮,选择
AWS服务和
EC2 ,如下所示:

然后,单击
下一步:权限按钮,然后在下一个屏幕上找到并选择
AmazonEC2ContainerRegistryPowerUser策略。 之后,我们完成创建角色并将其附加到我们的Bamboo服务器上。
步骤3:配置Docker映像启动作业
我们构建的应用程序将Docker映像与war文件放在一起。 现在,您需要将此图像上传到存储库。 为此,我添加了另一个Docker任务,这次将映像上传到ECR存储库。 我转到“
任务”选项卡,单击“
添加任务” ,选择
Docker类型。 我输入描述,然后从下拉菜单中选择
将Docker映像推送到Docker注册表 。 我选择“
自定义注册表”,然后在“
存储库”字段中输入存储库地址。 对于
身份验证类型,我选择
使用代理的本机凭据 。
这样就完成了将Docker映像加载到Amazon ECR存储库的设置过程。 以下步骤描述了配置集群和服务以启动容器应用程序的过程。 但是在此之前,您需要配置容器的启动选项。 这就是我们现在要做的。

创建Amazon ECS任务定义
任务定义-容器执行参数在此处编写。 我们的应用程序使用一个数据库,该数据库的参数是在容器启动时指定的,因此在本节中,我们还将创建一个数据库。 我将
Amazon RDS用作数据库,并将用于以加密形式访问数据库的密码存储在
AWS Systems Manager Parameter Store中 。 我遵循以下步骤以创建任务定义:
- 步骤1.在Amazon RDS实例上创建数据库;
- 步骤2.配置AWS Systems Manager参数存储;
- 步骤3.创建任务定义。
步骤1.在Amazon RDS实例上创建数据库
我们的应用程序使用PostgreSQL数据库。 要创建数据库,请打开AWS控制台,选择Amazon RDS服务,单击
创建数据库按钮,然后选择
PostgreSQL作为数据库引擎。 在下一页上,我选择“
开发/测试”作为工作环境,然后单击“
下一步” 。 然后,将
数据库实例标识符指定
为onboard-dev-db ,并将
主用户名指定为
devdbadmin 。 然后,我转到下一页以配置VPC,子网组和安全组。 该数据库将在专用网络上使用,因此我为“
公共可访问性”参数选择“
否 ”。 我在
数据库名称 字段中输入
devdb ,然后单击
创建数据库按钮。
步骤2.配置AWS Systems Manager参数存储
我以加密形式存储数据库密码。 为此,请打开AWS控制台,然后转到AWS Systems Manager→共享资源→参数存储→创建参数。 我输入
devdbpassword作为参数
名称,并为参数类型选择
SecureString ,然后在“
值”字段中输入数据库密码。
步骤3.创建任务定义
Amazon ECS是运行容器应用程序的集群。 它使用任务定义为容器应用程序指定执行参数。 要设置此类参数,请单击“
创建新任务定义”按钮。 然后,选择
Fargate作为启动
类型,然后继续下一步。 在这里,我将名称设置为
onboard-dev-taskdef 。 对于“
任务执行IAM角色”字段参数,选择“
创建新角色” 。 至于为此应用程序分配的资源,我指定2 GB的内存和1个vCPU。 现在,您需要添加容器启动选项。 我将容器命名为
onboard-dev-container 。 我将这样命名图像名称:
aws_account_id.dkr.ecr.us-east-2.amazonaws.com/onboard:latest 。 Amazon ECR Docker Credential Helper将负责ECR身份验证,因此我未选中“
私有存储库身份验证”选项。 在开发环境中,该应用程序在端口8080上可用,因此对于端口映射参数,我编写
8080并选择
tcp协议。 使用环境变量将数据库URL参数,用户名和密码传递到容器。 我在“环境变量”部分中设置了这些参数。 为了从参数存储中获取
devdbpassword参数的值,我指定了
ValueFrom类型。 我配置的最后一件事是
日志配置 ,在这里我选择
自动配置CloudWatch Logs 。 现在,任务定义的创建完成。
但是,ecsTaskExecutionRole角色需要一个策略来从参数存储中获取devdbpassword。 为此,请转到IAM角色,然后选择ecsTaskExecutionRole,然后单击
添加内联策略 。 在这种情况下,我将使用可视编辑器进行添加。 因此,在“服务”字段中,输入“
系统管理器” ,在“动作”字段中输入“
GetParameters” 。 然后,单击“资源”字段的“
添加ARN ”并填写我的值:

最后,我查看通过单击Review policy设置的参数值,为其命名并完成ecsTaskExecutionRole配置的使用。
这样就完成了启动容器应用程序设置的配置。 现在,您需要创建一个ECS集群和服务。

创建Amazon ECS服务
我们的容器应用程序在ECS集群中作为服务运行。 要配置,您必须执行以下步骤:
- 步骤1.创建一个Amazon ECS集群;
- 步骤2:建立服务
步骤1.创建Amazon ECS集群
要创建ECS集群,请转到AWS控制台并选择ECS服务。 然后单击“
创建群集” ,然后选择“
仅联网”群集模板。 在下一页上,我将集群命名为
onboard-dev-cluster并完成集群。 现在,我有了一个基于
Fargate的ECS集群。
步骤2:建立服务
要创建服务,我单击
onboard-dev-cluster链接,然后转到“
服务”选项卡并单击“
创建”按钮。 对于
启动类型,我选择Fargate,对于
任务定义,我选择onboard-dev-taskdef。 另外,我在“群集”字段中选择onboard-dev-cluster。 在
服务名称字段中,我编写了onboard-dev。 我将“
任务数”参数设置为零,因为我现在不想启动应用程序。 我将“
最小健康百分比”参数保留为100,将“
最大 健康百分比”参数保留为200。对于“
部署类型”参数,请选择“
滚动更新”并转到下一步。
在“
配置网络”页面上,为“
群集VPC”参数选择一个先前创建的名为“
开发VPC”的VPC 。 正在开发的应用程序仅在专用网络上可用,因此我选择了两个专用子网。 要配置安全组,请单击“
编辑”按钮,然后选择“
选择现有安全组” ,然后
选择 “
默认安全组”,然后单击“
保存”按钮。 对于
自动分配公用IP参数,我选择
禁用 。 接下来,对于“
负载均衡器类型”参数,我选择“
无”,并
取消选中 “
启用服务发现集成”选项。 然后单击“
下一步”,“下一步”和“
创建服务” 。
现在,我有一个正在运行的作业数量为零的服务。 我们将在下一步中配置应用程序启动。

服务更新
开发人员更新应用程序代码后,我们的部署将首先创建一个Docker映像,然后将其上传到Elastic Container Registry,最后在ECS Fargate集群中将容器应用程序作为服务启动。 目前,集群中正在运行的作业数为零。 为了启动应用程序,您需要更新服务,指示数量等于1。 我按照以下步骤来实现:
- 步骤1.为AWS Bamboo插件安装任务;
- 步骤2.更新ECS服务
步骤1.安装AWS Bamboo插件的任务
AWS Bamboo的任务是一个插件,可简化Bamboo构建和部署项目中AWS资源的准备和操作。 要安装此插件,我转到部署项目,单击
添加任务 ,转到Atlassian Marketplace并安装
AWS任务(Bamboo) 。
步骤2.更新ECS服务
现在,在部署项目中,我正在添加
Amazon ECS服务作业。 然后,在工作描述字段中
为onBoard-dev更新服务 。 在“操作”字段中,选择“
更新服务并
强制进行新部署” 。 然后,我选择美国东部(俄亥俄州)作为发射区域。 然后,我在Task Definiton,集群和服务的相应字段ARN(Amazon资源名称)中编写。 在此任务中,我将所需的运行任务数更新为一个。 接下来,我使用以下值填充部署配置文本框:
{ "maximumPercent": 200, "minimumHealthyPercent": 100 }
我正在建立一个没有公共IP的网络,如下所示:
{ "awsvpcConfiguration": { "assignPublicIp": "DISABLED", "subnets": ["subnet-ID1", "subnet-ID2"], "securityGroups": ["sg-ID"] } }
在“
AWS安全凭证”的“
源”部分中
,选择
“ EC2的IAM角色” 。
我需要能够更新ECS,因此我将
AmazonECS_FullAccess策略附加到我的Bamboo EC2实例。 为此,请打开AWS控制台,选择IAM。 然后,我选择用于Bamboo服务器的角色。 我单击
附加策略按钮,找到AmazonECS_FullAccess策略,选择左侧的复选框,并完成附加策略。
到此结束使用AWS和Bamboo的CI / CD设置。 因此,当开发人员更新应用程序代码时,将此代码上传到存储库,将启动应用程序的测试和组装。 然后,使用应用程序的war文件构建Docker映像,并将该映像复制到Amazon ECR存储库。 接下来,在Amazon ECS集群中,将容器应用程序作为服务启动,如果尚未停止当前应用程序,它将更新该应用程序。 如果停止应用程序以节省资源,则该应用程序仅启动。 在开发环境中检查应用程序后,可以通过将集群中运行的作业数指定为零来停止应用程序。
如果您喜欢这篇文章并有改进的想法,请在评论中写。