yaml工程师的血泪 shi

子 Chart 使用中划线时无法作为参数路径选取

1
2
3
4
5
6
7
8
# values.yaml
sub-foo-chart:
preferName: "Happy"

# _helper.tpl
{{ .Values.sub-foo-chart.preferName }} 错误写法

{{ index .Values "sub-foo-chart" "preferName" }} 💩 正确但丑陋的写法

Accessing values of the subchart with dash in the name · Issue #2192 · helm/helm

Chart 之间的继承关系只能有一级

所有的依赖关系必须简化成两层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# parentchart/requirements.yaml
dependencies:
- name: childchart
repository: http://localhost:10191
version: 0.1.0
condition: childchart.enabled

# childchart/requirements.yaml
dependencies:
- name: grandchildchart
repository: http://localhost:10191
version: 0.1.0
condition: grandchildchart1.enabled,childchart.grandchildchart.enabled

# parentchart/values.yaml
childchart:
grandchildchart:
enabled: true 并不能够生效

Nested sub charts values · Issue #5135 · helm/helm

Hook 创建的资源不能被 uninstall

1
2
3
4
annotations:
"helm.sh/hook": "pre-install"
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": hook-failed,before-hook-creation

类似这样通过 helm hook 创建出来的资源,是不能够被 helm uninstall 删除的。如果只是用来做一些临时任务当然问题不大,但是我们利用了 hook 创建了一些内建存储,所以无法删除的特性会带来大量的无用存储资源占用,非常头疼。

可以通过 label 统一删除,一个临时的 workaround 💩:

1
kubectl delete deploy,sts,cronjob,pod,svc,ingress,secret,cm,sa,pvc -n ${NAMESPACE} -l app.kubernetes.io/instance=${RELEASE_NAME}

Manifests with hooks not getting deleted during helm uninstall · Issue #9206 · helm/helm

一些苦中作乐的解决方案

为多个项目模块创建统一的库

如果项目中存在多个模块,那么可以通过 subChart 方式统一整合

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
apiVersion: v2
name: bk-user-stack
description: A Helm chart for bk-user
type: application
version: 0.5.1
appVersion: v2.3.0-a2

dependencies:
- name: bkuserapi
version: "1.0.0"
repository: "file://../api"
condition: bkuserapi.enabled

- name: bkusersaas
version: "1.0.0"
repository: "file://../saas"
condition: bkusersaas.enabled

- name: mariadb
version: "9.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: mariadb.enabled

- name: redis
version: "14.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled

由于 bkuserapibkusersaas 都有类似的架构,所以重复为二者创建 Helm Chart 一定不是明智的选择。

我们针对这种 web 类型的应用多封装了一层,能够一定程度上减少重复劳动。

可以通过自定义的 processes 变量完成对于 workload 的定义和封装:

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
# 定义应用内的多个进程
processes:
web:
ingress:
enabled: true
host: "bkuser-api.{{ .Values.global.sharedDomain }}"
paths: ["/"]
replicas: 1
resources:
limits:
cpu: 1024m
memory: 1024Mi
requests:
cpu: 200m
memory: 128Mi
readinessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 5
periodSeconds: 30
livenessProbe:
httpGet:
path: /ping
port: http
initialDelaySeconds: 5
periodSeconds: 30
celery:
replicas: 1
command:
- bash
args:
- /app/start_celery.sh
beat:
replicas: 1
command:
- bash
args:
- /app/start_beat.sh

具体内容可以参考 TencentBlueking/bk-user部署配置,结合 Makefile 可以实现一件部署\卸载,一定程度上缓解了 Helm 设计弊病带来的不便。