使用AWS和Bamboo的CI / CD

我们的团队由一名开发人员和一名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集群中,将容器应用程序作为服务启动,如果尚未停止当前应用程序,它将更新该应用程序。 如果停止应用程序以节省资源,则该应用程序仅启动。 在开发环境中检查应用程序后,可以通过将集群中运行的作业数指定为零来停止应用程序。

如果您喜欢这篇文章并有改进的想法,请在评论中写。

Source: https://habr.com/ru/post/zh-CN458648/


All Articles