引入:
Kubernetes是什么:
他是一个自动化管理和部署应用程序(如前端、数据库(依赖)、后端服务)的工具
Kubernetes有什么作用:
- 自动化部署:只需要用Helm配置好参数,它就可以帮我们把应用部署到合适的服务器上
- 弹性伸缩:它会自动根据应用程序的访问量,帮我们增加或减少应用副本
- 自我修复:因为应用程序有多个副本,当某个服务器或者应用崩溃,它会自动将应用转移到健康的服务器,保证服务不中断
- 负载均衡:它可以把用户的请求负载均衡给不同的应用副本
Kubernetes的一些核心概念:
- Pod:容器组,是Kubernetes中最小的部署单元,一般里面有一个或多个容器
举例:如果你的一个服务需要一个主应用容器和一个用来收集日志的辅助容器,它们就可以放在同一个 Pod 里。
Kubernetes Deployment组件:
它是Kubernetes中用来管理无状态应用的控制器
- 管理Pod副本数量
- 管理滚动更新和回滚:当我们应用升级新版本时,Deployment会平滑地帮我们进行旧版本替换,而不会造成服务中断;如果新版本有问题,也会帮我们回滚到旧版本
- 实现自我修复:如果某个Pod崩溃,Deployment会检测到,然后自动创建一个新的Pod来替换他,确保副本的数量满足配置
虽然Pod可以直接部署在Kubernetes上运行,但是缺少
Deployment
会使它没有任何管理能力,无法实现Kubernetes的强大功能(见上"Kubernetes有什么作用")
配置与部署
方式一:原生方式
比较简单,只需编写一个Kubernetes的.yaml文件,定义好应用的配置信息,即可在Kubernetes上运行它
比如在seata-server.yaml中,定义了应用的基本信息
# seata-server.yaml
apiVersion: v1
kind: Service
metadata:
name: seata-server
namespace: default
labels:
k8s-app: seata-server
spec:
type: NodePort
ports:
- port: 8091
nodePort: 30091
protocol: TCP
name: http
selector:
k8s-app: seata-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: seata-server
namespace: default
labels:
k8s-app: seata-server
spec:
replicas: 1
selector:
matchLabels:
k8s-app: seata-server
template:
metadata:
labels:
k8s-app: seata-server
spec:
containers:
- name: seata-server
image: docker.io/seataio/seata-server:latest
imagePullPolicy: IfNotPresent
env:
- name: SEATA_PORT
value: "8091"
- name: STORE_MODE
value: file
ports:
- name: http
containerPort: 8091
protocol: TCP
方式二:使用Helm工具进行动态配置
Helm是什么:
在Kubernetes生态中,Helm是Kubernetes的包管理器,它提供了一套命令行(CLI)工具和一套打包格式,用于定义、安装、升级、管理、删除在Kubernetes上运行的应用程序
Helm最核心的功能是Chart模板渲染,即根据用户提供的配置(如values.yaml
、Deployment.yaml
、Service.yaml
),动态生成最终的Kubernetes API对象清单
Helm 只是一个更高层次的抽象和工具,它为你管理和生成这些 Kubernetes YAML 文件提供了便利。就算不用 Helm 工具,你也可以在 Kubernetes 部署 Pod,只需要为应用程序编写一个
seata-server.yaml
文件
Helm Chart是什么:
是Helm包管理器的基本单元,它代表了一个预先打包的、可版本化的Kubernetes应用程序,本质上就是一个特定结构化的目录
组成:
Chart.yaml
:元数据文件,提供Chart的基本消息,如name、version、description(这个文件高度标准化,几乎所有的Chart 都遵循的一致结构)values.yaml
:默认配置项文件,提供Chart模板中使用的所有默认配置参数,可以被命令行或自定义values.yaml
文件覆盖templates/
目录:资源模板文件,包括Deployment
、Service
、ConfigMap
等配置。这些文件使用 Go 模板语法,结合values.yaml
中的数据进行渲染,生成最终的 Kubernetes API 对象。【附录2】_helpers.tpl
:命名模板文件,存储可重用的Go模板片段,它们封装了常用的逻辑、字符串处理或复杂计算【详细介绍见附录1】
Helm工作流程:
- 开发者配置应用的 Helm Chart,定义了应用程序在 Kubernetes 上的所有部署细节和可配置项。
- 用户通过 Helm CLI (例如
helm install my-seata ./seata-chart --set replicaCount=3
) 来安装 Chart- Helm 客户端接收命令和参数,读取本地或远程的 Chart 文件结构。
- Helm 客户端进行模板渲染: 这一步在用户本地(或执行 Helm 命令的机器上)完成。它将
templates/
目录下的所有.yaml
和.tpl
文件作为 Go 模板,结合values.yaml
中的默认值和用户通过--set
或-f
提供的自定义值,生成最终的、完整的 Kubernetes YAML 清单。 - Helm 客户端将渲染好的 YAML 清单发送给 Kubernetes API Server。 通常通过 Kubernetes 的客户端库和 API 调用完成。
- Kubernetes API Server 接收并处理这些清单: API Server 负责校验这些清单,并将其存储到 etcd(Kubernetes 的分布式存储)中。
- Kubernetes 控制器(如 Deployment Controller)开始工作: 当 API Server 接收到新的或更新的资源定义时,相应的 Kubernetes 控制器会检测到这些变化,并采取行动确保集群的实际状态与这些声明式定义相匹配。例如,Deployment Controller 会创建或更新 Pods。
- 最终,如果你的应用程序的镜像尚未存在, Kubelet会指示拉去进项,并将 Pods 在 Kubernetes 集群中运行起来。
附录:
_helpers.tpl
文件到底有什么用:
_helpers.tpl
文件通常以_
开头,表示它不应直接被渲染成 Kubernetes 资源,而是作为辅助文件被其他模板引用- 用于定义命名模板 (Named Templates)。这些命名模板是可重用的 Go 模板片段。(类似于编程中的工具类)
- 它们封装了常用的逻辑、字符串处理或复杂计算,供 Chart 中其他 Kubernetes 资源模板文件(如 Deployment, Service 等)调用。
比如在templates/Deployment.yaml
文件中,就引用到了这个文件的命名模板
name: {{ include "应用程序.name" . }}
labels:
{{ include "应用程序.labels" . | indent 4 }}
_helpers.tpl
文件中, 这个命名模板可能长这样:
{{- define "应用程序.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "应用程序.labels" -}}
helm.sh/chart: {{ include "应用程序.chart" . }}
{{ include "应用程序.selectorLabels" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
templates
目录的其他模板说明:
**emplates/service.yaml**
** (Service 资源)**:
作用: 定义一个 Kubernetes Service,用于暴露 Seata Server 应用程序,使其可以在集群内部被其他服务发现和访问。Service 提供了稳定的网络地址,即使背后的 Pods 动态变化,Service 的地址也不变。
**示例代码片段:**YAML
apiVersion: v1
kind: Service # 这是一个 Service 类型的 Kubernetes 资源
metadata:
name: {{ include "seata-server.fullname" . }} # 通过命名模板生成 Service 名称
namespace: {{ .Release.Namespace | quote }}
labels:
{{ include "seata-server.labels" . | indent 4 }}
spec:
type: ClusterIP # 服务类型,ClusterIP 表示只在集群内部可访问
ports:
- port: 8091 # Service 监听的端口
targetPort: http # 转发到 Pod 内部名为 "http" 的端口(对应 Deployment 中定义的端口名称)
protocol: TCP
name: tcp-seata
selector: # Service 通过这些标签选择它要代理的 Pods
app.kubernetes.io/name: {{ include "seata-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
这个 Service
模板会确保 Seata Server Pod 暴露的 8091 端口可以通过一个稳定的集群 IP 地址被访问。
**templates/configmap.yaml**
** (ConfigMap 资源)**:
作用: 存储非敏感的配置数据,例如 Seata Server 的配置文件 registry.conf
或 file.conf
。
**示例代码片段:**YAML
apiVersion: v1
kind: ConfigMap # 这是一个 ConfigMap 类型的 Kubernetes 资源
metadata:
name: {{ include "seata-server.fullname" . }}-config # 生成 ConfigMap 名称
namespace: {{ .Release.Namespace | quote }}
labels:
{{ include "seata-server.labels" . | indent 4 }}
data:
registry.conf: | # ConfigMap 的数据部分
# 这就是 Seata Server 的 registry.conf 文件内容
# 可以通过 values.yaml 来定制这些内容
registry {
type = "file"
file {
name = "file.conf"
}
}
file.conf: |
# Seata Server 的 file.conf 内容
# ...
这个 ConfigMap
模板可以在运行时将配置数据注入到 Seata Server 的 Pod 中,而无需将配置硬编码到 Docker 镜像中。
总结Helm基于原生模式的增强:
简单来说,Helm 在原生 Kubernetes YAML 配置与 **kubectl**
部署的基础上,主要增加了以下三大核心能力:
- 打包与标准化
- 增强点: 将一个应用程序所需的所有 Kubernetes 资源(Deployment, Service, ConfigMap 等)以及它们的配置打包成一个标准的、可版本化的单元——Chart。
- 解决了什么: 原生方式需要你手动管理和应用多个独立的 YAML 文件,容易遗漏或出错。Helm Chart 就像一个“应用程序安装包”,把所有相关的东西都捆绑在一起。
- 模板化与可配置性
- 增强点: 引入 Go 模板语法和
values.yaml
文件,使得 Kubernetes 资源配置可以参数化和动态生成。 - 解决了什么: 原生 YAML 是静态的,若要在不同环境或不同配置下部署,你得手动修改或维护多份 YAML 文件。Helm 让你能通过简单的参数调整,就生成适用于特定环境的最终配置,极大地减少了重复工作和错误。
- 增强点: 引入 Go 模板语法和
- 发布与生命周期管理
- 增强点: 提供发布 (Release) 概念,跟踪每次部署的版本历史,并支持升级、回滚、依赖管理等高级操作。
- 解决了什么: 原生
kubectl
部署缺乏对应用版本和部署历史的统一管理,升级和回滚复杂且风险高。Helm 让你能轻松地进行应用的升级和降级,并且管理应用间的复杂依赖关系,提高了运维效率和部署的可靠性。
运用场景:
如果应用程序是有状态服务,比如大型集群化服务,使用helm进行Kubernetes配置会收益更大:
有状态服务天生就比无状态服务在 Kubernetes 上的部署更复杂、需要更精细的控制。Helm 的强大模板化、参数化、打包以及高级生命周期管理能力,恰好能完美地解决这些复杂性,将繁琐的部署流程抽象为简单的配置和命令,因此带来的效率提升和风险降低远超无状态服务。