Kubernetes Helm
Zhongjun Qiu 元婴开发者

介绍了 Helm 的基本概念、安装方法、常用命令以及如何使用 Helm 模拟部署多个前端服务的示例。

什么是 Helm

Helm 是 Kubernetes 的一个包管理器。在没有 Helm 之前,部署一个复杂的 K8s 应用需要手动部署 deploymentsvc 等多个资源,步骤繁琐。

Helm 通过打包的方式,将 K8s 应用的各种资源(如 Deployment, Service, ConfigMap 等)以及其配置信息集合在一起,实现了版本管理,极大地简化了 K8s 应用的部署和管理。

Helm 的本质是让 K8s 的应用管理可配置,可以动态生成 K8s 资源清单文件(如 deployment.yaml, service.yaml),然后调用 kubectl 执行部署。

Helm 重要概念

Helm 有两个重要的概念:chartrelease

  • Chart

    chart 是一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系和文档说明。它是应用部署的自包含逻辑单元,可以将其想象成 apt 或 yum 中的软件安装包。

  • Release

    release 是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 Kubernetes 集群时,就会生成一个 release。同一个 chart 能够多次安装到同一个集群,每次安装都是一个独立的 release。

类似于docker里images 和 containers的关系

Helm 使用

Helm 是 Kubernetes 的包管理工具,类似于 Linux 的 yum/apt 或 Python 的 pip。安装方式有多种,这里给出最常用的一种脚本安装方式:

1
2
3
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

安装完成后,可以执行以下命令确认:

1
helm version

输出版本信息则表示安装成功。

1. 仓库管理

1
2
3
4
helm repo add bitnami https://charts.bitnami.com/bitnami   # 添加仓库
helm repo list # 查看已配置仓库
helm repo update # 更新仓库
helm repo remove bitnami # 移除仓库

2. 查找和查看 Chart

1
2
3
4
5
helm search hub wordpress     # 在 Artifact Hub 上搜索 chart
helm search repo apache # 在已添加的仓库里搜索 chart
helm show chart bitnami/apache # 查看 chart 的基本信息
helm show values bitnami/apache # 查看 chart 默认配置
helm show all bitnami/apache # 查看全部信息

3. 安装 Chart

1
2
3
4
5
6
7
8
9
10
11
# 安装一个 chart
helm install my-apache bitnami/apache

# 随机生成 release 名称
helm install bitnami/apache --generate-name

# 使用自定义 values.yaml 安装
helm install -f values.yaml my-apache bitnami/apache

# 使用 --set 直接覆盖配置
helm install my-apache bitnami/apache --set service.type=NodePort

📌 配置方式:

  • -f values.yaml:通过配置文件覆盖默认参数(推荐,便于版本管理)。
  • --set key=value:命令行直接覆盖参数,适合临时修改。

4. 查看 Release 信息

1
2
3
4
helm list                   # 查看集群中所有 release
helm status my-apache # 查看 release 运行状态
helm get values my-apache # 查看 release 使用的配置
helm history my-apache # 查看 release 历史版本

5. 升级与回滚

1
2
helm upgrade -f new-values.yaml my-apache bitnami/apache   # 升级 release
helm rollback my-apache 1 # 回滚到 revision=1 的版本

选项:

  • --timeout:设置超时时间(默认 5 分钟)。
  • --wait:等待所有 Pod 就绪后才认为安装/升级成功。

6. 卸载 Release

1
2
helm uninstall my-apache                  # 卸载 release
helm uninstall my-apache --keep-history # 卸载但保留历史

查看历史卸载的 release:

1
helm list --all

7. 创建自定义 Chart

1
helm create myapp   # 创建模板项目
  • templates/ 目录下编写 deployment.yamlservice.yaml 等模板。

  • values.yaml 中定义变量,例如镜像名、副本数、端口。

  • 安装自定义 chart:

1
helm install myapp ./myapp

Helm模拟部署多个前端服务

创建一个空Helm模版,删除用不到的文件

1
2
3
helm create my-nginx
cd ./my-nginx
rm -rf ./templates/*

需求:

  • 需要同时部署5个nginx服务
  • 需要提供外部高可靠的访问
  • 访问每个nginx服务时显示各自的pod名称和podIP
  • 可以动态修改服务数量,修改暴露的外部接口访问地址,升级或更改镜像

创建templates/depolyment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deploy
labels:
app: {{ .Values.app }}
spec:
// nginx服务数量
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.app }}
template:
metadata:
labels:
app: {{ .Values.app }}
spec:
// 用空白卷存储要显示的页面信息
volumes:
- name: html-volume
emptyDir: {}
// 初始化页面信息
initContainers:
- name: init-index
image: busybox
command:
- sh
- -c
- |
echo "<html><body><h1>Pod: $POD_NAME</h1><p>Creation time: $POD_CREATION_TIMESTAMP</p></body></html>" > /usr/share/nginx/html/index.html
// 通过环境变量注入当前pod的名称和IP
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
// 挂载到html-volume
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
containers:
- name: nginx
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 80
// 挂载到html-volume
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html

创建templates/service.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
spec:
type: NodePort
selector:
app: {{ .Values.app }}
ports:
- name: http
port: 80
targetPort: 80
nodePort: {{ .Values.nodePort }}

创建values.yaml(里面的属性都是通过.Values调用)

1
2
3
4
5
6
7
8
9
10
app: nginx-test

replicaCount: 3

image:
repository: docker.xuanyuan.me/nginx
tag: latest
pullPolicy: IfNotPresent

nodePort: 32100

这里之所以要用InitContainer,是因为尽量不要干扰主容器Nginx的配置

数据准备操作尽量放在InitContainer中进行,利用临时卷或其他卷来实现数据传递

运行

1
helm install my-nginx ../my-nginx/

image

之后在外部机器用curl访问暴露的32100端口,可以看出实现了负载均衡

image

svc暴露的NodePort,会在集群每个Node上的生成对应的IPVS规则,因此你可以访问任意一台Node上的32100端口,IPVS会将你的请求转发到特定的pod上

可以用ipvsadm -Ln --stats来查看Node上已经部署的IPVS规则

image

可以看到目标端口为32100的请求会转发到三个地址,即实际nginx-pod的地址

因为此时已经在集群内,使用的是CNI里的内部IP进行转发

之后需要进行端口更改或者镜像升级,直接修改values.yaml文件,然后运行

1
helm upgrade my-nginx ../my-nginx

可以查看所有的历史版本

image

 REWARD AUTHOR
 Comments
Comment plugin failed to load
Loading comment plugin