亚马逊AWS官方博客

使用 Amazon EKS 和 Jenkins X 持续交付

Amazon Elastic Container Service for Kubernetes (Amazon EKS) 为使用 Kubernetes 构建和部署现代云应用程序提供了容器编排平台。Jenkins X 使用 Kubernetes 构建以为此类应用程序提供自动化的 CI/CD。Amazon EKS 与 Jenkins X 携手提供了一个持续交付平台,让开发人员可以专注于自己的应用程序。本博文由 Henryk Konsek 撰写,介绍了如何依据 GitOps 原则实现 CI/CD 需求的自动化,从而提高您的效率。

我们都想成为高效率的团队,遵循 Accelerate 手册State of DevOps 报告提出的最佳实践。这包括使用持续集成和持续交付、使用基于主干的开发以及用好云等实践。

现在,用好云意味着要使用 Kubernetes 等容器管理平台,实现对任何云基础设施上容器的自动化运行和负载均衡。它也意味着弹性扩展节点和容器,所有这些都可以由您的云提供商来管理。

Amazon EKS 是 AWS 的托管 Kubernetes 产品,可让您专注于构建应用程序,而将管理 Kubernetes 和底层云基础设施的任务交给 AWS 来处理。

Jenkins X 在 Kubernetes 之上构建,提供自动化的持续集成和持续交付,方便团队迁移到 Kubernetes 并使用 Accelerate 手册列举的最佳实践实现自动化的 CI/CD。

本博文依托 Jenkins X 项目,演示了如何发挥 Amazon Elastic Compute Cloud (Amazon EC2)、Amazon Route 53、Amazon Elastic Container Registry (Amazon ECR) 和 Amazon EKS 等 AWS 产品的强大能力来为持续交付管道夯实基础。

您将会创建什么

下图演示了我们将要构建的对象。我们的目标是使用 Elastic Load Balancing (ELB) 和 Route 53 域映射技术部署一个面向外部世界的 EKS 集群。在集群内部,我们希望建立一个 Jenkins 服务器(响应 Git 的变化),该服务器将可以启动基于 Kubernetes 的编译,最终获得推送到 Elastic Container Registry (ECR) 中的 Docker 映像。最后,我们希望 Jenkins 将我们的应用程序映像部署到一个 EKS 集群中并通过进站流量与外部接触。对我们基础设施和应用程序的所有持续性需求都将由 Amazon 服务来处理,例如将由 ECR 或 Kubernetes 连续卷使用的 Amazon Elastic Block Store (Amazon EBS)。

插图:我们将创建什么

在 Route 53 中配置项目域

首先让我们来配置一个域,以便客户访问我们的应用程序以及我们的开发运营团队访问我们的 Jenkins 服务器,从而开始我们的持续交付之旅。

请记住从技术上看,我们可以使用 nip.io 服务而不是真实的域,因为 Jenkins X 原生提供 nip.io 支持。如果您希望采用 nip.io 方案,只需在安装阶段建议使用 1.2.3.4.nip.io 域按下回车键即可(其中 1.2.3.4 将替换为安装程序为您设置的网络负载均衡器 IP 地址)。然后 foo.bar.1.2.3.4.nip DNS 名称将解析至您的 IP 地址,1.2.3.4 为您提供了一个万能 DNS,无需真正接触 DNS 或 Route 53。

但在本博文中,我们将演示如何使用 Route 53 正确添加真实的域,并指令 Jenkins X 使用它。

如要向 AWS 添加域,请在 AWS 控制台选择 Route 53 Service,然后单击蓝色 Create Hosted Zone(创建托管区)按钮。在对话框中,键入您的域名并单击蓝色创建 按钮。在下例中,我们将使用 konsek.cloud 域。

创建托管区对话框

创建托管区后,您应会在 Route 53 控制台中看到它。

Route 53 控制台显示托管区

如果购买了 AWS 之外的域,您的域配置应将您的托管区 NS 记录中定义的域名服务器委托给 AWS,如下图所示:

将您的托管区 NS 记录中定义的域名服务器委托给 AWS

DNS 的更改可能需要几分钟才能完成发布,但从这时开始,您的域已经可由 Jenkins X 使用。

安装 Jenkins X cli 客户端

Jenkins X cli 客户端叫做 jx。它用于管理 Jenkins X 基础设施以及您的持续交付管道。有关如何安装 jx 的详细说明请参阅此处

成功安装 jx 客户端后,您应该可以执行以下命令来显示 jx 客户端的版本:

$ jx version
jx                 1.3.366

创建 EKS Kubernetes 集群

现在我们已经安装了 jx 客户端,可以开始创建将用于运行 Jenkins X 服务器、CI 编译和应用程序本身的 EKS 集群。Jenkins X 借助 eksctl 项目的力量让这一任务变得极为简单。不要担心您是否安装有 eksctl、kubectl(Kubernetes 客户端)、 Helm(Kubernetes 封装管理程序)或 Heptio Authenticator for AWS:jx 将会检测任何缺失的程序并自动为您下载安装。

开始使用 EKS 之前,请确保您已经设置了 AWS 凭证。Jenkins X 客户端十分智能,可以从标准的 AWS cli 位置检索 AWS 凭证,包括环境变量或 ~/.aws 配置文件。在此例中,我们可以仅使用环境变量:

export AWS_ACCESS_KEY_ID=myAccessId
export AWS_SECRET_ACCESS_KEY=mySecret

让我们使用 EKS 创建新的 Kubernetes 集群:

jx create cluster eks --cluster-name=konsek-cloud --skip-installation=true

此命令的执行可能需要一些时间,因为 eksctl 会等待 EKS 集群完全初始化。但在命令完成后,您将能够立即用下面的 jx 命令查看集群:

$ jx get eks
NAME
konsek-cloud

或者在 AWS Web 控制台中显示它:

您应该还可以看到与您的集群关联的 EC2 工作线程节点。

与集群关联的 EC2 工作线程节点

将 Jenkins X 平台安装到 Kubernetes 集群

现在 EKS 集群已经上线运行,我们可以将 Jenkins X 平台安装集群中。Jenkins X 平台由 Jenkins 服务器本身、一个 Nexus 服务器、存储在 Kubernetes 中的配置以及多个其他组件组成,这些组件全部封装在一个 Helm 图中。Jenkins X 平台可以使用如下命令安装:

jx install --provider=eks --domain=konsek.cloud --default-environment-prefix=konsek-cloud

在安装期间,jx 可能会要求您确认一些设置,其中大部分都与 Git 配置有关。Jenkins X 遵循 GitOps 原则 并使用 git 来存储环境部署定义。Kubernetes 中部署的 Jenkins 服务器也使用同样的 git 配置来访问您的应用程序源。jx 默认假设您使用的是 GitHub,当然也支持其他 git 提供商(包括 BitBucket 和 GitLab)。

jx 要求您定义一个 API 令牌,以用于代表您访问 Git 存储库。

定义 GitHub API 令牌

直接按照 jx 的提示生成 API 令牌(单击 jx 为您提供的链接)。在 GitHub 对话窗口中,如下所示提供令牌的唯一名称:

新的个人访问令牌对话框

单击绿色 Generate Token 按钮,复制令牌的值,然后将它粘贴到 jx cli 输入中。

在安装过程中,您可能会注意到 jx 会自动打开在 http://jenkins.jx.your.domain.com 地址(此例中为 http://jenkins.jx.konsek.cloud,)上运行的 Jenkins 服务器,并登录该服务器,然后保存一些设置。这只是 jx 使用无标头浏览器 自动化来代表您生成 Jenkins API 令牌。此令牌稍后将由 Jenkins X 在内部用于代表您自动创建 Jenkins 作业。

Jenkins 登录

几分钟后,jx 安装命令应会完成 Jenkins X 平台的创建。此外,它还应告诉您可用于访问 Jenkins 服务器的 URL 以及此服务器的随机管理员密码。

创建 GitHub webhook 屏幕

在此例中,URL 为 http://jenkins.jx.konsek.cloud,jx 生成的随机管理员密码为 toothglory。现在拥有了 Jenkins 凭证,我们可以登录 Jenkins 服务器并看到 Jenkins 已经成功为我们预置了两个环境:一个为暂存环境,另一个为生产环境。

Jenkins 控制台 — 创建的暂存环境和生产环境

您还可以导航至 GitHub 并看到 Jenkins X 预置了代表 Jenkins 刚刚构建的环境的 Helm 图定义的项目。

Jenkins 预置的 GitHub 项目

现在我们跳回 Route 53 中域的配置。正如您可以看到,Jenkins X 为 AWS Elastic Load Balancer 创建了新的 *.konsek.cloud DNS CNAME 条目。此 ELB 又指向一个 Kubernetes Nginx Ingress 控制器。从而可让我们可以通过 Internet 访问 http://jenkins.jx.konsek.cloud 地址。

创建记录集

创建新的 Spring Boot 项目

现在我们的 Kubernetes 集群已经运行并且安装了 Jenkins X,我们可以创建我们的第一个项目并尝试使用我们的 CD 管道将它部署到集群中。Jenkins X 支持许多不同的项目类型,自带一组好用的快速入门,我们可以用这些快速入门轻松启动新的应用程序。在此例中,我们将使用如下 jx 命令,从 Spring Boot 初始化程序中创建一个通用的 Spring Boot REST 应用程序:

jx create spring -d web -d actuator

在创建新应用程序过程中,jx 将向您询问项目名称、您希望为项目使用的语言、Maven 坐标等等信息。

jx 问题回答屏幕

此处 Jenkins X 通知我们已经在本地笔记本电脑上创建了应用程序,推送到远程 GitHub 存储库中,并添加到 Jenkins X CD 管道中。下面我们来确认这是真的! 执行 jx get pipe 命令并自行查看:

jx get pipe 命令

上述命令将会显示 Jenkins X 中注册的管道列表。正如您可以看到,我们安排了专门的管道来处理应当应用到暂存环境和生产环境的更改。此外还有一个专门的管道用于构建我们的新 Spring Boot 应用程序,而且恰恰它现在正在构建。您还可以使用 Jenkins UI 来查看管道的进度。

使用 Jenkins UI 来查看管道进度

应用程序管道完成后,您可以在 jx 客户端提供的列表中看到该应用程序。如要查看此列表,请执行 jx get app 命令。

jx get app 命令

Jenkins X 现在已经构建了应用程序并部署到暂存环境中。让我们使用 jx 命令输出提供的应用程序 URL(此例中为 http://eks-demo.jx-staging.konsek.cloud)来看它是否已经上线运行:

Spring Whitelabel 错误消息

如果您看到 Spring Whitelabel 错误消息,则说明应用程序已经成功部署到 EKS 集群并通过 Ingress 控制器开放。

下面我们来尝试在应用程序中进行一些修改,例如将一些文本添加到项目 readme 文件中。

为项目readme 文件添加一些文本示例

Jenkins X 需要一些时间完成项目的重新构建和重新部署,然后再看 jx get app 的输出:

jx get app 输出版本 2

您可以看到,应用程序的版本从 0.0.1 变为了 0.0.2。

下面来看将新项目导入 Jenkins X 或触发版本控制变更时发生了什么。

AWS 上的 GitOps

Jenkins X 遵循 GitOps 原则向您的环境部署和升级应用程序(开发 -> 暂存 -> 生产)。简而言之,GitOps 部署方法意味着您在有版本控制的系统中存储环境配置,例如在描述给定环境部署内容的 YAML 文件。这种方法符合 Kubernetes 公布的通用理念,即您需要规定您希望保持的预期环境状态,而由 Kubernetes 其他工具在核对循环实现该状态。

每次您对应用程序作出更改时,Jenkins X 都会检测到更改并尝试构建应用程序。构建通常首先从运行测试以及对项目进行所有必要的预检查开始,然后是实际的 Docker 映像构建阶段,最后将有版本控制的 Docker 映像推送到 ECR 注册表中。Jenkins X 将根据 git 项目创建一条 pull 请求,其中包含应向其部署映像的环境的配置。这一条 pull 请求包含一条使用更新 Docker 映像版本的建议。如果 Jenkins X 可以成功部署所请求的更改,则 pull 请求会合并到主分支。否则 Jenkins X 会创建部署作业日志,可以用该日志来查看导致部署失败的原因。

Pull 请求和预览环境

遵循《Accelerate 手册》中提出的高效团队最佳实践,我们建议采用基于主干道开发方法(从分支发布),始终保持发布分支的干净和正常工作。因此,我们建议您按小的批次开发代码,然后频繁通过短暂的 pull 请求提交代码。

当您创建 pull 请求时,Jenkins X 会自动触发一个管道来验证您的代码能够编译并且测试将会运行。它还会为每个 pull 请求生成一个动态的预览环境,部署建议代码,并在该 pull 请求的备注中添加您可以用来尝试应用程序的链接:

Pull 请求的预览环境

这在您开发 Web 应用程序时将尤其有用,从而让您的团队可以快速检查更改,查看对布局、CSS 或行为的更改是否与需求相符。

在 Jenkins X 上开发

虽然我们演示的例子使用 Spring Boot,但 Jenkins X 也支持许多编程语言和编译工具。一个替代方式是通过 quickstart

jx create quickstart

此命令会返回以不同编程语言和运行时的示例应用程序列表。

如果您的笔记本电脑上已经有一些您希望导入 Jenkins X 的源代码,您可以通过如下命令导入

jx import

在您安装好 Jenkins X 并创建或导入应用程序的代码后,您将通过 git 提交和 pull 请求以普通的 git 方式来处理您的源代码,剩余的任务都交由 Jenkins X 自动完成。您的开发团队无需担心 Kubernetes、Docker 映像、Jenkins 管道或 GitOps 等细节,您可以专注于应用程序代码,并将大部分时间用于您中意的 IDE!

 

 

Henryk Konsek

Henryk Konsek

Henryk 现为 Capsilon Corporation (https://capsilon.com) 首席架构师。他专长于云技术的采用,是 AWS、开发运营、CI/CD、Jenkins 和 Spring 生态系统的拥趸。

本博文中的内容和意见属于第三方作者,AWS 不对本博文的内容或准确性负责。