DevOps系列Helmfile对已存在的helm release的管理实践

作者介绍: helm 分支维护者 helmfile核心维护者

在 helm as code的文章中,已经介绍helm和helmfile的相关内容,包括这两个项目的用途,以及如何进行使用,见识到了helm和helmfile的在云原生应用编排的优势,对于基于helmfile创建的helm release,可以充分享受到helmfile带来的管理优势,但是原本由helm的创建的release,我们如何用helmfile进行管理呢?接下来我们就具体聊一聊。

helm release 组成四要素

  • chart
    helm chart 是一系列yaml的组成集合,并按照helm规定的目录结构排列,结合Go template系统,可以结合不同配置来生成不同的release。具体可以参阅: https://helm.sh/docs/topics/charts/

  • configuration
    configuration顾名思义,就是针对chart的自定义配置,根据需求传入到chart中,来满足不同场景的部署需求。

  • namespace
    为什么会提到namespace呢?那就得说一下helm的release保存和版本化原理,在我们每次进行helm upgrade --install --namespace <namespace> --create-namespace时候,helm会将相关的资源进行gzip打包,并以secret的形式保存在k8s中的namespace里,我们进行rollback的时候也会读取相关的secret。

  • release name 在使用helm进行安装chart时,指定的release 名称

了解四要素后,接下来我们就具体实践一下如何做吧:

helmfile 纳管已存在的 helm release

模拟原生helm部署应用

1. helm 生成模板chart
helm create chartexample
2. helm安装应用
# cat values.yaml
image:
  tag: 1.23.1

# helm upgrade chartexample ./chartexample --install --namespace testchart --create-namespace -f values.yaml

# helm list -n testchart
NAME        	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART             	APP VERSION
chartexample	testchart	1       	2022-10-04 11:52:53.746614286 +0800 CST	deployed	chartexample-0.1.0	1.16.0

至此,我们已经模拟出以本地目录作为chart的helm release。

helmfile纳管release流程

1. 获取chart

当前示例中,chart的位置位于./chartexample,这个在配置helmfile会用到。

2. 获取namespace

helm upgrade 的 –namespace 对应的值即为 namespace,默认为kubeconfig中对应的namespace。

3. 获取configuration

# testchart 是helm upgrade配置的namesapce
# chartexample是helm  release名称
helm get values chartexample -n testchart | grep -v "^USER-SUPPLIE" > values.yaml

4. 编写helmfile.yaml

目录结构:

.
├── chartexample            # chart的本地目录
│   ├── charts
│   ├── Chart.yaml
│   ├── templates
│   │   ├── deployment.yaml
│   │   ├── _helpers.tpl
│   │   ├── hpa.yaml
│   │   ├── ingress.yaml
│   │   ├── NOTES.txt
│   │   ├── serviceaccount.yaml
│   │   ├── service.yaml
│   │   └── tests
│   │       └── test-connection.yaml
│   └── values.yaml
├── environments              # helmfile的环境目录,可以配置多个环境,比如stg、prd,默认是default
│   └── default
│       └── values.yaml.gotmpl # 对应default环境的配置
├── helmfile.yaml             # helmfile的主配置
└── values
    └── values.yaml.gotmpl    # helm release的values配置,可根据不同环境的配置生成不同的内容,传递给helm upgrade命令。
# cat values/values.yaml.gotmpl
{{ .Values.chartexample | toYaml }}
# cat environments/default/values.yaml.gotmpl
chartexample:
  image:
    tag: 1.23.3
  replicaCount: 2

# cat helmfile.yaml
environments:
{{- range $index, $item := (readDirEntries "environments") -}}
  {{ if $item.IsDir }}
  {{ $item.Name }}:
    values:
      - "environments/{{ $item.Name }}/*.yaml.gotmpl"
  {{- end }}
{{- end }}

releases:
- name: chartexample
  namespace: testchart
  chart: ./chartexample
  values:
    - "values/values.yaml.gotmpl" # 传递给helm upgrade的values文件,不同环境生成不同的配置。

该文件使用go template的模式编写以及helmfile的自定义的template func,详情请参与helmfile的文档: https://helmfile.readthedocs.io/

helmfile操作:

# 1. helmfile自动比较差异,有变更时自动更新
helmfile apply
# 2. 分步骤确认更新
helmfile diff -f helmfile.yaml # 只比较差异,并前台打印

Building dependency release=chartexample, chart=chartexample
Comparing release=chartexample, chart=chartexample
testchart, chartexample, Deployment (apps) has changed:
  # Source: chartexample/templates/deployment.yaml
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: chartexample
    labels:
      helm.sh/chart: chartexample-0.1.0
      app.kubernetes.io/name: chartexample
      app.kubernetes.io/instance: chartexample
      app.kubernetes.io/version: "1.16.0"
      app.kubernetes.io/managed-by: Helm
  spec:
    replicas: 2
    selector:
      matchLabels:
        app.kubernetes.io/name: chartexample
        app.kubernetes.io/instance: chartexample
    template:
      metadata:
        labels:
          app.kubernetes.io/name: chartexample
          app.kubernetes.io/instance: chartexample
      spec:
        serviceAccountName: chartexample
        securityContext:
          {}
        containers:
          - name: chartexample
            securityContext:
              {}
-           image: "nginx:1.23.1"
+           image: "nginx:1.23.3"
            imagePullPolicy: IfNotPresent
            ports:
              - name: http
                containerPort: 80
                protocol: TCP
            livenessProbe:
              httpGet:
                path: /
                port: http
            readinessProbe:
              httpGet:
                path: /
                port: http
            resources:
              {}

helmfile sync -f helmfile.yaml # 同步变更

总结

通过helmfile进行纳管已存在的helm release,我们就可以拥有helmfile的声明式管理helm release的能力,做到变更可预知,发布更放心。还等什么?让我们行动起来,尽情享受helmfile带来的便利吧!

文章同步发布: aiopsclub.com

helmfile: github.com/helmfile/helmfile
helm: github.com/helm/helm

「真诚赞赏,手留余香」

roc

请我喝杯咖啡?

使用微信扫描二维码完成支付