1、简介
Helm 是 Kubernetes 中广泛使用的包管理工具,它通过 Charts 封装应用程序,并提供命令行工具和函数来简化应用程序的安装、更新、配置和管理。而 Helm 模板引擎的强大之处在于它支持函数与管道的组合,使得配置和渲染 Kubernetes 资源时能够更加灵活和高效。在本文中,我们将深入探讨 Helm 函数和管道的使用,详细讲解它们的工作原理及如何在 Helm 模板中使用。
2、目录结构
首先,创建一个 Helm Chart 目录结构:
my-app-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ └── service.yaml
└── charts/
Chart.yaml:Helm Chart 的元数据文件,包含了 Chart 的基本信息,如名称、版本等。
[root@mast01 my-app-chart]# vim Chart.yaml
apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes Web Application
version: 1.0.0
appVersion: “1.0”
values.yaml:配置文件,定义了用户可以覆盖的变量。
[root@mast01 my-app-chart]# vim values.yaml
replicaCount: 3
image:
repository: my-web-app
tag: latest
pullPolicy: Always
service:
type: ClusterIP
port: 8080
resources:
requests:
cpu: “250m”
memory: “512Mi”
limits:
cpu: “500m”
memory: “1Gi”
ingress:
enabled: true
annotations: {}
path: /
host: my-web-app.local
templates/:存放 Kubernetes 资源模板文件,如 deployment.yaml 和 service.yaml。
Deployment 资源模板,Helm 会根据 values.yaml 中的配置动态生成。
[root@mast01 my-app-chart]# vim templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
labels:
app: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
– name: {{ .Release.Name }}
image: “{{ .Values.image.repository }}:{{ .Values.image.tag }}”
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
– containerPort: {{ .Values.service.port }}
resources:
requests:
cpu: {{ .Values.resources.requests.cpu }}
memory: {{ .Values.resources.requests.memory }}
limits:
cpu: {{ .Values.resources.limits.cpu }}
memory: {{ .Values.resources.limits.memory }}
在这个 deployment.yaml 模板中,我们使用了 Helm 函数和管道来动态渲染 Kubernetes 资源:通过这种方式,我们将不同的 Helm 函数和管道结合起来,使得模板更加灵活和动态。
{{ .Release.Name }}:获取 Helm Release 的名称,通常是安装时指定的名称。
{{ .Values.replicaCount }}:从 values.yaml 中读取副本数。
{{ .Values.image.repository }}:{{ .Values.image.tag }}:动态渲染镜像地址和标签。
{{ .Values.resources.requests.cpu }}:从 values.yaml 中读取资源请求和限制。
service资源模板,它将暴露 Web 应用以供其他应用访问。
[root@mast01 my-app-chart]# vim templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
spec:
selector:
app: {{ .Release.Name }}
ports:
– protocol: TCP
port: {{ .Values.service.port }}
targetPort: {{ .Values.service.port }}
type: {{ .Values.service.type }}
在 service.yaml 中:
{{ .Values.service.port }}:动态获取服务暴露的端口。
{{ .Values.service.type }}:从 values.yaml 中读取服务类型(ClusterIP, NodePort, LoadBalancer 等)。
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Mon Jan 6 16:13:16 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
– protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
Source: my-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
– name: my-app
image: “my-web-app:latest”
imagePullPolicy: Always
ports:
– containerPort: 8080
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
3、quote 函数
quote 函数将值转换为带有双引号的字符串。如果该值本身已经是字符串,quote 仍然会添加双引号。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_name: {{ .Values.app_name | quote }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
app_name: myapp
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 17:00:24 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
app_name: “myapp”
4、default 函数
default 函数用于设置默认值。如果值为空或未定义,则会使用指定的默认值。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_version: {{ .Values.version | default “1.0.0” }}
假设 values.yaml 中有以下内容:
values.yaml
中没有 version
字段,模板渲染后,是1.0.0。如果 values.yaml
中定义了 version
,如 version: 2.0.0
[root@mast01 huqi]# vim my-app-chart/values.yaml
version: 2.0.0
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 17:08:02 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
app_version: 2.0.0
5、indent和nindent 函数
indent 函数会在每行前添加指定数量的空格,而 nindent 会在每行前添加指定数量的空格,并且保留行首的缩进。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myconfig: |-
{{ .Values.configContent | nindent 4 }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
configContent: |
database:
user: admin
password: secret
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 17:37:49 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
myconfig: |-
database:
user: admin
password: secret
6、toYaml 函数
toYaml 函数将一个对象转换为 YAML 格式。通常用于渲染嵌套的数据结构。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
values_yaml: |-
{{ .Values.app | toYaml | nindent 4 }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
app:
name: myapp
version: 2.0
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 17:39:12 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
values_yaml: |-
name: myapp
version: 2
7、upper和title 函数
upper 函数将字符串转换为大写,而 title 函数将字符串的每个单词首字母转换为大写。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_name: {{ .Values.app_name | upper }}
app_name: {{ .Values.app_name | title }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
app_name: myapp
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 18:01:43 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
app_name: MYAPP
app_name: Myapp
8、lower 函数
lower 函数将字符串转换为小写。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_name: {{ .Values.app_name | lower }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
app_name: myapp
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 18:05:31 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
app_name: myapp
9、cat 函数
cat 函数用于连接多个字符串,它接受一个或多个字符串并返回它们的连接结果。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_name_with_version: {{ .Values.appName | cat “-” .Values.version }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
appName: myapp
version: v2.0.0
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
apiVersion: v1
kind: ConfigMap
metadata:
name: myrelease-configmap
data:
app_name_with_version: myapp-v2.0.0
10、trim 函数
trim 函数用于移除字符串两侧的空格或其他指定字符。
[root@mast01 huqi]# vim my-app-chart/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
app_name: {{ .Values.app_name | trim }}
假设 values.yaml 中有以下内容:
[root@mast01 huqi]# vim my-app-chart/values.yaml
app_name: myapp
模板渲染后:
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Tue Jan 7 18:12:46 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/ConfigMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-configmap
data:
app_name: myapp
11、使用管道和函数动态生成配置
在 Helm 中,我们可以使用管道和函数进行更复杂的操作,提升模板的灵活性。比如,我们需要设置默认值、处理配置文件和检查某些条件:
[root@mast01 huqi]# vim my-app-chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
labels:
app: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount | default 2 }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
– name: {{ .Release.Name }}
image: “{{ .Values.image.repository }}:{{ .Values.image.tag | default “latest” }}”
imagePullPolicy: {{ .Values.image.pullPolicy | default “IfNotPresent” }}
ports:
– containerPort: {{ .Values.service.port | default 8080 }}
resources:
requests:
cpu: {{ .Values.resources.requests.cpu | default “100m” }}
memory: {{ .Values.resources.requests.memory | default “256Mi” }}
limits:
cpu: {{ .Values.resources.limits.cpu | default “500m” }}
memory: {{ .Values.resources.limits.memory | default “512Mi” }}
在这个例子中,我们使用了:
default:为多个参数提供默认值,如果用户在 values.yaml中没有定义这些值,它们会自动使用默认配置。
例如,replicaCount 默认值为 2,image.tag 默认为 latest,image.pullPolicy 默认为 IfNotPresent。
管道:通过管道连接函数,可以方便地在模板中做值的转换和处理。
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Mon Jan 6 16:27:18 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
– protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
Source: my-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
– name: my-app
image: “my-web-app:latest”
imagePullPolicy: Always
ports:
– containerPort: 8080
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
12、ingress.yaml (可选)
如果 ingress.enabled 为 true,我们将动态创建一个 Ingress 资源。
[root@mast01 my-app-chart]# vim templates/ingress.yaml
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
annotations:
{{- toYaml .Values.ingress.annotations | nindent 4 }}
spec:
rules:
– host: {{ .Values.ingress.host }}
http:
paths:
– path: {{ .Values.ingress.path }}
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-service
port:
number: {{ .Values.service.port }}
{{- end }}
在这个模板中:
{{ .Values.ingress.enabled }}:检查是否启用了 Ingress。
toYaml:将 ingress.annotations 转换为 YAML 格式。
nindent:将生成的 YAML 缩进,以便在模板渲染时正确显示。
[root@mast01 huqi]# helm install –dry-run my-app ./my-app-chart
NAME: my-app
LAST DEPLOYED: Mon Jan 6 16:34:18 2025
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
Source: my-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
– protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
Source: my-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
– name: my-app
image: “my-web-app:latest”
imagePullPolicy: Always
ports:
– containerPort: 8080
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
Source: my-app/templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
{}
spec:
rules:
– host: my-web-app.local
http:
paths:
– path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 8080
13、部署与测试
安装 Helm Chart:
[root@mast01 huqi]# helm install my-app ./my-app-chart
查看生成的 Kubernetes 资源: 你可以通过 kubectl 命令查看生成的 Deployment、Service 和其他资源:
[root@mast01 helm]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-app-deployment 0/3 3 0 49s
[root@mast01 helm]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-app-service ClusterIP 10.100.135.137 8080/TCP 22s
[root@mast01 helm]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-app-ingress my-web-app.local 80 3s
升级 Helm Chart: 修改 values.yaml 后,你可以通过 Helm 升级部署:
[root@mast01 huqi]# helm upgrade my-app ./my-app-chart
14、总结
在本示例中,我们展示了如何使用 Helm 函数与管道结合来动态生成 Kubernetes 资源模板。通过 Helm 强大的模板引擎,我们可以利用多种内置函数和管道操作来灵活地生成配置,处理不同的应用场景,并确保 Kubernetes 资源的灵活性和可定制性。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/424717.html