> 文档中心 > K8s:通过 Helmify 实现将 YAML 文件 转化为 Helm Charts

K8s:通过 Helmify 实现将 YAML 文件 转化为 Helm Charts


写在前面


  • 分享一个 Yaml 资源文件Helm Charts 包的小工具 helmify
  • 博文内容涉及:
  • helmify 工具安装,简单使用
  • YAML 静态文件转化为 HELM charts 包
  • kustomize 输出转化为 Helm
  • 理解不足小伙伴帮忙指正
  • 博文涉及 helmify

我心匪石,不可转也。我心匪席,不可卷也。——《邶风·柏舟》


简单介绍及安装

如果部署环境涉及的 k8s API 资源比较多,往往会通过定义一个 charts 包来统一管理,变动的部分通过模板变量的方式引用。

正常我们创建一个 Helm chart 包。会通过命令 helm create 来创建

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$helm create  liruilonghelmCreating liruilonghelm┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$lsindex.yaml  liruilonghelm  mysql  mysql-1.6.4.tgz

打包 push 私有 helm 源会通过下面的命令操作

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$helm package liruilonghelm/Successfully packaged chart and saved it to: /root/ansible/k8s-helm-create/liruilonghelm-0.1.0.tgz

那么对于已经存在的 yaml 资源文件,或者部署的集群中的环境,如何生成 chart 包,可以把对应的 资源文件导出来,然后手工编写对应的 charts 包,类似 Ansible 中 角色的编写。

通过 helmify 我们可以把上面的过程变成自动的。helmify 支持大部分的 api 资源转化为 对应的 charts 包。Helmify 从 标准输入 读取支持的 k8s 对象列表,并将其转换为 helm chasrts。

我们还可以获得 k8s 上现有服务的 YAML 文件,并可以将其转换为使用 helmify。

helmify 支持的 k8s 资源:

  • deployment
  • daemonset
  • service, Ingress
  • PersistentVolumeClaim
  • RBAC (serviceaccount, (cluster-)role, (cluster-)rolebinding)
  • configs (configmap, secret)
  • webhooks (cert, issuer, ValidatingWebhookConfiguration)
  • custom resource definitions

下载安装

下载二进制安装包

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$wget https://github.com/arttor/helmify/releases/download/v0.3.22/helmify_0.3.22_Linux_64-bit.tar.gz

解压,配置为可执行文件

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$tar -zxvf helmify_0.3.22_Linux_64-bit.tar.gzhelmify┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$chmod +x helmify┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$mv helmify  /usr/local/bin/┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$helmify -versionVersion:    0.3.22Build Time: 2022-12-17T15:55:46ZGit Commit: 253310a3cd32156f6952e9a4a9ec4d1e387f7775

这里需要注意支持 Helm >=v3.6.0

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$helm  versionversion.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}

如果 helm 版本太旧的话,需要更新 Helm

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$tar -zxvf helm-v3.11.0-rc.1-linux-amd64.tar.gzlinux-amd64/linux-amd64/helmlinux-amd64/LICENSElinux-amd64/README.md┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$mv linux-amd64/helm /usr/local/bin/mv:是否覆盖"/usr/local/bin/helm"? y┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$helm versionversion.BuildInfo{Version:"v3.11.0-rc.1", GitCommit:"9d8fee155bd7e7d3c1390f4076d9271a1147dce5", GitTreeState:"clean", GoVersion:"go1.18.9"}┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-helm-create]└─$

使用方式

将 YAML 文件转换为 Helm chart 包

dashboard 创建服务账号 sa 的一个 yaml 文件。

┌──[root@vms81.liruilongs.github.io]-[~/ansible]└─$cat dashboard-adminuser.yamlapiVersion: v1kind: ServiceAccountmetadata:  name: admin-user  namespace: kubernetes-dashboard---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: admin-userroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: cluster-adminsubjects:- kind: ServiceAccount  name: admin-user  namespace: kubernetes-dashboard┌──[root@vms81.liruilongs.github.io]-[~/ansible]└─$cat  dashboard-adminuser.yaml | helmify mychart

可以通过下面的方式生成 charts 包

┌──[root@vms81.liruilongs.github.io]-[~/ansible]└─$cat  dashboard-adminuser.yaml | helmify mychart

生成的数据文件信息

┌──[root@vms81.liruilongs.github.io]-[~/ansible/mychart]└─$tree -h.├── [1.1K]  Chart.yaml├── [  77]  templates│   ├── [ 405]  admin-user-rbac.yaml│   ├── [ 157]  deployment.yaml│   └── [1.7K]  _helpers.tpl└── [  39]  values.yaml1 directory, 5 files

可以通过下面的命令查看生成的 charts 包 的资源文件

┌──[root@vms81.liruilongs.github.io]-[~/ansible/mychart]└─$helm template  ./---# Source: mychart/templates/deployment.yamlapiVersion: v1kind: ServiceAccountmetadata:  name: release-name-mychart-admin-user  labels:    helm.sh/chart: mychart-0.1.0    app.kubernetes.io/name: mychart    app.kubernetes.io/instance: release-name    app.kubernetes.io/version: "0.1.0"    app.kubernetes.io/managed-by: Helm---# Source: mychart/templates/admin-user-rbac.yamlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: release-name-mychart-admin-user  labels:    helm.sh/chart: mychart-0.1.0    app.kubernetes.io/name: mychart    app.kubernetes.io/instance: release-name    app.kubernetes.io/version: "0.1.0"    app.kubernetes.io/managed-by: HelmroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: cluster-adminsubjects:- kind: ServiceAccount  name: 'release-name-mychart-admin-user'  namespace: 'liruilong-topo-namespace'┌──[root@vms81.liruilongs.github.io]-[~/ansible/mychart]└─$

也可以从带有 yamls 的目录生成:

awk 'FNR==1 && NR!=1  {print "---"}{print}' /<my_directory>/*.yaml | helmify mychart

从kustomize输出转换为 Helm chart 包

一个简单的 Demo

下面为一个 kustomize 元文件。

┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$cat kustomization.yamlnamespace: my-namespacenamePrefix: dev-nameSuffix: "-001"commonLabels:  app: liruilong-appcommonAnnotations:  isDemo: "true"configMapGenerator:- name: example-configmap-liruilong-env  literals:  - FOO=Bar

通过下面的命令我们可以看到 kustomize 生成的 yaml 文件的内容。

┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$kustomize  build ./apiVersion: v1data:  FOO: Barkind: ConfigMapmetadata:  annotations:    isDemo: "true"  labels:    app: liruilong-app  name: dev-example-configmap-liruilong-env-001-42cfbf598f  namespace: my-namespace

使用下面的命令我们可以生成上面 kustomize build 生成的 charts

┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$kustomize  build ./ | helmify mychart┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$lskustomization.yaml  mychart┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$tree -h mychart/mychart/├── [1.1K]  Chart.yaml├── [  89]  templates│   ├── [ 333]  dev-example-configmap-liruilong-env-001-42cfbf598f.yaml│   └── [1.7K]  _helpers.tpl└── [  96]  values.yaml1 directory, 4 files┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$

查看生成的 charts 包的 yaml 资源内容。

┌──[root@vms81.liruilongs.github.io]-[~/kustomize/failed]└─$helm template  ./mychart---# Source: mychart/templates/dev-example-configmap-liruilong-env-001-42cfbf598f.yamlapiVersion: v1kind: ConfigMapmetadata:  name: release-name-mychart-dev-example-configmap-liruilong-env-001-42cfbf598f  labels:    app: liruilong-app    helm.sh/chart: mychart-0.1.0    app.kubernetes.io/name: mychart    app.kubernetes.io/instance: release-name    app.kubernetes.io/version: "0.1.0"    app.kubernetes.io/managed-by: Helm  annotations:    isDemo: "true"data:  FOO: "Bar"

Deployment Demo

一个通过 kustomize 来生成一个 Deployment 资源的 Demo,kustomization 文件定义。

┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$cat kustomization.yamlresources:- deploy.yamlconfigMapGenerator:- name: example-configmap-liruilong  files:  - application.properties┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$

生成的 YAML 资源文件

┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$kubectl kustomize ./apiVersion: v1data:  application.properties: |    sendSMS.maxAuthSendNumber=3    sendSMS.maxAuthNumber=3    sendSMS.validationCodeExpirationTime=300000    sendSMS.VerificationCodeLength=4kind: ConfigMapmetadata:  name: example-configmap-liruilong-42d226k4h6---apiVersion: apps/v1kind: Deploymentmetadata:  creationTimestamp: null  labels:    app: web  name: webspec:  replicas: 3  selector:    matchLabels:      app: web  strategy: {}  template:    metadata:      creationTimestamp: null      labels: app: web    spec:      containers:      - image: nginx:1.14.2 name: nginx-web ports: - containerPort: 80   name: nginx-web      volumes:      - configMap:   name: example-configmap-liruilong-42d226k4h6 name: config resources: {}status: {}

通过 helmify 生成对应的 chart 包, -v 可以查看详细的生成信息。

┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$kubectl kustomize ./ | helmify -v nginx-webINFO[0000] creating a chart  ChartName=nginx-web Namespace=INFO[0000] Skip creating Chart skeleton: Chart.yaml already exists.INFO[0000] overwrittenfile=nginx-web/templates/example-configmap-liruilong-42d226k4h6.yamlINFO[0000] overwrittenfile=nginx-web/templates/deployment.yamlINFO[0000] overwrittenfile=nginx-web/values.yaml┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$kubectl kustomize ./ | helmify -vv nginx-webDEBU[0000] Start processing...DEBU[0000] decoded    ApiVersion=v1 Kind=ConfigMap Name=example-configmap-liruilong-42d226k4h6DEBU[0000] decoded    ApiVersion=apps/v1 Kind=Deployment Name=webDEBU[0000] EOF received. Finishing input objects decoding.INFO[0000] creating a chart  ChartName=nginx-web Namespace=DEBU[0000] processed  ApiVersion=v1 Kind=ConfigMap Name=example-configmap-liruilong-42d226k4h6DEBU[0000] processed  ApiVersion=apps/v1 Kind=Deployment Name=webINFO[0000] Skip creating Chart skeleton: Chart.yaml already exists.DEBU[0000] writing a template into  file=nginx-web/templates/example-configmap-liruilong-42d226k4h6.yamlINFO[0000] overwrittenfile=nginx-web/templates/example-configmap-liruilong-42d226k4h6.yamlDEBU[0000] writing a template into  file=nginx-web/templates/deployment.yamlINFO[0000] overwrittenfile=nginx-web/templates/deployment.yamlINFO[0000] overwrittenfile=nginx-web/values.yaml

生成的 helm charts 文件结构

┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$tree nginx-web/nginx-web/├── Chart.yaml├── templates│   ├── deployment.yaml│   ├── example-configmap-liruilong-42d226k4h6.yaml│   └── _helpers.tpl└── values.yaml1 directory, 5 files

可以通过下面的方式查看 chart 包的 YAML 文件信息

┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$helm template nginx-web/---# Source: nginx-web/templates/example-configmap-liruilong-42d226k4h6.yamlapiVersion: v1kind: ConfigMapmetadata:  name: release-name-nginx-web-example-configmap-liruilong-42d226k4h6  labels:    helm.sh/chart: nginx-web-0.1.0    app.kubernetes.io/name: nginx-web    app.kubernetes.io/instance: release-name    app.kubernetes.io/version: "0.1.0"    app.kubernetes.io/managed-by: Helmdata:  application.properties: |    sendSMS.maxAuthSendNumber="3"    sendSMS.maxAuthNumber="3"    sendSMS.validationCodeExpirationTime="300000"    sendSMS.VerificationCodeLength="4"---# Source: nginx-web/templates/deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:  name: release-name-nginx-web-web  labels:    app: web    helm.sh/chart: nginx-web-0.1.0    app.kubernetes.io/name: nginx-web    app.kubernetes.io/instance: release-name    app.kubernetes.io/version: "0.1.0"    app.kubernetes.io/managed-by: Helmspec:  replicas: 3  selector:    matchLabels:      app: web      app.kubernetes.io/name: nginx-web      app.kubernetes.io/instance: release-name  template:    metadata:      labels: app: web app.kubernetes.io/name: nginx-web app.kubernetes.io/instance: release-name    spec:      containers:      - env: - name: KUBERNETES_CLUSTER_DOMAIN   value: cluster.local image: nginx:1.14.2 name: nginx-web ports: - containerPort: 80   name: nginx-web resources: {}      volumes:      - configMap:   name: release-name-nginx-web-example-configmap-liruilong-42d226k4h6 name: config┌──[root@vms81.liruilongs.github.io]-[~/kustomize]└─$

博文参考


https://medium.com/geekculture/convert-kubernetes-yaml-files-into-helm-charts-4107de079455