写Helm Chart之前我希望提前知道的8个有用的事项
这是Kubernetes3 Adcent Calendar 2018年11月份的第11篇文章。
在开始编写Helm Chart模板之前,我会介绍一些我希望在此之前就知道的要点。
基本上,如果你能好好地读一下《图表模板开发人员指南》,然后再开始,就可以了…
如果存在多个环境,使用”–values”选项可以按环境指定变量,这看起来是个不错的选择。
看起来像是需要根据环境使用不同的变量文件,就像这个幻灯片上所展示的一样。(因为我们是同一家公司,所以我也在学习他们的做法…)
2. –set选项将覆盖–values指定的文件
在只需要修改tag指定时使用。
3. – 很困难
如果在if语句中去掉前面的空格和换行符号,可以实现相应的去除操作,但是如果只想显示else部分,就比较难控制了…如果按照下面这样写
{{- if .Values.hpa.enabled -}}
{{- else -}}
replicas: {{ .Values.replicas | default "2" }}
{{- end -}}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
由于不符合正确的yaml格式,会导致出现以下情况,因此会产生错误…
spec:replicas: 3selector:
matchLabels:
app.kubernetes.io/name: my-chart
app.kubernetes.io/instance: my-chart
文档中写着要使用缩进函数({{indent 2 “mug:true”}}),但是按照这种方法,无法使用默认值(?),所以最终我选择了下面的方式。
spec:
{{- if .Values.hpa.enabled -}}
{{- else }}
replicas: {{ .Values.replicas | default "2" }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
当.Values.hpa.enabled为true时,
spec:
selector:
matchLabels:
app.kubernetes.io/name: my-chart
app.kubernetes.io/instance: my-chart
当.Values.hpa.enabled参数为false时,
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: my-chart
app.kubernetes.io/instance: my-chart
尝试使用以下方法,
{{- if .Values.hpa.enabled -}}
{{- else }}
replicas: {{ .Values.replicas | default "2" }}
{{ end -}}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
当是真的时不行了…
spec:selector:
matchLabels:
app.kubernetes.io/name: my-chart
app.kubernetes.io/instance: my-chart
template:
metadata:
labels:
app.kubernetes.io/name: my-chart
app.kubernetes.io/instance: my-chart
使用include和nindent可能比使用template更好。
由于模板的缩进不能被控制,建议使用 “{{- include xxx . | nindent n }}” 这样的写法。
在存在多个容器的情况下特别方便。
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "my-chart.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
helm.sh/chart: {{ include "my-chart.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
{{- if .Values.hpa.enabled -}}
{{- else }}
replicas: {{ .Values.replicas | default "2" }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
# ここ
{{- include "my-chart.app" . | nindent 6 }}
{{- include "my-chart.sidecar" . | nindent 6 }}
5. 使用“with”能少写一些字,但是也有利有弊。
使用”with”语句时,只能使用该范围内的变量,如果想要使用不同层次的变量,只能通过结束或重新定义来实现。
因此,前面提到在使用多个容器时可能需要分割模板,但是使用”with”语句时,也可能需要为每个范围定义变量。
{{- define "my-chart.sidecar" -}}
{{- with .Values.sidecar -}}
- image: "{{ .image.repository }}:{{ .image.tag | default "v1.0.2" }}"
name: sidecar
resources:
requests:
cpu: {{ .resources.requests.cpu | default "50m" }}
memory: {{ .resources.requests.memory | default "50Mi" }}
limits:
cpu: {{ .resources.limits.cpu | default "100m" }}
memory: {{ .resources.limits.memory | default "100Mi" }}
ports:
- containerPort: 24224
name: sidecar
protocol: "TCP"
env:
- name: SIDECAR_WEB_HOST
value: "localhost:9990"
{{- end -}}
{{- end -}}
6. 模板的嵌套和with的嵌套
模板的嵌套可以很普遍地实现。缩进会被继承,因此在下面的例子中是6 + 2。(因为在上面示例中的deployment中的{{- include “my-chart.app” . | nindent 6 }})
{{- define "my-chart.app" -}}
{{- with .Values.app -}}
- name: app
image: "{{ .image.repository }}:{{ .image.tag }}"
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
requests:
cpu: {{ .resources.requests.cpu | default "100m" }}
memory: {{ .resources.requests.memory | default "500Mi" }}
limits:
cpu: {{ .resources.limits.cpu | default "100m" }}
memory: {{ .resources.limits.memory | default "500Mi" }}
env:
{{- include "my-chart.app.env" . | nindent 2 }}
{{- end -}}
{{- end -}}
然而,由于使用“with”的范围仍然是父级的,所以在.Values.app的模板中进行include时,它将成为.Values.app的范围。
{{- define "my-chart.app.env" -}}
# .Values.app.envではない
{{- with .env -}}
env:
- name: APP_ENVIRONMENT
value: {{ .APP_ENVIRONMENT | quote }}
- name: WRK_WARMUP_DURATION
value: {{ .WRK_WARMUP_DURATION | default "10" | quote }}
{{- end -}}
{{- end -}}
8. Values的键是必需的。
CPU:即使设置了默认值(”100m”),变量文件中还必须始终将requests写成如下形式。
resources:
requests: {}
limits: {}
因此,如果将其按照上述方式分成多个容器并进行结构化,即使是对于默认值的情况,也不得不写更多的键。
environment: dev
replicas: 3
app:
image:
repository: nginx
tag: stable
resources:
requests: {}
limits: {}
env:
APP_ENVIRONMENT: dev
sidecar:
image:
repository: fluentd
tag: stable
resources:
requests: {}
limits: {}
hpa:
enabled: false
最后
最终
最后
设计变量和模板的设计是一个让人头疼的问题。目前还在摸索中…