kubernetes应用包管理器helm下
2054字约7分钟
2024-09-29
Chart模板:函数与管道
常用函数:
quote:将值转换为字符串,即加双引号
default:设置默认值,如果获取的值为空则为默认值
indent和nindent:缩进字符串
toYaml:引用一块YAML内容
其他函数:upper、title等
upper: 将值修改为大写 title: 将值首字母修改为大写
quote:将值转换为字符串,即加双引号
示例:nodeSelector标签的值用了true正常使用会报错,这是因为它是关键字,需要加引号才可以。
#vi mychart/values.yaml
replicaCount: 1
image:
repository: nginx
tag: "latest"
selectorLabels: "nginx"
nodeSelector:
gpu: true
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web2
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
apiVersion: v1
kind: Service
metadata:
labels:
app: web2
name: {{ .Release.Name }}
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: {{ .Values.selectorLabels }}
验证部署
helm install web2 --dry-run mychart/
helm install web2 mychart/
default:设置默认值,如果获取的值为空则为默认值
示例:以防止忘记定义而导致模板文件缺少字段无法创建资源,这时可以为字段定义一个默认值。
#vi mychart/values.yaml
replicaCount: 1
image:
repository: nginx
tag: "latest"
selectorLabels: "nginx"
nodeSelector:
gpu: true
labels:
app: ""
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Values.labels.app | default "web2" }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
验证部署
helm install web3 --dry-run mychart/
helm install web3 mychart/
这里用到了管道符“|”,前面的值传递后函数验证是否为空。
indent和nindent函数都是缩进字符串,主要区别在于nindent会在缩进前多添加一个换行符。
示例:
toYaml:引用一块YAML内容
示例:在values.yaml里写结构化数据,引用内容块
#vi mychart/values.yaml
replicaCount: 1
image:
repository: nginx
tag: "latest"
selectorLabels: "nginx"
nodeSelector:
gpu: true
labels:
app: ""
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Values.labels.app | default "web2" }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
resources:
{{ toYaml .Values.resources | nindent 10 }}
验证
helm install web4 --dry-run /root/mychart/
helm install web4 --set resources.limits.cpu="200m" --dry-run /root/mychart/
Chart模板:流程控制
Helm模板语言提供以下流程控制语句:
if/else:条件判断
range:循环
with:指定变量作用域
Chart模板:流程控制之if/else
条件判断:根据不同的条件做不同的行为
语法:
{{ if <表达式> }}
# 做某事
{{ else if <表达式> }}
# 做某事
{{ else }}
# 默认
{{ end }}
示例:部署一个应用,在没明确启用ingress时,默认情况下不启用
# values.yaml
ingress:
enabled: false
#vi mychart/templates/ingress.yaml
{{ if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
{{ end }}
验证
helm install web1 --set ingress.enabled=true --dry-run /root/mychart/
如果值为以下几种情况则为false:
一个布尔类型 false
一个数字 0
一个空的字符串
一个 nil(空或 null)
一个空的集合( map、 slice、 tuple、 dict、 array)
条件表达式也支持操作符:
eq 等于
ne 不等于
lt 小于
gt 大于
and 逻辑与
or 逻辑或
示例:如果是一个空的集合则不启用资源配额
#vi mychart/values.yaml
replicaCount: 1
image:
repository: nginx
tag: "latest"
selectorLabels: "nginx"
nodeSelector:
gpu: true
labels:
app: ""
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
ingress:
enabled: false
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Values.labels.app | default "web2" }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- end }}
验证渲染结果:
helm install test --dry-run mychart/
渲染结果会发现有多余的空行,这是因为模板渲染时会将 指令删除,所以原有的位置就空白了。可以使用横杠“-” 消除空
Chart模板:流程控制之range
循环:一般用于遍历序列结构的数据。例如序列、键值
语法:
{{ range <值> }}
# 引用内容
{{ end }}
示例:遍历数据
#vi mychart/values.yaml
test:
- 1
- 2
- 3
#vi mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}
data:
test: |
{{- range.Values.test }}
{{ . }} # 引用当前元素
{{- end }}
验证渲染结果
helm install web1 --dry-run mychart/
Chart模板:流程控制之with
with:指定变量作用域
语法:
{{ with <值> }}
# 限制范围
{{ end }}
with语句可以允许将当前范围 . 设置为特定的对象,比如我们前面一直使用 的 .Values.nodeSelecotr,我们可以使用 with来将 . 范围指向 .Values.nodeSelecotr:
示例:
#vi mychart/values.yaml
labels:
operation: "ms"
app: "gateway"
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- with .Values.labels }}
operation: {{ .operation }}
app: {{ .app }}
{{- end }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- end }}
验证渲染结果
helm install web1 --dry-run mychart/
with块限制了变量作用域,也就是无法直接引用模板对象,例 如.Values、.Release,如果还想使用,可以定义变量来解决该问题。
示例:
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- $rs := .Values.replicaCount }}
{{- with .Values.labels }}
operation: {{ .operation }}
app: {{ .app }}{{ $rs }}
# test: {{ $rs }}
{{- end }}
name: {{ .Release.Name }}
spec:
...
验证
helm install web1 --dry-run mychart/
或者
Chart模板:变量
变量是实际应用中不多,但有时候结合with、range能更好处理数据。
示例:k8s变量是键值,可以range遍历生成
#vi mychart/values.yaml
env:
NAME: "gateway"
JAVA_OPTS: "-Xmx1G"
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- $rs := .Values.replicaCount }}
{{- with .Values.labels }}
operation: {{ .operation }}
app: {{ .app }}{{ $.Values.replicaCount }}
# test: {{ $rs }}
{{- end }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- end }}
env:
{{- range $k,$v := .Values.env }}
- name: {{ $k }}
value: {{ quote $v }}
{{- end }}
验证渲染结果:
helm install web1 --dry-run mychart/
Chart模板:命名模板
命名模板类似于开发语言中的函数。指一段可以直接被另一段程序或代码引用的程序或代码。 在编写chart时,可以将一些重复使用的内容写在命名模板文件中供公共使用,这样可减少重 复编写程序段和简化代码结构。
命名模块使用define定义,template或include引入,在templates目录中默认下划线开头的 文件为公共模板(helpers.tpl)。
示例:资源名称生成指令放到公共模板文件,作为所有资源名称
#vi mychart/templates/_helpers.tpl
{{- define "fullname" -}}
{{- .Chart.Name -}}-{{ .Release.Name }}
{{- end -}}
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- $rs := .Values.replicaCount }}
{{- with .Values.labels }}
operation: {{ .operation }}
app: {{ .app }}{{ $.Values.replicaCount }}
# test: {{ $rs }}
{{- end }}
name: {{ template "fullname" . }}
验证渲染结果:
helm install web1 --dry-run mychart/
template指令是将一个模板包含在另一个模板中的方法。但是,template函 数不能用于Go模板管道。为了解决该问题,引入include指令。
示例:
#vi mychart/templates/_helpers.tpl
{{- define "labels" -}}
operation: {{ .Values.labels.operation }}
app: {{ .Values.labels.app }}
{{- end -}}
#vi mychart/templates/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- include "labels" .| nindent 4 }}
name: {{ template "fullname" . }}
验证渲染结果:
helm install web1 --dry-run mychart/
带你写一个通用的Chart
先创建模板示例 helm create demo
修改Chart.yaml,Values.yaml,参考示例预留变动的字段值
在templates目录下准备部署应用所需的yaml文件,并添加指令引用 Values.yaml字段
将重复使用的内容作为命名模板
使用Chart结合参数部署多个同类服务
使用Harbor作为Chart仓库
Harbor是一个主流的镜像仓库系统,在 v1.6 版本以后的 harbor 中新增加了 helm charts 的管理功能,可以存储Chart文件。
使用步骤:
1、启用Harbor的Chart仓库服务
# ./install.sh --with-chartmuseum
启用后,默认创建的项目就带有helm charts功能了。
2、安装push插件
helm plugin install https://github.com/chartmuseum/helm-push
ls /root/.local/share/helm/plugins/helm-push/ #家目录
3、推送
# helm push demo-0.1.0.tgz --username=admin --password=Harbor12345 http://192.168.0.13/chartrepo/library
4、添加repo
helm repo add myrepo --username=admin --password=Harbor12345 http://192.168.0.13:/chartrepo/library
helm repo update
helm repo list
5、部署
# helm install web --version 0.1.0 myrepo/demo #--version指定chart版本,如果未指定,使用最新版本
helm install web1 --set service.type=NodePort --set service.nodeport=30010 myrepo/demo
公共Chart仓库
国内Chart仓库,可直接使用它们制作好的包:
微软仓库(http://mirror.azure.cn/kubernetes/charts/)
阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts )
官方仓库(https://hub.kubeapps.com/charts/incubator)
添加仓库方式:
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update
helm repo list