💩 一些 Helm 最(tòng)佳(kǔ)实践

date
Sep 1, 2021
slug
helm-pratices.html
status
Published
tags
helm
best-practice
k8s
tech
summary
标题的 emoji 就是我对 Helm 的评价
type
Post
 

yaml工程师的血泪 shi

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

# values.yaml
sub-foo-chart:
  preferName: "Happy"

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

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

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

所有的依赖关系必须简化成两层
# 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  ❌ 并不能够生效
 

Hook 创建的资源不能被 uninstall

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 💩:
kubectl delete deploy,sts,cronjob,pod,svc,ingress,secret,cm,sa,pvc -n ${NAMESPACE} -l app.kubernetes.io/instance=${RELEASE_NAME}
 

一些苦中作乐的解决方案

 

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

如果项目中存在多个模块,那么可以通过 subChart 方式统一整合
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 的定义和封装:
# 定义应用内的多个进程
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 设计弊病带来的不便。
 

© bluesyu 2019 - 2024

powered by nobelium