背景

AWS CodePipeline 是一种持续性的集成与交付服务,可以实现快速而可靠的应用程序和基础设施更新。根据您定义的发布流程模型,只要代码发生变更,CodePipeline 便会生成、测试和部署您的代码。

情况是这样的,最近公司在搞APN认证,需要将项目迁移到AWS上面,并且搭建一套CI/CD流程。因为项目是SpringCloud微服务,所以需要部署多个服务。

经过调研,我们做了以下设计:

我们设计,将代码推送到AWS Code Commit,将项目需要用到的自研jar包上传到AWS Code Artifact。代码推送到AWS Code Commit时,AWS Code Pipeline触发打包服务,使用AWS Code Build打包的时候,访问AWS Code Artifact去拿jar包。打完jar包之后,AWS Code Pipeline触发AWS Code Deploy上传jar包至EC2(ECS也可以,看需求),然后AWS Code Deploy调用配置好的脚本,备份和启动项目。

所以除了项目中用到的数据库,中间件之外不谈,我们需要的服务有:

  • 代码仓库:使用AWS Code Commit
  • 制品仓库: 使用AWS Code Artifact
  • 项目打包服务: 使用 AWS Code Build
  • 部署服务: AWS Code Deploy
  • 流水线服务: AWS Code Pipeline
  • 虚拟机EC2

AWS Code Pipeline 负责将这些服务串联起来,形成工作流。

产品都使用的孟买地区的服务(ap-south-1)

安装AWS CLI

因为需要使用AWS服务,所以首先我们得安装AWS CLI命令行工具,并且配置好自己的账号信息,下载和配置AWS CLI参考:AWS CLI 官方文档

我们安装AWS CLI主要是用来通过Code Artifact的认证,Code Artifact必须使用AWS CLI来生成临时凭证访问。

AWS Code Commit

AWS CodeCommit 是一种完全托管型源代码控制服务,使公司可以轻松地托管安全和高度可扩展的专用 Git 存储库。CodeCommit 使您无需运作自己的源控制系统或担心基础设施的扩展能力。

这一步其实可以不做,因为AWS Code Build可以从github中拉取代码,但是为了认证APN,最好都使用AWS的服务,所以加了这一步。

在AWS Code Commit中,直接创建存储库即可,最主要的是怎么连接。

Code Commit可以使用账号密码访问,就像github一样。账号密码需要在IAM权限管理服务中查看:

在IAM中,选择用户选项,然后打开一个用户,来到安全证书选项下面:

上图箭头所标识的就是登陆Code Commit的方式,SSH和账号密码选择一种进行登陆即可。

AWS CodeArtifact

AWS CodeArtifact 是一种完全托管的构件存储库服务,它使各种规模的组织都可以轻松安全地存储、发布及共享其软件开发过程中所使用的软件包。

咱们的项目使用的是自己写的微服务框架,原本是存储在公司的Nexus制品仓库中(Maven私服),为了方便AWS CodeBuild打包,所以我们将项目所需要的jar包都上传到这个服务中。

因为我们使用的是Maven来进行Deploy,按照官方的指南,需要通过以下的配置来通过验证:

前提:安装好AWS CLI,并且配置好自己的账号。

首先修改maven的setting文件:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>你的本地Maven仓库地址</localRepository>
<pluginGroups></pluginGroups>
<proxies></proxies>
<servers>
<server>
<id>codeartifact</id>
<username>aws</username>
<password>${env.CODEARTIFACT_TOKEN}</password>
</server>
</servers>
<profiles>
<profile>
<id>default</id>
<repositories>
<repository>
<id>codeartifact</id>
<url>你的CodeArtifact访问地址</url>
</repository>
</repositories>
</profile>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>default</activeProfile>
</activeProfiles>
</settings>

可以从上面的配置文件中看到,我们是从环境变量中获取密码的,因为其密码只能通过AWS CLI生成临时的凭证,而且生成的Token只能保持12小时有效。

生成密码的方式:

macOS or Linux:

$ export CODEARTIFACT_TOKEN=`aws codeartifact get-authorization-token --domain mydomain --domain-owner domain-owner-id --query authorizationToken --output text`

Windows PowerShell:

> $CODEARTIFACT_TOKEN = aws codeartifact get-authorization-token --domain my-domain --domain-owner domain-owner-id --query authorizationToken --output text

你需要将界面中的 export 配置的

–my-domain

–domain-owner-id

2 个参数替换成你配置的参数。

通过上面的命令就会生成 Token, 然后将这个 token 保存到系统变量中。

如果一切顺利,你将会看到你的屏幕中输出上面的字符串,上面的字符串就是你 Maven 登录使用的 token。

登录之后,我们将项目所需要的Jar包上传至AWS CodeArtifact

AWS CodeBuild

AWS CodeBuild 是一项完全托管的持续集成服务,可编译源代码、运行测试以及生成可供部署的软件包。使用 CodeBuild,您无需配置、管理和扩展自己的生成服务器。CodeBuild 可以持续扩展并同时处理多项生成任务,因此您的构建任务不会在队列中等待。

我们使用AWS CodeBuild对项目进行打包

创建CodeBuild角色

在使用AWS CodeBuild之前,我们需要创建其角色:

来到IAM页面,点击创建角色,选择CodeBuild产品,点击下一步

在附加权限中,搜索CodeArtifact,选择其一,我这里选择的是AdminAccess,下面一个是只读

只有选择了这两个的其中一个,我们才能通过CodeBuild访问CodeArtifact

然后跳过标签,下一步,创建一个名字,自拟。点击创建角色即可。

创建CodeBuild构建项目

来到AWS CodeBuild页面,创建构建项目:

这里只说明几个需要注意的选项

源我们使用CodeCommit

可以选择源是来源于CodeCommit的哪一个分支或者Git标签或者提交的ID。

打包环境选择标准的Standard环境即可,角色选择现有服务角色,使用我们刚才创建的哪个角色即可。

需要注意的是这里,BuildSpec.yml文件,这个文件是具体的打包步骤,如果要配合CodeDeploy部署程序,还需要一个appspec.yml文件 Build+Deploy官方示例

这是我们项目中的其中一个服务,我们项目启动只需要api模块中的jar包

这里的settings-aws.xml为在CodeBuild中进行maven打包的setting配置文件。

buildspec.yml

version: 0.2

phases:
install:
runtime-versions:
java: corretto8
pre_build:
commands:
- pip3 install awscli --upgrade --user
- export CODEARTIFACT_TOKEN=`aws codeartifact get-authorization-token --domain xxx --domain-owner xxx --query authorizationToken --output text`
build:
commands:
- echo Build started on `date`
post_build:
commands:
- echo Build completed on `date`
- mvn package -Dmaven.test.skip=true --settings ./settings-aws.xml
- rm -rf vehicles-service-api/target/*jar.original
- rm -rf vehicles-service-api/target/*-javadoc.jar
- rm -rf vehicles-service-api/target/*-sources.jar
artifacts:
files:
- vehicles-service-api/target/*.jar
- appspec.yml
- backup.sh
- start.sh
discard-paths: yes

注意:

  • pre_build.commands中执行的是CodeArtfact验证的过程,如果CodeBuild的角色没有CodeArtfactAccess的权限,这一步则会验证失败。

  • artifacts.files是我们打完包之后,会将这里定义的文件交给CodeDeploy

appspec.yml、backup.sh和start.sh涉及CodeDeploy服务,在下一节介绍。

AWS CodeDeploy

AWS CodeDeploy 是一项完全托管的部署服务,可自动将软件部署到计算服务,例如 Amazon EC2、AWS Lambda 以及您的本地服务器。借助 AWS CodeDeploy,您可以更轻松地快速发布新功能、避免在应用程序部署过程中出现停机,并简化应用程序的更新工作。

CodeDeploy的配置思路:

  1. 配置角色
  2. 安装Deploy组件
  3. 创建应用程序
  4. 在应用程序中创建部署组,设定部署在哪里
  5. 编写appspec.yml文件

配置角色

配置服务器角色

无论使用的是ECR还是EC2,我们都需要给服务器配置权限,这里我使用的是EC2

来到IAM角色页面,如果你没有EC2的角色,则创建一个新角色,选择角色类型为Amazon EC2。如果你有EC2的角色,则点击附加角色

在附加策略里面搜索 CodeDeploy;然后选择AmazonEC2RoleforAWSCodeDeploy

我这里将其取名为:ChuanXiaoCodeDeployInstanceRole

如果你的服务器没有角色,需要去将你的服务器角色改为创建的新角色

配置CodeDeploy角色

我们还要在这里建立一个 CodeDeploy 的应用使用的角色。再次点击「创建角色」。选择角色为「Amazon EC2」,在附加策略时依然搜索 CodeDeploy,但是这次选择的策略叫做:AWSCodeDeployRole

我这里将其取名为CodeDeployServiceRole

安装Deploy组件

如果需要使用Deploy部署你的服务,则需要安装Deploy组件: 安装CodeDeploy官方文档

登录你的服务器,执行以下命令

$ sudo yum update
$ sudo yum install ruby
$ sudo yum install wget $ cd /home/ec2-user
# 将以下命令的bucket-name换为您CodeDeploy所在区域的S3桶名字,比如:美国东部(俄亥俄)区域,请将存储桶名称替换为 aws-codedeploy-us-east-2
# 将以下命令的region-identifier换为您CodeDeploy所在区域的表示符,比如美国东部(俄亥俄)区域,请将区域标识符替换为 us-east-2
$ wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto # 检查服务是否正在运行
$ sudo service codedeploy-agent status
# 开启服务
$ sudo service codedeploy-agent start

创建应用程序

点击CodeDeploy选项中的应用程序,点击创建应用程序

输入应用程序的名字,选择应用程序需要部署到的平台,点击创建应用程序

创建部署组

应用程序创建完毕之后,点进去,然后点击创建部署组

这里的角色选择我们刚才创建的角色

这里选择就地部署,因为我使用的是EC2,所以选择AmazonEC2实例,通过标签来标识选择哪一个Ec2实例,我这里的EC2实例的name就为ChuangXiaoEc2,所以这里通过name设置。

这是我们ES2的信息:

最后的负载均衡这里,因为没有这个需求,就没有选择

编写appspec.yml文件

在配置CodeBuild的时候说道,我们需要appspec.yml文件,这个文件是做什么的呢?

appspec.yml是YAML格式、用于定于CodeDeploy服务在整个阶段所做的操作和文件拷贝路径和权限等。

也就是说定义CodeDeploy在部署的机器上面拷贝哪些文件,定义和描述被拷贝到目标服务器上的文件拷贝后的权限,定义各个阶段执行的操作。具体的解析可以参考这篇文章:appspec.yml文件解析

appspec.yml示例

version: 0.0
os: linux
files:
- source: /
destination: /home/ec2-user/chengdu_iot/vehicles-service/standby_dir
hooks:
BeforeInstall:
- location: backup.sh
timeout: 3000
ApplicationStart:
- location: start.sh
timeout: 3000

这个文件的version只能填0.0,我们服务器是linux,所以os为linux

files:定于文件映射关系

source文件路径是是相对于本此部署包的相对路径,如果是/,表示本此部署包里的全部文件和目录

需要注意的是,本此部署包中的文件,就是你在Buildspec.yml中定义的artifacts.files的文件,CodeDeploy会通过Buildspec.yml,获取需要哪些文件,然后上传至服务器。linux系统下,版本包会被上传到/opt/codedeploy-agent/deployment-root/deployment-group-id/deployment-id/deployment-archive,windows系统会被上传到C:\ProgramData\Amazon\CodeDeploy\deployment-group-id\deployment-id\deployment-archive

destination这里是被部署服务器的完整路径(绝对路径),会将source中设定的文件,从/opt/codedeploy-agent/deployment-root/deployment-group-id/deployment-id/deployment-archivecopy到设定的destination路径中

hooks区段就是定义各个阶段执行的操作,这里的BeforeInstall为:文件复制到目标目录之前的操作

project_dir=/home/ec2-user/chengdu_iot/vehicles-service

standby_dir=$project_dir/standby_dir
backup_dir=$project_dir/backup cd $project_dir if [ ! -d $standby_dir ]; then
echo "创建等待文件夹"
mkdir -p $standby_dir
else
echo "等待文件夹已存在"
fi if [ ! -d $backup_dir ]; then
echo "创建备份文件夹"
mkdir -p $backup_dir
else
echo "备份文件夹已存在"
fi jar_name=`ls | grep jar$ | awk '{print $1}'`
if [ -n "$jar_name" ];then
mv ./$jar_name ./backup/$jar_name.`date +%Y%m%d%H%M%S`
fi

这个脚本判断项目文件夹是否存在,不存在则创建。再判断jar包是否存在,存在则进行备份。

ApplicationStart表示文件复制完之后的操作

port=9083
project_dir=/home/ec2-user/chengdu_iot/vehicles-service standby_dir=$project_dir/standby_dir cd $standby_dir jar_name=`ls | grep jar$ | awk '{print $1}'` mv $jar_name ../ cd ..
rm -rf standby_dir pid=`netstat -anp|grep $port|awk '{printf $7}'|cut -d/ -f1`
if [ -n "$pid" ]
then
if [ "$pid" != "-" ]
then
echo "kill -9 的pid:" $pid
kill -9 $pid
fi
fi nohup java -Xms1g -Xmx1g -jar $jar_name --spring.profiles.active=test --server.port=$port >console.log 2>&1 &

这个脚本做了三件事,将jar包从等待文件夹中拿出来,然后删掉等待文件夹。然后判断是否有这个jar包的进程在运行,如果有就杀掉。最后运行jar包

AWS CodePipeline

AWS CodePipeline 是一种持续性的集成与交付服务,可以实现快速而可靠的应用程序和基础设施更新。根据您定义的发布流程模型,只要代码发生变更,CodePipeline 便会生成、测试和部署您的代码。

对于AWS Pipeline我的理解是,将以上服务串联起来,当设定的CodeCommit分支发生变动的时候,就触发CodeBuild,然后CodeBuild打包成功之后,将buildspec.yml文件中设定的需要传输的文件告诉CodeDeploy,然后CodeDeploy将文件上传至服务器。最后CodeDeploy执行执行脚本,运行项目。

在CodePipeline页面,点击创建流水线

第一步设置流水线名字和角色,这里自拟名字,选择一个新服务角色就好。

这里源选择AWS CodeCommit,设置好分支,这样当这个分支发生变化的时候,就会触发整个流水线。

构建选择AWS CodeBuild,选择我们之前在CodeBuild中创建的构建项目

部署选择AWS CodeDeploy,选择我们创建的应用程序和部署组。

最后点击创建流水线,这样一个流水线就创建完毕了。

结果

当设定的CodeCommit分支发生变动的时候,就触发CodeBuild,然后CodeBuild打包成功之后,将buildspec.yml文件中设定的需要传输的文件告诉CodeDeploy,然后CodeDeploy将文件上传至服务器。最后CodeDeploy执行执行脚本,运行项目。

AWS CodePipeline部署Maven项目至EC2的更多相关文章

  1. Intellij 部署maven项目

    一 部署Maven项目 1.下载和配置 (1)下载:maven.apache.org,点击download,下载apache-maven-3.3.9-bin.zip (2)配置环境变量: 环境变量包括 ...

  2. 部署Maven项目到tomcat报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener【转】

    部署Maven项目到tomcat报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderLi ...

  3. maven的配置环境及Myeclipse部署Maven项目

    1.官网下载maven>解压>配置环境变量:在path后面加上 D:\software\apache-maven-3.3.9\bin; 2.cmd/mvn -version 测试  显示版 ...

  4. [置顶] Maven多模块项目 eclipse热部署 Maven项目实现 tomcat热部署 二

    最近看到有好多童鞋比较热衷热部署,特别是多模块的项目,其实这热部署如果多模块比较大资源,容易内存溢出或者电脑卡住,并不建议这么做. 不过了解下也没有关系,这里我就在说说热部署的另外一种方法,因为我之前 ...

  5. Myeclipse2014中,新建部署Maven项目

    一.环境 1.1 myeclipse2014 1.2 maven3.2.1 1.3 jdk1.7 上述环境配置可参照我之前编写的maven搭建方面的文档.本文着重介绍myeclipse2014下mav ...

  6. Jenkins+harbor+gitlab+k8s 部署maven项目

    一.概述 maven项目部署流程图如下: 环境介绍 操作系统 ip 角色 版本 ubuntu-16.04.4-server-amd64 192.168.10.122 Jenkins+harbor Je ...

  7. Jenkins部署maven项目到远端服务器

    jenkins服务器地址:192.168.1.203 项目部署机器地址:192.168.1.201,192.168.1.200 代码托管github 虽然比较low,但是入门是可以的! Jenkins ...

  8. 解决eclipse部署maven项目无法导入lib的问题

    eclipse版本为2018-12(4.10.0) 1.默认tomcat的server配置 改成: 2.项目部署 按上面的配置,项目会部署到你配置的本地tomcat的webapps目录下. 部署了项目 ...

  9. Jenkins构建部署Maven项目

    1 创建新项目 2 构建maven项目 3 配置 3.1  源代码管理 svn 用户名,密码 4 配置maven打包 配置SSH 保存之后 立即构建 执行成功

随机推荐

  1. C. Bank Hacking 解析(思維)

    Codeforce 796 C. Bank Hacking 解析(思維) 今天我們來看看CF796C 題目連結 題目 略,請直接看原題. 前言 @copyright petjelinux 版權所有 觀 ...

  2. scrapy和scrapy-redis 详解一 入门demo及内容解析

    架构及简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. Scrapy 使用了 Twisted(其主要对手是Tornado)异步网络框架来处理 ...

  3. C 语言编程习惯总结

    笔者能力有限,如果文中出现错误的地方,还请各位朋友能够给我指出来,我将不胜感激,谢谢~ 引言 编程习惯的培养需要的是一个长期的过程,需要不断地总结,积累,并且我们需要从意识上认识其重要性,一个良好的编 ...

  4. k8s各组件启动时, -v参数指定的日志级别

    k8s 相关组件启动时 -v参数指定的日志级别 --v=0 Generally useful for this to ALWAYS be visible to an operator. --v=1 A ...

  5. CodeForces 1025G Company Acquisitions

    题意 描述有点麻烦,就不写了. \(\texttt{Data Range:}1\leq n\leq 500\) 题解 势能函数这个东西好神啊-- 这个题目用常规的 DP 好像做不出来,所以我们可以考虑 ...

  6. 工业级4G路由器有哪些优势

    在金融.电力.邮政以及气象等各大行业中有着更为广泛的应用,并受到人们的高度推崇与青睐,那么工业级4G路由器有哪些优势深受用户的喜欢呢? 1.高稳定性 工业级4G路由器在传输和接收数据时具有较高的稳定性 ...

  7. DTU有哪些功能特点?

    DTU指的是一种数据终端设备(Data Terminal unit),可以把它简单理解为下位GPRS发射终端,在进行通信的时候,传输数据的链路两端肯定是存在DTU,所传信息进行格式转换和数据整理效验都 ...

  8. python给图片添加文字

    如何用几行代码给图片加上想要的文字呢? 下面为大家说下实现过程. 关注公众号 "轻松学编程"了解更多. 有图如下,想添加自写的诗句 诗句 静安心野 朝有赤羽暮落霞, 小舟载我湖旋停 ...

  9. 浅析 AC 自动机

    目录 简述 AC 自动机是什么 AC 自动机有什么用 AC 自动机·初探 AC 自动机·原理分析 AC 自动机·代码实现 AC 自动机·更进一步 第一题 第二题 第三题 从 AC 自动机到 fail ...

  10. windows编译openssl(64位)一游

    编译openssl,一套标准流程: (环境:  win10 64位os, vs2019) 需要的工具:perl     nasm   openssl源码包 1  安装perl 2  下载nasm,将n ...