亚马逊AWS官方博客
在 Amazon EKS 上使用 Jenkins 和 HashiCorp Terraform 实现持续集成
这篇博客文章是 Amazon Web Services 与 HashiCorp 合作的成果。HashiCorp 是 AWS 合作伙伴网络 (APN) 的高级技术合作伙伴,在开发运营和容器方面均具有 AWS 能力。
简介
有些客户在 Amazon Elastic Kubernetes Service (Amazon EKS) 上运行基于微服务的应用程序,他们需要使用 Jenkins 和 Spinnaker 构建完整的端到端持续集成 (CI) 和持续部署/交付 (CD) 管道方面的指导。Jenkins 是非常流行的 CI 服务器,具有强大的社区支持和许多插件 (Slack、GitHub、Docker、Build Pipeline) 可用。Spinnaker 提供自动发布和内置部署功能,并支持即开即用的蓝/绿部署。
这篇文章是在 Amazon EKS 上使用 Spinnaker 实现持续交付的姊妹篇,重点关注持续集成,并将讨论使用 Hashicorp Terraform 在 Amazon EC2 上安装和配置 Jenkins。我们还将讨论 Spinnaker 管道的创建,此过程是实现强大的协调和分支的各个阶段的组合。这些管道可以手动启动,也可以由事件自动触发,例如 Docker 注册表中出现的新 Docker 映像。这篇文章中使用的其他服务和技术包括 Amazon EC2、AWS Cloud9、Docker Hub 和 Amazon EKS。
概念概述
Terraform
Terraform 是用于安全高效地构建、更改和版本控制基础设施的工具。它通过易于使用的命令行界面 (CLI) 以及免费使用的名为 Terraform Cloud 的 SaaS 产品和用于企业的专用设备进行控制。Terraform 可以管理现有和流行的服务提供商以及定制的内部解决方案。配置文件向 Terraform 描述了运行单个应用程序或整个数据中心所需的组件。Terraform 生成执行计划,以描述达到预期状态所需执行的操作,然后执行该计划以构建所描述的基础设施。配置更改时,Terraform 能够确定更改的内容并创建可以应用的增量执行计划。Terraform 的主要功能包括:基础设施即代码、执行计划、资源图和变更自动化。
Jenkins
Jenkins 是一个自包含的开源自动化服务器,可用于自动化与构建、测试以及交付或部署软件有关的各种任务。它可以通过本机系统软件包 Docker 安装,甚至可以由安装有 Java Runtime Environment (JRE) 的任何计算机独立运行。
先决条件
为了实现本文中的说明,您需要以下资源:
架构
本文中,我们将讨论下列适用于持续集成的架构:
图 1.持续集成架构
步骤概述:
- 使用 Terraform 创建 Jenkins CI 服务器。
- 配置 Jenkins。
- 配置 Jenkins 作业和管道。
- 创建和配置 Spinnaker 管道。
- 手动运行 Spinnaker 管道。
- 使用 AWS Cloud9 修改代码并推送代码更改。
- 清理。
使用 Terraform 创建 Jenkins CI 服务器
手动预置 Jenkins CI 服务器可能容易出错且耗时,因此我将使用“基础设施即代码 (IaC)”方式配置 Jenkins Continuous Server (CI)。在本博文论述中我将使用 Terraform。登录到 AWS 管理控制台并创建一个 EC2 密钥对(在我的示例中,密钥对的名称为 ibuchh-key
)。使用您的 GitHub 账户,派生 https://github.com/aws-samples/amazon-eks-jenkins-terraform.git 上的代码示例存储库
在 AWS Cloud9 IDE 中,打开一个 shell 终端并执行以下操作(用您的 GitHub 账户替换 aws-samples
):
git clone https://github.com/aws-samples/amazon-eks-jenkins-terraform.git
cd amazon-eks-jenkins-terraform/terraform/
terraform init
terraform plan
terraform apply -auto-approve
图 2.Terraform apply 的输出
Terraform apply
还将输出 Jenkins CI 服务器的 IP 地址,如上所示。
Terraform 将预置一个 AWS EC2 实例,并如 install_jenkins.sh
文件所示安装 git、Apache Maven、Docker、Java 8 和 Jenkins:
#!/bin/bash
sudo yum -y update
echo "Install Java JDK 8"
sudo yum remove -y java
sudo yum install -y java-1.8.0-openjdk
echo "Install Maven"
sudo yum install -y maven
echo "Install git"
sudo yum install -y git
echo "Install Docker engine"
sudo yum update -y
sudo yum install docker -y
sudo sudo chkconfig docker on
echo "Install Jenkins"
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install -y jenkins
sudo usermod -a -G docker jenkins
sudo chkconfig jenkins on
echo "Start Docker & Jenkins services"
sudo service docker start
sudo service jenkins start
使用浏览器,打开页面 http://jenkins_ip_address:8080,这将显示 Jenkins 管理员页面:
图 3.Jenkins 管理员页面
使用 AWS Cloud9 shell 终端,登录到 Jenkins CI 服务器,通过运行以下命令找到管理员密码:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
将其粘贴到输入框中,从而在 Jenkins 控制台上输入管理员密码,然后单击下一步。 单击安装建议的插件。
配置 Jenkins
1.插件:
登录 Jenkins 控制台,单击管理 Jenkins → 管理 Plugins → 可用。选择并安装 Docker 插件 和 GitHub 集成插件,然后通过单击“重启 Jenkins”复选框重新启动 Jenkins,如下所示:
图 4.Jenkins 插件
2.凭据:
Docker Hub:单击凭据 → 全局 → 添加凭据,在具有密码的用户名选择种类,输入 Docker Hub 用户名和密码并使用 dockerHubCredentials
作为 ID。
GitHub:单击凭据 → 全局 → 添加凭据,在具有密码的用户名选择种类,输入 GitHub 用户名和密码并使用 gitHubCredentials
作为 ID。
配置 Jenkins 作业和管道
在 Jenkins 控制台中,单击新建项目。选择多分支管道,将其命名为 petclinic
然后单击确定。
图 5.Jenkins 多分支管道
选择 GitHub,然后从下拉列表中选择 GitHub 凭据。输入如下所示的 GitHub URL,然后单击保存以保存 Jenkins 作业。
图 6.Jenkins 作业详细信息
Jenkins 构建执行器将检出并扫描 GitHub 存储库,并按照下面显示的 Jenkins 文件中的规定执行管道中的阶段。确保将注册表替换为构建阶段中 Docker 注册表 URL。
pipeline {
agent any
triggers {
pollSCM "* * * * *"
}
stages {
stage('Build Application') {
steps {
echo '=== Building Petclinic Application ==='
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test Application') {
steps {
echo '=== Testing Petclinic Application ==='
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Build Docker Image') {
when {
branch 'master'
}
steps {
echo '=== Building Petclinic Docker Image ==='
script {
app = docker.build("ibuchh/petclinic-spinnaker-jenkins")
}
}
}
stage('Push Docker Image') {
when {
branch 'master'
}
steps {
echo '=== Pushing Petclinic Docker Image ==='
script {
GIT_COMMIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'", returnStdout: true)
SHORT_COMMIT = "${GIT_COMMIT_HASH[0..7]}"
docker.withRegistry('https://registry.hub.docker.com', 'dockerHubCredentials') {
app.push("$SHORT_COMMIT")
app.push("latest")
}
}
}
}
stage('Remove local images') {
steps {
echo '=== Delete the local docker images ==='
sh("docker rmi -f ibuchh/petclinic-spinnaker-jenkins:latest || :")
sh("docker rmi -f ibuchh/petclinic-spinnaker-jenkins:$SHORT_COMMIT || :")
}
}
}
}
下面是最终运行的屏幕截图;如果一切顺利,您将看到一个新的 Docker 映像推送到您的 Docker 注册表中。
图 7.管道阶段
创建和配置 Spinnaker 管道
管道是指 Spinnaker 提供的一定顺序的阶段,从操作基础设施的功能(部署、调整、禁用),到支持功能(手动判断、等待、运行 Jenkins 作业),这些功能共同精确定义了管理您部署的操作手册。管道可帮助您一致、可重复且安全地管理部署。
1. 登录到 AWS Cloud9 IDE 环境,然后打开一个新终端。运行以下命令:
kubectl get svc -n spinnaker
图 8.Spinnaker UI 终端节点
2. 打开浏览器,使用 spin-deck-public services
终端节点登录 Spinnaker UI,如上面的输出所示。
选择应用程序选项卡,然后选择操作 → 创建应用程序。 输入 petclinic
作为名称,然后输入有效的电子邮件地址,其余字段留为空白。
图 9.Spinnaker 应用程序
3. 在管道选项卡上,单击配置新管道,输入 DeployToUAT
作为管道名称,然后单击创建。
图 10.Spinnaker DeployToUAT 管道
4. 单击添加构件并选择 GitHub → 种类,文件路径 → kubernetes/petclinic.yaml
,显示名称 → Petclinic-Manifest
,内容 URL →
https://api.github.com/repos/aws-samples/amazon-eks-jenkins-terraform/contents/kubernetes/petclinic.yaml
图 11.管道构件
5. 单击添加触发器并选择类型 → Docker 注册表,注册表名称 → Spinnaker 中配置的 Docker 注册表,组织 → 您的 Docker 注册表名称,映像 → Jenkins 创建的 Docker 映像。
图 12.管道触发器
6. 单击添加阶段,选择阶段类型 → 部署(清单),账户 → eks-uat
,应用程序 → petclinic,清单源 → 构件,清单构件 → Petclinic-Manifest
,构件账户 → spinnaker-github
。
图 13.部署清单阶段
7. 单击保存将更改保存到 DeployToUAT 管道。
8. 在管道选项卡下,单击创建,输入 ManualApproval
作为管道名称,然后单击“创建”。单击添加触发器并选择类型 → 管道,应用程序 → petclinic
,管道 → DeployToUAT
。
图 14.ManualApproval 管道
9. 单击添加阶段,选择阶段名称 → 手动判断,在判断输入下添加两个选项批准
和拒绝
,如下所示:
图 15.手动判断阶段
10. 单击保存将更改保存到 ManualApproval
管道。
11. 在管道选项卡下,单击创建,输入 DeployToProd
作为管道名称,然后单击创建。单击添加触发器并选择类型 → 管道,应用程序 → petclinic
,管道 → DeployToProd
。
12. 单击添加构件并选择 GitHub → 种类,文件路径 → kubernetes/petclinic.yaml
,显示名称 → Petclinic-Manifest
,内容 URL →
https://api.github.com/repos/aws-samples/amazon-eks-jenkins-terraform/contents/kubernetes/petclinic.yaml
图 16.管道构件
13. 单击添加触发器并选择类型 → Docker 注册表,注册表名称 → Spinnaker 中配置的 Docker 注册表,组织 → 您的 Docker 注册表名称,映像 → Jenkins 创建的 Docker 映像。
图 17.管道触发器
14. 单击添加阶段,选择阶段类型 → 部署(清单),账户 → eks-prod,应用程序 → petclinic
,清单源 → 构件,清单构件 → Petclinic-Manifest
,构件账户 → spinnaker-github
。
图 18.部署清单阶段
15. 单击保存将更改保存到 DeployToProd
管道。
手动运行 Spinnaker 管道
现在手动运行三个管道。单击开始手动执行,选择管道 → DeployToUAT,类型 → 标记,标记 → 输入有效的标记号。单击运行并观察管道执行。
图 19.管道执行
使用 AWS Cloud9 修改代码并推送代码更改
让我们使用 AWS Cloud9 推送代码更改,并观察 Jenkins 和 Spinnaker 中端到端的持续集成和持续部署管道的执行情况。打开 AWS Cloud9 并在 messages.properties 文件中将 welcome
更改为 Welcome CI/CD
,然后保存文件。
图 20.推送代码更改
在 AWS Cloud9 中打开 shell 终端并运行以下命令:
cd environment/amazon-eks-jenkins-terraform
git status
git commit -am "change messages.properties"
git push
这会将代码更改推送到 GitHub 存储库,从而触发 Jenkins 管道。Jenkins 管道将运行各个阶段,并将 Docker 映像推送到 Docker Hub 注册表。新 Docker 映像的创建将触发 Spinnaker DeployToUAT
管道,这继而会触发 Manual Approval
管道,如下所示。此时,新的代码更改已交付给 Amazon EKS UAT 集群:即实现了持续交付。
图 21.Spinnaker 管道
选择批准作为判断输入,然后单击继续以批准将触发 DeployToProd
Spinnaker 管道的代码更改。然后,新的代码更改将部署到 Amazon EKS 生产集群:即实现了持续部署。
打开 Amazon EKS 生产集群的负载均衡器终端节点,您将看到新的代码更改:
图 22.应用程序代码更改
清理
要删除 Jenkins 实例,请在 AWS Cloud9 IDE 内运行以下命令:
cd environment/amazon-eks-jenkins-terraform/terraform
terraform destroy -auto-approve
图 23.Terraform destroy
结论
在本文中,我们概述了在 Amazon EKS 上使用 Terraform 和 Jenkins 配置持续集成平台所需的详细说明。Jenkins 可以与 Spinnaker 集成以构建完整的 CI/CD 管道。在 Spinnaker 中将 Jenkins 设置为持续集成 (CI) 系统,您将可以使用 Jenkins 触发管道、在管道中添加 Jenkins 阶段或在管道中添加脚本阶段。要了解有关 Terraform 的更多信息,请参阅 terraform.io 或 Terraform 文档。
本博文中的内容和意见属于第三方作者,AWS 不对本博文的内容或准确性负责。