GitOps 是目前比较理想的方法来实现基于 Kuberentes 集群的持续部署。
了解了 [GitOps 的概念以及 CI/CD 流水线的架构](https://dev.amazoncloud.cn/column/article/64256901add53077e881c79d),接下来我们将通过以下四个模块逐步完成构建 CI/CD 流水线的最佳实践:
1. 通过 IaC 部署云基础架构;
2. 在 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 集群上部署 Flux CD;
3. 利用 Flux CD 部署 GitOps 工作流;
4. 利用 GitOps 工作流实现基于镜像的自动部署;
CI/CD 流水线中的代码仓库我们使用 Amazon CodeCommit,CI 部分我们使用 Amazon CodePipeline,CD 引擎使用 GitOps 理念的始作俑者 WeavWorks 的 Flux。我们会详细演示如何在 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 环境搭建符合生产要求的 GitOps 工作流;演示微服务应用如何在以 GitOps 方式构建的 CI/CD 流水线上实现应用的持续集成和持续交付。
# 通过 IaC 部署云基础架构
DevOps 的一个基本原则是以开发人员对待代码的方式来对待基础设施。通过代码部署云上基础架构以及云环境的治理,也就是基础设施即代码 (IaC) 。通过 IaC 开发者能够使用配置文件或代码来定义所需的基础架构,并以编程方式创建基础架构以确保一致性和可重复性。通过 IaC,开发者还可以管理资源的生命周期,比如可以在版本控制存储库中托管基础架构的定义,同时在基础设计及代码的定义修改中可以利用与应用程序代码协调的持续集成和持续部署 (CI/CD),使环境(开发、测试、生产等)与 IaC 代码更改同步。此外,在出现故障时可以自动回滚,并具有漂移检测功能以识别与预期状态的差异。
在云上,开发者可以使用云开发套件 Cloud Development Kit (CDK) 以 Python、Java 和 Typescript 等语言对其基础设施进行建模。CDK 提供了称为构造 Constructs 的高级组件,这些组件使用被验证的默认值预配置云资源。CDK 还允许开发者根据组织的要求编写和共享自己的自定义结构,从而加快新项目的进度。
## 1 使用 CDK CLI 新建项目
使用 cdk init 新建一个 TypeScript CDK 项目。创建了文件夹结构并安装 TypeScript CDK 项目所需的一些必要模块。
```js
mkdir -p ~/environment/quickstart
cd ~/environment/quickstart
cdk init --language typescript
```
## 2 使用 EKS Blueprints 创建 EKS 集群
EKS Blueprints 可帮助开发者构建完整的 EKS 集群。通过 EKS Blueprints 将 EKS 环境所需状态的配置(例如控制平面、工作节点和 Kubernetes 附加组件)描述为 IaC 蓝图。配置蓝图后,开发者可以使用它通过持续部署自动化来消除跨多个亚马逊云科技账户和区域的一致环境。同时,开发者可以使用 EKS Blueprints通过 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 插件以及各种流行的开源插件轻松引导 EKS 集群,包括 Prometheus、Karpenter、Nginx、Traefik、Amazon Load Balancer Controller、Fluent Bit、Keda 、ArgoCD 等。EKS Blueprints 还可以实施来自同一个集群多个团队运行操作工作负载所需的相关安全控制。
执行以下代码,安装项目的依赖:
```js
npm install @aws-quickstart/eks-blueprints@1.3.0 typescript@~4.8.4 --save
```
左滑查看更多
打开 lib/quickstart-stack.ts 编写 EKS Blueprints 代码:
```js
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as blueprints from '@aws-quickstart/eks-blueprints';
import { KubernetesVersion } from 'aws-cdk-lib/aws-eks';
export class QuickstartStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const account = props?.env?.account!;
const region = props?.env?.region!;
const clusterProvider = new blueprints.GenericClusterProvider({
version: KubernetesVersion.V1_23,
managedNodeGroups: [
{
id: "default-ng",
desiredSize: 2,
minSize: 1,
maxSize: 2,
}
]
});
const cluster = blueprints.EksBlueprint.builder()
.clusterProvider(clusterProvider)
.account(account)
.region(region)
.addOns(
new blueprints.AwsLoadBalancerControllerAddOn,
)
.teams();
}
}
```
左滑查看更多
在上述代码中,我们创建了一个 EKS 集群,定义了它的 NodeGroup,并且添加了 AwsLoadBalancerController 插件。
> **最佳实践**
>
> 我们建议通过 clusterProvider 自定义集群参数,通过 EKS Blueprints 内置的 addOns 添加插件。
虽然利用 CDK 命令行工具部署一个堆栈很方便,但我们建议设置自动 Pipeline,负责部署和更新 EKS 基础设施。这样更方便使用框架的代码管道堆栈在不同地区部署开发测试和生产环境。
CodePipelineStack 是一种持续交付 Amazon CDK 应用程序的结构。每当将 Amazon CDK 应用程序的源代码上传 Git 时,堆栈可以自动构建、测试和部署新版本。如果添加了应用程序阶段或堆栈,也会自动重新配置自身以部署这些新阶段或堆栈。
![8ac313048d3eb9581ed30687f7ddb375.png](https://dev-media.amazoncloud.cn/f633ef8f735a4e33af591130aa56c79f_8ac313048d3eb9581ed30687f7ddb375.png "8ac313048d3eb9581ed30687f7ddb375.png")
> **最佳实践**
>
> 把基础设施通过 CDK 代码定义,使用 Pipeline 管理多集群的变更,也是 GitOps 理念的一种落地形式。
随后我们可以执行 cdk deploy 命令,部署该堆栈。
```js
cdk deploy
```
完成集群部署后,查询信息
```js
kubectl get ns
```
看到输出如下:
![b3f40bc70150b92cb827c02d7edaac18.png](https://dev-media.amazoncloud.cn/34ea22b717ab4a95b2f0949b59a08635_b3f40bc70150b92cb827c02d7edaac18.png "b3f40bc70150b92cb827c02d7edaac18.png")
最后通过命令查看 Amazon Application Load balancer 是否成功安装:
```js
kubectl get pod -n kube-system
```
查看输出,确认 Amazon Application Load balancer 部署成功:
![71eb81d73e9bd157773a60dc6681f449.png](https://dev-media.amazoncloud.cn/7eddc5fc18c14c57a62d09cf8478084c_71eb81d73e9bd157773a60dc6681f449.png "71eb81d73e9bd157773a60dc6681f449.png")
## 3 小结
以上内容我们介绍了 IaC 的概念,并且通过使用 CDK 创建了一个自定义 EKS 集群,同时安装了 Amazon Application Load balancer 插件,为后续访问微服务的 web 页面提供了前置条件:
- 通过 cdk init 初始化 CDK 项目
- 通过 EKS Blueprint 快速定义 EKS 集群,同时添加 Amazon Application Load balancer 插件
# 在 Amazon EKS 集群上部署 Flux CD
Flux CD 是一个持续交付工具。Weaveworks 最初开发了该项目,然后将其开源到 CNCF。它成功的原因是它可以感知 Kubernetes 变化并且易于设置。它提供的最亮点的功能是,它允许团队以声明方式管理其 Kubernetes 部署。Flux CD 通过定期轮询存储库来将存储在源代码存储库中的 Kubernetes manifests 文件与 Kubernetes 集群同步, 因此团队无需担心运行 kubectl 命令和监视环境以查看他们是否部署了正确的工作负载。Flux CD 确保 Kubernetes 集群始终与源代码存储库中定义的配置保持同步。
## 1 Flux 客户端安装
Flux CLI 是所有平台的二进制可执行文件,可以从 GitHub 发布页面下载:
```js
curl -s https://fluxcd.io/install.sh | sudo bash
. <(flux completion bash)
```
左滑查看更多
## 2 准备 Amazon CodeCommit 凭证
创建用户,我们实验中使用 CodeCommit 作为 Git 源,需要 Amazon CodeCommit 的 HTTPS Git 凭证:
```js
aws iam create-user --user-name BuildingModernCodeCommitUser
aws iam attach-user-policy --user-name BuildingModernCodeCommitUser --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitPowerUser
aws iam create-service-specific-credential --user-name BuildingModernCodeCommitUser --service-name "codecommit.amazonaws.com" >> ~/environment/credential.json
```
左滑查看更多
把生成的 Amazon CodeCommit 的 HTTPS Git 凭证保存到 credential.json 文件:
![34bff20d6b764e9f50ace05f4ddc4065.png](https://dev-media.amazoncloud.cn/52e3521b525f45fa9e7ca3d60ff5377f_34bff20d6b764e9f50ace05f4ddc4065.png "34bff20d6b764e9f50ace05f4ddc4065.png")
## 3 在集群上安装 Flux
Clone 准备好的 GitOps 代码:
```js
cd ~/environment
git clone codecommit::us-west-2://gitops
cd gitops
```
左滑查看更多
项目结构如下:
![ca3a66ac02437fbf959cdb55d3bb7454.png](https://dev-media.amazoncloud.cn/6597c42dc2ca475190c00e5f77e7f39b_ca3a66ac02437fbf959cdb55d3bb7454.png "ca3a66ac02437fbf959cdb55d3bb7454.png")
> **最佳实践**
>
> 该项目结构是我们推荐的一种,我们把 flux 相关资源分为了基础设施层(infrastructure)、集群管理层(clusters)和应用层(apps)。我们通过 Kustomization (base、overlays)实现了多集群部署的支持。
使用 flux bootstrap 命令在 Kubernetes 集群上安装 flux,并将其配置为从 Git 存储库管理自己。如果集群上存在 Flux 组件,则引导命令将在需要时执行升级。引导程序是幂等的,可以安全地运行命令任意次数。用 Amazon CodeCommit 的 HTTPS Git 凭证替换下面命令中的 username 和 password。
```js
flux bootstrap git \\
--url=https://git-codecommit.us-west-2.amazonaws.com/v1/repos/gitops \\
--username=__替换成Git凭证_username_ \\
--password=__替换成Git凭证_password__ \\
--token-auth=true \\
--path="./clusters/dev-cluster" \\
--components-extra=image-reflector-controller,image-automation-controller
```
左滑查看更多
*注意:
启用镜像自动更新功能,bootstrap Flux 时需要加上 --components-extra=image-reflector-controller,image-automation-controller 参数。*
用 git pull 查询引导程序提交的更新,会看到 Git 仓库 clusters/dev-cluster/flux-system 目录下会新增 3 个文件:
- gotk-components.yaml:定义了 Flux 的 6 个 controller,分别是:helm、kustomize、source、notification、image-automation、image-reflector。
- gotk-sync.yaml:Flux 的 Git 源,集群中的 Source Controller 会监听 gitops 仓库的代码变更,并执行相应的变更。
- kustomization.yaml:多集群配置
通过命令 flux get kustomizations –watch 检查 Flux 是否安装成功,输出类似:
![57274bc44aae03d18b383b0500adcaa5.png](https://dev-media.amazoncloud.cn/c569de7e9561473cb67259c813e69331_57274bc44aae03d18b383b0500adcaa5.png "57274bc44aae03d18b383b0500adcaa5.png")
通过命令:kubectl -n flux-system get pod,services 检查 flux-system 部署的组件,输出如下:
![7308cbd3d1bbf2bd68503d9c08f00b1e.png](https://dev-media.amazoncloud.cn/a3162a7c3f4f4ba29016fccb20c10f46_7308cbd3d1bbf2bd68503d9c08f00b1e.png "7308cbd3d1bbf2bd68503d9c08f00b1e.png")
## 4 小结
在这一部分我们使用 flux bootstrap 命令在 Kubernetes 集群上安装 flux,并且介绍最重要的 3 个配置文件 gotk-components.yaml,gotk-sync.yaml 和 kustomization.yaml:
- Flux 客户端安装
- 创建 IAM 用户,并且创建 CodeCommit 凭证
- 在 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 集群安装 Flux,并且启用镜像自动更新功能
使用 GitOps 工具 FluxCD 实现管理云环境下的 [Amazon EKS](https://aws.amazon.com/cn/eks/?trk=cndc-detail) 集群的微服务自动发布,本文详细实践了 GitOps 流水线的前两个部分。在下一篇文章中,我们将继续分享:
1. 利用 Flux CD 部署 GitOps 工作流;
2. 利用 GitOps 工作流实现基于镜像的自动部署;
请持续关注 Build On Cloud 微信公众号,了解更多面向开发者的技术分享和云开发动态!
### 往期推荐
[Generative AI 新世界](https://mp.weixin.qq.com/s/aIDvCOA98n2SeGWVHzqj1w?trk=cndc-detail)
[亚马逊的开源文化](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=Mzg5Mzg1NDc2NQ==&action=getalbum&album_id=2779048236732137474&scene=21#wechat_redirect?trk=cndc-detail)
[开发者生态](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=Mzg5Mzg1NDc2NQ==&action=getalbum&album_id=2779048236715360257&scene=21#wechat_redirect?trk=cndc-detail)
### 文章作者
![Betty200.png](https://dev-media.amazoncloud.cn/eeb75c0614994615a9d95bb406998a74_Betty200.png "Betty200.png")
**郑予彬**
亚马逊云科技资深开发者布道师
20 年 ICT 行业和数字化转型实践积累,专注于亚马逊云科技云原生、云安全技术领域。18 年架构师经验,致力于为金融、教育、制造以及世界 500 强企业用户提供数据中心建设以及软件定义数据中心等解决方案的咨询及技术落地。
![阙铭飞200.jpg](https://dev-media.amazoncloud.cn/1a5b38b6b0734da289b3e84b008b151e_%E9%98%99%E9%93%AD%E9%A3%9E200.jpg "阙铭飞200.jpg")
**阙铭飞**
亚马逊云科技大中华区解决方案研发中心-解决方案架构师
任职亚马逊云科技大中华区解决方案研发中心-解决方案架构师,负责解决方案研发工作。到目前为止有 10 年的工作经验,主要涉及大数据、DevOps、容器化等相关工作。
![dc8e0f81f65186ee59f9b87f53deba0e.jpg](https://dev-media.amazoncloud.cn/a5e956dcfa88449a998224c11c460c02_dc8e0f81f65186ee59f9b87f53deba0e.jpg "dc8e0f81f65186ee59f9b87f53deba0e.jpg")