云原生应用是什么?

云原生应用程序是由多个称为微服务的相互依赖的小型服务组成的软件程序。
目前主要的云原生应用管理工具主要有 Helm、Kustomize、Porter、Kubevela 等。

云原生应用发展现状

云原生安全风险 云原生管理平台_kubernetes


统计截止时间:2023-05-15

Helm

官方文档地址:https://helm.sh/docs/ github 地址:https://github.com/helm/helm 由于 Kubernetes 部署资源与模版比较分散,导致部署一个应用需要的模版特别多,因此诞生了基于 Kubernetes 的应用管理工具 Helm。

发展历程

云原生安全风险 云原生管理平台_云原生_02


Helm1

2015年10月15日,Helm诞生了。2016年,Helm 加入 Kubernetes 社区。

需要提前编写许多 Kubernetes 编排模板,然后使用类似脚本语言的方式进行渲染,最后把它们提交到 Kubernetes 集群中。

Helm2
2016年1月,Google 的一个研发团队找到 Helm 团队,两家的项目合并,创建了名为 Helm2 的新项目。Helm2 的特性:

  • 定制化 Chart 模板;
  • 构建集群内的管理方式;
  • 构建可以存储 Chart 的仓库;
  • 构建稳定可签名的包格式;
  • 实现强版本控制以及向后兼容性。
    Helm2 增加了一个新组件 ---- Tiller。Tiller 是一个集群内部署的 Pod,负责安装和管理 Chart。

Helm3
Helm2的问题:一个主要问题是需要在k8s集群里面运行一个服务端,而这就需要把tiller的端口暴露给外界,会产生安全隐患。
在helm 2中引入的tiller主要是当时k8s还没有RBAC机制,所以就引入了服务端tiller。
而后来k8s的功能相应完善,加入了RBAC和CRD等,都使得tiller这个东西显得多余。
2019年,Helm3面世。

Helm2 VS Helm3

适用场景

如果你需要向 Kubernetes 集群部署服务,并且你的应用使用了超过一种 Kubernetes 资源,那么在这些场景中,你就需要使用 Helm。
Chart 仓库地址:https://artifacthub.io/

版本支持策略

Helm的版本用 x.y.z 描述,x是主版本,y是次版本,z是补丁版本。

版本偏差

从Helm 3开始,Helm 编译时假定与针对n-3版本的Kubernetes兼容。

例如,如果您在使用一个针对Kubernetes 1.17客户端API版本编译的Helm 3版本,那么它应该可以安全地使用Kubernetes 1.17, 1.16,1.15,以及1.14。

云原生安全风险 云原生管理平台_云原生安全风险_03

[warning]
注:不推荐将Helm用于比编译它所依赖的版本更高的Kubernetes版本,因为Helm并没有做出任何向前兼容的保证。
如果您选择了一个Kubernetes版本不支持的Helm,需自负风险。

Chart 示例

test-chart
├── charts
│   └── mysql-ha
│       ├── Chart.yaml
│       ...
├── Chart.yaml
├── files
│   ├── certificates
│   │   └── ...
├── lib.sh
├── README.md
├── templates
│   ├── development,yaml
│   ├── configmap.yaml
│   ├── ...
├── shell.sh
└── values.yaml

使用 Helm 部署一个应用

# 安装
helm install -f values.yaml --name tn-sandbox
# 更新
helm upgrade -f values.yaml --name tn-sandbox
# 卸载
helm uninstall tn-sandbox
# 列表
helm list

helm list -a

更多命令行请参考:https://helm.sh/zh/docs/helm/

Kustomize

官网地址:https://kustomize.io/ github 地址:https://github.com/kubernetes-sigs/kustomize 官方文档地址:https://kubectl.docs.kubernetes.io/references/kustomize/ Kustomize 是 Google 公司主导开发的一个 Kubernetes 生态应用管理工具,隶属于 CLI 工作组管理。
使用 Kustomize 对 Kubernetes 对象进行声明式管理:https://kubernetes.io/zh-cn/docs/tasks/manage-kubernetes-objects/kustomization/

是什么?

Kubernetes native configuration management
Kustomize introduces a template-free way to customize application configuration that simplifies the use of off-the-shelf applications. Now, built into kubectl as apply -k.

根据官网的描述:kustomize 是 kubernetes 原生的配置管理,以无模板方式来定制应用的配置。kustomize 使用 k8s 原生概念帮助创建并复用资源配置(YAML),允许用户以一个应用描述文件 (YAML 文件)为基础(Base YAML),然后通过 Overlay 的方式生成最终部署应用所需的描述文件。
Kustomize 是一个用来定制 Kubernetes 配置的工具。它提供以下功能特性来管理应用配置文件:

  • 从其他来源生成资源
  • 为资源设置贯穿性(Cross-Cutting)字段
  • 组织和定制资源集合

诞生背景

在 Kubernetes 环境中部署应用时,我们需要一些包含 API 对象的 yaml 文件,当应用所需的服务数量或环境数量很多时,我们就需要有多个不同版本的 yaml 文件来适配,这些不同版本的文件除了细微差别外,其他内容基本一样,这导致对配置文件进行升级时,很容易漏掉一些改动而造成配置错误。因此需要一个具有 yaml 文件版本管理功能的工具,为 Kuebernetes 配置文件提供一种类似代码生命周期管理的功能。
Kustomize 正是为了解决这个问题而生的,它允许用户将不同环境的共享配置放在同一个目录下,而将不同的配置放在其他目录下,用户以一个 yaml 文件为基础,通过 Overlay 的方式生成部署应用所需的描述文件。

解决了什么问题?

一般应用都会存在多套部署环境:开发环境、测试环境、生产环境,多套环境意味着存在多套 K8S 应用资源 YAML。而这么多套 YAML 之间只存在微小配置差异,比如镜像版本不同、Label 不同等,而这些不同环境下的YAML 经常会因为人为疏忽导致配置错误。再者,多套环境的 YAML 维护通常是通过把一个环境下的 YAML 拷贝出来然后对差异的地方进行修改。一些类似 Helm 等应用管理工具需要额外学习DSL(Domain Specific Language,领域特定语言) 语法。总结以上,在 k8s 环境下存在多套环境的应用,经常遇到以下几个问题:

  • 如何管理不同环境或不同团队的应用的 Kubernetes YAML 资源
  • 如何以某种方式管理不同环境的微小差异,使得资源配置可以复用,减少 copy and change 的工作量
  • 如何简化维护应用的流程,不需要额外学习模板语法

Kustomize 通过以下几种方式解决了上述问题:

  • kustomize 通过 Base & Overlays 方式方式维护不同环境的应用配置
  • kustomize 使用 patch 方式复用 Base 配置,并在 Overlay 描述与 Base 应用配置的差异部分来实现资源复用
  • kustomize 管理的都是 Kubernetes 原生 YAML 文件,不需要学习额外的 DSL 语法

版本支持

云原生安全风险 云原生管理平台_云原生安全风险_04

官方示例

文件结构

demo
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── production
    │   ├── deployment.yaml
    │   └── kustomization.yaml
    └── staging
        ├── kustomization.yaml
        └── map.yaml

新建一个 Base 目录
这里使用官网的 helloWorld 的 YAML 资源文件作为示例,在 base 目录下新增几个 k8s YAML 资源文件,文件结构如下:

demo
└── base
    ├── configMap.yaml
    ├── deployment.yaml
    ├── kustomization.yaml
    └── service.yaml

接下来看看 kustomization.yaml 配置文件中包含什么内容:

commonLabels:
  app: hello

resources:
- deployment.yaml
- service.yaml
- configMap.yaml

这个文件声明了这些 YAML 资源(deployments、services、configmap 等)以及要应用于它们的一些自定义,如添加一个通用的标签。kustomization 还提供了namePrefix、commonAnnoations、images 等配置项,全部配置在github 的示例 kustomization.yaml 中。

云原生安全风险 云原生管理平台_YAML_05

功能特性列表参考:https://kubernetes.io/zh-cn/docs/tasks/manage-kubernetes-objects/kustomization/#kustomize-feature-list 这时候,可以通过 kustomize build 命令来看完整的配置:

$ kustomize build demo/base  # build 出来的 YAML 太长就不贴处理了
$ kustomize build demo/base | kubectl apply -f -  # 这种方式直接部署在集群中
$ kubectl apply -k # 1.14 版本可以直接使用该命令部署应用于集群中

build 出来的 YAML 每个资源对象上都会存在通用的标签 app: hello

创建 Overlays
创建一个 staging 和 production overlay,目录树结构如下所示:

demo
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── production
    └── staging

演示环境 kustomization
在 staging kustomization 文件中,定义一个新的名称前辍以及一些不同的标签

# 文件路径 demo/overlays/staging/kustomization.yaml
namePrefix: staging-
commonLabels:
  variant: staging
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am staging!
bases:
- ../../base
patchesStrategicMerge:
- map.yaml

演示环境 patch
添加一个 ConfigMap 自定义把 base 中的 ConfigMap 中的 “Good Morning!” 变成 “Good Night!”

# 文件路径 demo/overlays/staging/map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Good Night!"
  enableRisky: "true"

生产环境 kustoimzation
在生产环境目录下,创建一个 kustomization.yaml 文件,定义不同的名称及标签

# 文件路径 demo/overlays/production/kustomization.yaml
namePrefix: production-
commonLabels:
  variant: production
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am production!
bases:
- ../../base
patchesStrategicMerge:
- deployment.yaml

生产环境 patch
创建一个生产环境的 patch, 定义增加副本数量

# demo/overlays/production/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 10

部署不同环境
需要在生产环境部署应用,通过下面命令

$ kustomize build demo/overlays/production | kubectl apply -f -   # 或者 kubectl apply -k

需要在演示环境部署应用,通过下面命令

$ kustomize build demo/overlays/staging | kubectl apply -f -     # 或者 kubectl apply -k

kustomize vs Helm

通过上面对 kustomize 的讲解,可能已经有人注意到它与 Helm 有一定的相似。先来看看 **Helm 的定位:Kubernetes 的包管理工具,而 kustomize 的定位是:Kubernetes 原生配置管理。**两者定位领域有很大不同,**Helm 通过将应用抽象成 Chart 来管理, 专注于应用的操作、复杂性管理等, 而 kustomize 关注于 k8s API 对象的管理。**下面列举了一些它们之间的区别(不是特别全面,欢迎补充或修正):

  • Helm 提供应用描述文件模板(Go template),在部署时通过字符替换方式渲染成 YAML,对应用描述文件具有侵入性。Kustomize 使用原生 k8s 对象,无需模板参数化,无需侵入应用描述文件(YAML), 通过 overlay 选择相应 patch 生成最终 YAML
  • Helm 专注于应用的复杂性及生命周期管理(包括 install、upgrade、rollback),kustomize 通过管理应用的描述文件来间接管理应用
  • Helm 使用 Chart 来管理应用,Chart 相对固定、稳定,相当于静态管理,更适合对外交付使用,而 kustomize 管理的是正在变更的应用,可以 fork 一个新版本,创建新的 overlay 将应用部署在新的环境,相当于动态管理,适合于 DevOps 流程
  • Helm 通过 Chart 方式打包并管理应用版本,kustomize 通过 overlay 方式管理应用不同的变体,通过 Git 来版本管理
  • Helm 在v3 版本前有 Helm 和 Tiller 两组件,需要一定配置,而 kustomize 只有一个二进制,开箱即用
    总的来说,Helm 有自己一套体系来管理应用,而 kustomize 更轻量级,融入Kubernetes 的设计理念,通过原生 k8s API 对象来管理应用。

参考

《云原生应用管理原理与实践》https://e.jd.com/30640760.html 《深入剖析 Kubernetes》第11章,https://e.jd.com/30623387.html,https://time.geekbang.org/column/intro/100015201 kustomize 最简实践:https://zhuanlan.zhihu.com/p/92153378