k8s核心技术-Helm

发布于:2025-09-08 ⋅ 阅读:(16) ⋅ 点赞:(0)

1、Helm的引入和介绍

Helm 是 Kubernetes 应用的包管理工具,类似于 Linux 系统中的 yum 或 apt。它主要用来管理 Kubernetes 应用的包(称为 Charts),帮助用户更高效地部署、管理和维护 Kubernetes 应用。通过 Helm,用户可以轻松地打包、发布、安装和升级复杂的 Kubernetes 应用。
         Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。它包含了一组预定义的 Kubernetes 资源模板,这些模板可以通过参数化的方式进行配置,从而实现灵活的部署。Chart 的设计使得用户可以在部署应用时自定义应用程序的元数据(Metadata),便于应用程序的分发和管理。

2、Helm的安装部署

2.1、下载安装包并解压,以 helm-v3.17.3-linux-amd64.tar.gz 为例

[root@Rocky-1 ~]# wget -c https://get.helm.sh/helm-v3.17.3-linux-amd64.tar.gz
--2025-09-07 02:02:48--  https://get.helm.sh/helm-v3.17.3-linux-amd64.tar.gz
Resolving get.helm.sh (get.helm.sh)... 13.107.253.49, 2620:1ec:29:1::49
Connecting to get.helm.sh (get.helm.sh)|13.107.253.49|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17491989 (17M) [application/x-tar]
Saving to: ‘helm-v3.17.3-linux-amd64.tar.gz’

helm-v3.17.3-linux-amd64.tar.gz     100%[==================================================================>]  16.68M   278KB/s    in 53s

2025-09-07 02:03:42 (320 KB/s) - ‘helm-v3.17.3-linux-amd64.tar.gz’ saved [17491989/17491989]

[root@Rocky-1 ~]# tar -xf helm-v3.17.3-linux-amd64.tar.gz -C /opt

2.2、将 helm 可执行文件复制到 /usr/local/bin/ 目录,使其可以在系统中全局使用

[root@Rocky-1 ~]# cp /opt/linux-amd64/helm /usr/local/bin/

2.3、为了方便使用Helm命令,配置命令自动补全功能

[root@Rocky-1 ~]# helm completion bash > ~/.helmrc
[root@Rocky-1 ~]# source ~/.helmrc

2.4、验证Helm是否安装成功

[root@Rocky-1 ~]# helm version
version.BuildInfo{Version:"v3.17.3", GitCommit:"e4da49785aa6e6ee2b86efd5dd9e43400318262b", GitTreeState:"clean", GoVersion:"go1.23.7"}

3、Helm常用的命令

命令 描述
create 创建一个 chart 并指定名字
dependency 管理 chart 依赖
get 下载一个 release。可用于命令:all、hooks、manifest、notes、values
history 获取 release 历史
install 安装一个 chart
list 列出 release
package 将 chart 目录打包到 chart 存档文件中
pull 从远程仓库中下载 chart 并解压到本地 # helm pull stable/mysql --untar
repo 添加,列出,移除,更新和索引 chart 仓库。可用于命令:add、index、list、remove、update
rollback 从之前版本回滚
search 根据关键字搜索 chart。可用于命令:hub、repo
show 查看 chart 详细信息。可用于命令:all、chart、readme、values
status 显示已命名版本的状态
template 本地呈现模板
uninstall 卸载一个 release
upgrade 更新一个 release
version 查看 helm 客户端版本

4、配置国内的Chart仓库

4.1、常用的国内仓库

•微软仓库(http://mirror.azure.cn/kubernetes/charts/)这个仓库推荐,基本上官网有的
chart 这里都有。
•阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts)
•官方仓库(https://hub.kubeapps.com/charts/incubator)官方 chart 仓库,国内有点不好使。

4.2、添加存储库

[root@Rocky-1 ~]# helm repo add stable http://mirror.azure.cn/kubernetes/charts
[root@Rocky-1 ~]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

[root@Rocky-1 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "aliyun" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
[root@Rocky-1 ~]# helm repo list
NAME    URL
stable  http://mirror.azure.cn/kubernetes/charts
aliyun  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

4.3、删除存储库(为了方便,博主就没有删除了)

helm repo remove aliyun

5、Helm的基本使用

5.1、主要的三个命令

chart install        :部署

chart upgrade    :更新部署

chart rollback     :回滚

5.2、chart查找

[root@Rocky-1 ~]# helm search repo weave
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
aliyun/weave-cloud      0.1.2                           Weave Cloud is a add-on to Kubernetes which pro...
aliyun/weave-scope      0.9.2           1.6.5           A Helm chart for the Weave Scope cluster visual...
stable/weave-cloud      0.3.9           1.4.0           DEPRECATED - Weave Cloud is a add-on to Kuberne...
stable/weave-scope      1.1.12          1.12.0          DEPRECATED - A Helm chart for the Weave Scope c...

5.3、查看Chart信息

[root@Rocky-1 ~]# helm show chart stable/weave-scope
apiVersion: v1
appVersion: 1.12.0
deprecated: true
description: DEPRECATED - A Helm chart for the Weave Scope cluster visualizer.
home: https://www.weave.works/oss/scope/
icon: https://avatars1.githubusercontent.com/u/9976052?s=64
keywords:
- containers
- dashboard
- monitoring
name: weave-scope
sources:
- https://github.com/weaveworks/scope
version: 1.1.12

5.4、查看发布状态

# 查看安装列表
[root@Rocky-1 ~]# helm list
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
db      default         1               2025-09-07 02:14:09.756019405 -0400 EDT deployed        mysql-1.6.9     5.7.30

# 查看应用发布状态
[root@Rocky-1 ~]# helm status db
NAME: db
LAST DEPLOYED: Sun Sep  7 02:14:09 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
db-mysql.default.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default db-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

To connect to your database:

1. Run an Ubuntu pod that you can use as a client:

    kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

2. Install the mysql client:

    $ apt-get update && apt-get install mysql-client -y

3. Connect using the mysql cli, then provide your password:
    $ mysql -h db-mysql -p

To connect to your database directly from outside the K8s cluster:
    MYSQL_HOST=127.0.0.1
    MYSQL_PORT=3306

    # Execute the following command to route the connection:
    kubectl port-forward svc/db-mysql 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}

# 查看pod的状态发现是Pending状态,原来是需要8G的PV
kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
db-mysql-5cd7cbc6b7-cjgkq   0/1     Pending   0          115m

所有集群节点安装nfs-utils
[root@Rocky-1 ~]# yum install nfs-utils -y
[root@Rocky-1 ~]# cat /etc/exports
/data/db        192.168.93.0/24(rw,no_root_squash)
[root@Rocky-1 ~]# mkdir -p /data/db
[root@Rocky-1 ~]# systemctl restart nfs-server
[root@Rocky-1 ~]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: dbdata # 修改PV名称
spec:
  capacity:
    storage: 8Gi # 修改大小
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /data/db # 修改目录名
    server: Rocky-1
[root@Rocky-1 ~]# kubectl apply -f pv.yaml
[root@Rocky-1 ~]# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
db-mysql-5cd7cbc6b7-tjxdm   1/1     Running   0          16m


# 查看数据库,进入数据库
[root@Rocky-1 ~]# kubectl get secret --namespace default db-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo
xizB6Hz7Uo
[root@Rocky-1 ~]# kubectl exec -it db-mysql-5cd7cbc6b7-tjxdm -- bash
Defaulted container "db-mysql" out of: db-mysql, remove-lost-found (init)
root@db-mysql-5cd7cbc6b7-tjxdm:/# mysql -uroot -pxizB6Hz7Uo
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 187
Server version: 5.7.30 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql>

6、构建一个Helm Chart

[root@Rocky-1 ~] helm create nginx
[root@Rocky-1 ~] cd nginx/templates/
[root@Rocky-1 templates]# cat ../values.yaml
replicas: 1
image:  nginx
tag: 1.17.1
label: nginx
port: 80

# 在templates的yaml文件使用values.yaml定义变量
[root@Rocky-1 ~]# rm -rf ./*
[root@Rocky-1 ~]# kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml

# 修改yaml文件
[root@Rocky-1 templates]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: {{ .Release.Name }}-deploy
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: {{ .Values.label }}
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: {{ .Values.label }}
    spec:
      containers:
      - image: {{ .Values.image }}:{{ .Values.tag }}
        name: {{ .Values.image }}
        resources: {}
status: {}

[root@Rocky-1 templates]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: {{ .Values.label }}
  name: {{ .Release.Name }}-svc
spec:
  ports:
  - port: {{ .Values.port }}
    protocol: TCP
    targetPort: 80
  selector:
    app: {{ .Values.label }}
status:
  loadBalancer: {}

[root@Rocky-1 ~]# helm install --dry-run web1 nginx/
NAME: web1
LAST DEPLOYED: Sun Sep  7 03:35:20 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: web1-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
status:
  loadBalancer: {}
---
# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.17.1
        name: nginx
        resources: {}
status: {}

[root@Rocky-1 ~]# helm install web1 nginx/
NAME: web1
LAST DEPLOYED: Sun Sep  7 03:36:27 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

更新、升级、回滚和删除

[root@Rocky-1 ~]# helm upgrade web1 --set replicas=3 nginx/
Release "web1" has been upgraded. Happy Helming!
NAME: web1
LAST DEPLOYED: Sun Sep  7 03:39:15 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
[root@Rocky-1 ~]# kubectl get pod,svc | grep web1
pod/web1-deploy-56c4688584-kg95j   1/1     Running             0          16s
pod/web1-deploy-56c4688584-lxr9z   0/1     ContainerCreating   0          16s
pod/web1-deploy-56c4688584-r9d82   1/1     Running             0          2m52s
service/web1-svc     ClusterIP   10.96.3.171   <none>        80/TCP     3m1s
[root@Rocky-1 templates]# helm history web1
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION
1               Sun Sep  7 03:36:27 2025        superseded      nginx-0.1.0     1.16.0          Install complete
2               Sun Sep  7 03:39:15 2025        deployed        nginx-0.1.0     1.16.0          Upgrade complete

# 也可以使用yaml进行升级
[root@Rocky-1 ~]# helm upgrade --set tag=1.25.1 web1 nginx/
Release "web1" has been upgraded. Happy Helming!
NAME: web1
LAST DEPLOYED: Sun Sep  7 03:54:36 2025
NAMESPACE: default
STATUS: deployed
REVISION: 3
TEST SUITE: None

# 回滚
[root@Rocky-1 ~]# helm rollback web1
Rollback was a success! Happy Helming!

管道和函数

前面讲的模块,其实就是将值传给模板引擎进行渲染,模板引擎还支持对拿到数据进行二次处理。
例如从.Values 中读取的值变成字符串,可以使用 quote 函数实现:
[root@kubernetes-master-001 ~]# vi templates/deployment.yaml
app: {{ quote .Values.label.app }}
[root@kubernetes-master-001 ~]# helm install --dry-run web ../mychart/ project:
ms
app: "nginx"
quote .Values.label.app 将后面的值作为参数传递给 quote 函数。模板函数调用语法为:
functionName arg1 arg2...
另外还会经常使用一个 default 函数,该函数允许在模板中指定默认值,以防止该值被忽略掉。例如忘记定
义,执行 helm install 会因为缺少字段无法创建资源,这时就可以定义一个默认值。
[root@kubernetes-master-001 ~]# cat values.yaml
replicas: 2
[root@kubernetes-master-001 ~]# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment metadata:
name: {{ .Release.Name }}-deployment
- name: {{ .Values.name | default "nginx" }}
其他函数:
缩进:{{ .Values.resources | indent 12 }}
大写:{{ upper .Values.resources }}
首字母大写:{{ title .Values.resources }}

7、Helm的流程控制

流程控制是为模板提供了一种能力,满足更复杂的数据逻辑处理。

Helm 模板语言提供以下流程控制语句:

  • if/else 条件块
  • with 指定范围
  • range 循环块

7.1、if/else

#1.if/else 块是用于在模板中有条件地包含文本块的方法,条件块的基本结构如下:
{{ if PIPELINE }}
# Do something
{{ elseif OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
#2.示例
[root@kubernetes-master-001 ~]# cat values.yaml
devops: k8
[root@kubernetes-master-001 ~]# cat templates/deployment.yaml
...
template:
metadata:
labels:
app: nginx
{{ if eq .Values.devops "k8s" }}
devops: 123
{{ else }}
devops: 456
{{ end }}
在上面条件语句使用了 eq 运算符判断是否相等,除此之外,还支持ne、 lt、 gt、 and、 or 等运
算符。注意数据类型。通过模板引擎来渲染一下,会得到如下结果:
[root@kubernetes-master-001 ~]# helm install --dry-run web ../mychart/
...
labels:
app: nginx
devops: 456
可以看到渲染出来会有多余的空行,这是因为当模板引擎运行时,会将控制指令删除,所有之前占的位置也就
空白了,需要使用{{- if ...}} 的方式消除此空行:
[root@kubernetes-master-001 ~]# vim templates/deploymemt.yaml
...
env:
{{- if eq .Values.env.hello "world" }}
- name: hello
value: 123
{{- end }}
现在是不是没有多余的空格了,如果使用-}}需谨慎,比如上面模板文件中:
[root@kubernetes-master-001 ~]# vim templates/deploymemt.yaml
...
env:
{{- if eq .Values.env.hello "world" -}}
- hello: true
{{- end }}
这会渲染成:
env:- hello: true
因为-}}它删除了双方的换行符。
条件判断就是判断条件是否为真,如果值为以下几种情况则为 false:
• 一个布尔类型的 false
• 一个数字 零
• 一个 空的字符串
• 一个空的集合( map、 slice、 tuple、 dict、 array) 除了上面的这些情况外,其他
所有条件都为 真。
例如,判断一个空的数组
[root@kubernetes-master-001 ~]# cat values.yaml
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi # requests:
# cpu: 100m
# memory: 128Mi
[root@kubernetes-master-001 ~]# vim templates/deploymemt.yaml
...
spec:
containers:
- image: nginx:1.16 name: nginx
{{- if .Values.resources }} resources:
{{ toYaml .Values.resources | indent 10 }}
{{- end }}
例如,判断一个布尔值
[root@kubernetes-master-001 ~]# cat values.yaml
service:
type: ClusterIP
port: 80
ingress:
enabled: true
host: example.ctnrs.com
[root@kubernetes-master-001 ~]# vim templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
spec:
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- path: /
backend:
serviceName: {{ .Release.Name }}
servicePort: {{ .Values.service.port }}
{{ end }}

7.2、Range

在 Helm 模板语言中,使用 range 关键字来进行循环操作。我们在values.yaml 文件中添加上一个变量
列表:
[root@kubernetes-master-001 ~]# cat values.yaml
test:
- 1
- 2
- 3
循环打印该列表:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}
data:
test: |
{{- range .Values.test }}
{{ . }}
{{- end }}
循环内部我们使用的是一个 .,这是因为当前的作用域就在当前循环内,这个 .引用的当前读取的元
素。

7.3、with

with :控制变量作用域。
还记得之前我们的{{.Release.xxx}}或者 {{.Values.xxx}}吗?其中的 .就是表示对当前范围的
引用, .Values 就是告诉模板在当前范围中查找 Values 对象的值。而 with 语句就可以来控制变
量的作用域范围,其语法和一个简单的 if 语句比较类似:
{{ with PIPELINE }}
# restricted scope
{{ end }}
with 语句可以允许将当前范围 .设置为特定的对象,比如我们前面一直使用的 .Values.label,我
们可以使用 with 来将 .范围指向 .Values.label:
在 Helm 模板语言中,使用 range 关键字来进行循环操作。我们在values.yaml 文件中添加上一个变量
列表:
[root@kubernetes-master-001 ~]# cat values.yaml
...
nodeSelector:
team: a
gpu: yes
[root@kubernetes-master-001 ~]# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

8、helm部署harbor

8.1、下载软件包

#创建名称空间
kubectl create namespace harbor
#添加harbor的helm仓库
helm repo add harbor https://helm.goharbor.io
#下载软件包
helm pull harbor/harbor

8.2、编辑配置文件

[root@Rocky-1 ~]# cat conf.yaml
expose:
  type: nodePort
  tls:
    enabled: false
  nodePort:
    ports:
      http:
        port: 80
        nodePort: 30002

harborAdminPassword: "admin"

externalURL: http://192.168.93.20:30002

persistence:
  enabled: false

8.3、部署

helm install harbor ./harbor-1.17.2.tgz -f conf.yaml -n harbor
[root@Rocky-1 ~]#  kubectl get pod,svc -n harbor
NAME                                     READY   STATUS    RESTARTS      AGE
pod/harbor-core-5b6f8d64d5-ddsvm         1/1     Running   2 (10m ago)   25m
pod/harbor-database-0                    1/1     Running   0             25m
pod/harbor-jobservice-66f6f4b7db-j5jt8   1/1     Running   6 (10m ago)   25m
pod/harbor-nginx-865698dfc6-zcwgq        1/1     Running   0             25m
pod/harbor-portal-f596f84db-b9mv2        1/1     Running   0             25m
pod/harbor-redis-0                       1/1     Running   0             25m
pod/harbor-registry-79bc794f45-4tdhc     2/2     Running   0             25m
pod/harbor-trivy-0                       1/1     Running   0             25m

NAME                        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)             AGE
service/harbor              NodePort    10.96.0.183   <none>        80:30002/TCP        26m
service/harbor-core         ClusterIP   10.96.0.113   <none>        80/TCP              26m
service/harbor-database     ClusterIP   10.96.3.206   <none>        5432/TCP            26m
service/harbor-jobservice   ClusterIP   10.96.1.18    <none>        80/TCP              26m
service/harbor-portal       ClusterIP   10.96.0.65    <none>        80/TCP              26m
service/harbor-redis        ClusterIP   10.96.0.184   <none>        6379/TCP            26m
service/harbor-registry     ClusterIP   10.96.0.200   <none>        5000/TCP,8080/TCP   26m
service/harbor-trivy        ClusterIP   10.96.2.190   <none>        8080/TCP            26m


网站公告

今日签到

点亮在社区的每一天
去签到