基础设施即代码

GitOps 一个最基础的工作是基础设施代码化。

基础设施即代码(Infrastructure as Code, IaC),顾名思义,表示使用代码(而非手动流程)来定义基础设施,研发人员可以像对待应用软件一样对待基础设施,
包括对网络配置、虚拟机、负载平衡、连接拓扑等等都使用高级语言进行编码。

对对应用开发所依靠的环境进行标准化后,DevOps 就能够启动、拆解和扩展基础设施,以响应不断波动的需求,这样的敏捷性能够造就更快、更简单的软件开发、测试和部署。

IaC 的优势

置备基础架构历来是一个耗时且成本高昂的手动过程,随着云计算的发展,基础架构的管理已逐渐转移到了虚拟化、容器和云计算,在基础架构之上,有数以百计、千计的服务不断地更新迭代,另外基础架构本身也不断地使用、扩展和移除。在这种状态下,如果没有相应的 IaC 管理实践,大规模的基础架构维护也会变得越来越困难。

使用 IaC 可以提高一致性并减少错误和手动配置,它的优势特点如下:

  • 可以创建包含基础架构规范的声明式配置文件,从而便于编辑和分发配置。
  • 可以确保每次配置的环境都完全相同。
  • 可以进行版本控制,所有的变更都会被记录下来,方便溯源。
  • 可以将基础设施划分为若干个模块化组件,并通过自动化以不同的方式进行组合。

广义上的 IaC 不仅仅只关于基础设施,还包含了网络、安全、配置等等,所以 IaC 又叫 X as Code。

IaC 工具选型

大部分的公有云已经提供了良好的 API 和相应的 IaC 生态,而对于使用混合云的企业,还是需要一些投入将底层基础设施 IaC 化。

云上资源 IaC 化,比较典型的工具是 Terraform。Terraform 可以说是 IaC 概念最早期的奠基项目,生态最为完善,社区也非常活跃,背后也有非常成熟的商业上市公司 HashiCorp 进行支持。Terraform 抽象了 HCL 这门相对简单易学的 DSL 作为资源描述语言,实践中配合 Terragrunt 这个工具(底层基于 Terraform 进行封装)能更好地写出相对紧凑简洁的代码。

另外一个 Crossplane 。基于 Kubernetes 并通过封装好的形形色色的 CRDs 来操作多云资源。

除以上云资源 IaC 化外,还有应用配置的 IaC,现在大部分企业选择 Kubernetes 作为 PaaS 的基座,行于 Kubernetes 之上的所有资源天然就已经被代码化了,其形式就是资源声明式 YAML 配置,但这种方式,过于简单,局限性过大。 从组织的角度来看,需要有对 yaml 更抽象的部署封装,这就是 Kustomize 和 Helm 。

这两个工具本质上就是客户端 YAML 渲染引擎,用以更好的管理 YAML。从易用性的角度来看 Kustomize 更容易,但从功能性和生态来看 Helm 无疑是现在 Kubernetes 上的事实标准。

Helm 有一定的学习门槛。但是它的功能性非常的完善,基本可以满足绝大多数的 YAML 生成需求。而且,Helm 还有相应的包管理机制 Helm Chart,几乎每一个流行的 Kubernetes 应用都会提供相应的 Helm Chart 供用户安装。

Kustomize

如果要在 Kubernets 发布一个应用, 并对外提供服务,需要配置诸如 Deployment、RC、PV、HPA、Service 等资源,并通过 Label 组合选择实现这些资源之间的松耦合。

如果想要这些资源之间的关系更加紧密,我们可以自己再向上抽象封装,通过另外一种配置将他们整合在一起。更重要的是,我们可以通过这层封装,屏蔽不同版本 API 之间差异,实现同一个配置兼容多版本集群,进而实现部署或迁移丝滑。

Kustomize 和 Helm 是 “无状态应用” 封装的典型代表。而 Operator 和 OAM 则是有状态应用的封装代表。

Kustomize

最初 Kubernetes 对如何封装应用 的解决方案是用配置文件来配置文件,这并不是绕口令,可以理解为针对 yaml 模版引擎的变体。

Kubernetes 官方认为,应用就是一组具有相同目标的 Kubernetes 资源的集合,如果逐一管理、部署每项资源元数据过于繁琐的话,那就提供一种便捷的方式,把应用中不变的信息和易变的信息分离,应用中所涉及的资源自动生成一个多合一(All-in-One) 的整合包,以此解决部署管理问题。

完成这项工作的工具就叫 Kustomize。Kustomize 原本只是一个独立的小工具,从 Kubernetes 1.14 起,被纳入了 kubectl 命令中,成为 Kubernetes 内置的功能。

Kustomize 使用 Kustomization 文件来组织与应用相关的所有资源,Kustomization 本身也是一个 yaml 编写的配置文件,里面定义了构成应用的全部资源,以及资源中根据情况被覆盖的变量。

Kustomize 的价值在于根据环境来生成不同的部署配置,只要建立多个 Kustomization 文件,开发人员就能基于基准派生的方式,对应用不同模式(开发、测试),不同的项目(客制)定制出不同的资源整合包。

Kustomize 示例

 ~/someApp
├── base
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── development
    │   ├── cpu_count.yaml
    │   ├── kustomization.yaml
    │   └── replica_count.yaml
    └── production
        ├── cpu_count.yaml
        ├── kustomization.yaml
        └── replica_count.yaml

 

从上面的目录结构中,可以可以观察到一个由 Kustomize 管理的应用结构,它主要由 base 和 overlays 组成。

 kustomize build ~/someApp/overlays/production

 

从效果上看,使用 Kustomize 编译生成的 All-in-One 整合包来部署应用相当方便,只要执行一行命令,就能够把应用所涉及的所有服务一次性安装好。

小结

Kustomize 毕竟只是一个小工具性质的辅助功能, 对于开发人员而言,使用 Kustomize 只能简化应用针对不同情况的重复配置,它其实并没有做到真正解决应用管理复杂的问题。

对于运维人员而言,应用的维护不仅仅只是部署,应用的整个生命周期除了部署还有更新、回滚、卸载、多版本、多实例、依赖维护等诸多工作。所以,要想解决这些问题,还需要更加强大的工具,这就是下面要介绍的 Helm。

Helm

Helm 是由 Deis 公司开发的一种系统性管理和封装 Kubernetes 应用的解决方案,它参考了各大 Linux 发行版管理应用的思路,应用格式是 Chart。(相较于 yum 之 Centos, apt-get 之 Ubunut)。Helm 本质就是 Kubernetes 的包管理器,对于使用者而言,使用 Helm 后不用需要了解 Kubernetes 的 yaml 语法并编写应用部署文件,可以通过 Helm 一行命令下载并在 kubernetes 上安装需要的应用。

Helm 一开始的目标就很明确:如果说 Kubernetes 是云原生操作系统的话,那 Helm 就是要成为这个操作系统之上的应用商店和包管理工具。

相信读者朋友们知道 Linux 下的包管理工具和封装格式, 如 Debian 系的 apt-get 命令和 dpkg 格式,RHEL 洗的 yum 命令和 rpm 格式。在 Linux 系统中,有了包管理工具,我们只要知道应用的名称,就可以很方便地从应用仓库中下载、安装、升级、回滚等,而且包管理工具掌握着应用的依赖信息和版本变更情况,具备完整的自管理能力,每个应用依赖哪些前置的第三方库,在安装时都会一并处理好。

Helm 模拟的就是这种做法,它提出了与 Linux 包管理直接对应的 Chart 格式 和 Repoistory 应用仓库,另外针对 Kubernetes 中特有的一个应用要部署多个版本的特点,又提出了 Release 的专有观念。

总结使用 Helm 可以帮我们解决下面这些问题:

  • 高度可配置:Helm Charts 提供了高度可配置的选项,可以轻松自定义和修改应用程序的部署配置
  • 版本控制 :Helm 允许管理应用程序的多个版本,从而轻松实现版本控制和回滚
  • 模板化:Helm Charts 使用 YAML 模板来定义 Kubernetes 对象的配置,从而简化了配置过程,并提高了可重复性和可扩展性
  • 应用程序库:Helm 具有应用程序库的概念,可以轻松地共享和重用 Helm Charts,从而简化了多个应用程序的部署和管理

Helm 的概念

在使用 Helm 之前,我们先需要理解如下几个核心概念

概念 描述
Chart Helm 的打包格式,内部包含了一组相关的 kubernetes 资源
Repoistory Helm 的软件仓库,用于存储 Charts
Release 在 kubernetes 上运行的 Chart 实例,例如 一个 Redis Chart 想要运行两个实例,可以将 Redis Chart install 两次,并在每次安装生成自己的 Release 以及 Release 名称
Value Chart 参数,用于配置 kubernetes 对象
Template 使用 Go 模版语言生成的 kubernetes 对象的定义文件

Helm 的工作流程

如下图所示, Helm 的工作流程总结如下:

  • 开发者首先创建并编辑 chart 配置
  • 接着打包并发布到 Helm 的仓库
  • 当管理员使用 helm 命令安装时, 相关的依赖会从仓库中下载
  • 接着 Helm 会根据下载的配置部署资源到 kubernetes 中

Chart 应用示例

 WordPress
.
├── Chart.lock
├── Chart.yaml
├── README.md
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── config-secret.yaml
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── svc.yaml
│   └── ...
├── values.schema.json
└── values.yaml

 

Chart 包内有几个固定的配置文件: Chart.yaml 给出了 应用自身的详细信息(名称、版本、许可证、自述、说明等), values.yaml 给出了所有可配置项目的预定义值。

从整体来说, Helm 提供了应用生命周期、版本、依赖项的管理功能,同时 Helm 还支持额外的插件扩展,能加加入 CI/CD 或者其他方面的辅助功能。

Helm 项目安装

Helm 提供了二进制以及脚本安装,我们这里使用二进制的方式安装。国内 Helm 镜像地址:https://mirrors.huaweicloud.com/helm/

  • 下载 需要的版本
  • 解压 tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
  • 在解压目录中找到 helm 程序,移动到需要的目录中 mv linux-amd64/helm /usr/local/bin/helm

添加一个 chart 仓库。

 helm repo add azure https://mirror.azure.cn/kubernetes/charts

 

搜索 chart

 $ helm search repo redis
NAME                           	CHART VERSION	APP VERSION	DESCRIPTION                                       
azure/prometheus-redis-exporter	3.5.1        	1.3.4      	DEPRECATED Prometheus exporter for Redis metrics  
azure/redis                    	10.5.7       	5.0.7      	DEPRECATED Open source, advanced key-value stor...

 
 # 拉取chart包到本地
$ helm pull bitnami/redis-cluster --version 8.1.2
# 安装redis-ha集群,取名redis-ha,需要指定持存储类
$ helm install redis-cluster bitnami/redis-cluster --set global.storageClass=nfs,global.redis.password=xiagao --version 8.1.2
# 卸载
$ helm uninstall redis-cluste

 

  • 无标签
写评论...