引言
Helmfile 是 Kubernetes 社区广泛使用的工具,它通过声明式配置简化了 Helm charts 的部署和管理。对于需要在不同环境间同步应用状态的团队来说,Helmfile 提供了一种集中化的解决方案。
Helmfile 是什么?
Helmfile 是一个强大的工具,它允许用户以简洁的 YAML 文件定义多个 Helm releases。它支持环境特定的配置,版本控制,并且能够通过 Go Templates 语法提供灵活性。
特性概览
- 集中管理:统一管理集群中的多个 Helm Chart。
- 环境区分:为不同部署环境设置特定配置。
- 版本控制:轻松管理 Chart 版本,包括锁定和范围指定。
- 差异识别:快速查看部署差异。
- 模板语法:支持 Go Templates 语法。
- 部署钩子:在部署时执行自定义脚本。
安装 Helmfile
Helmfile 可以从 GitHub 仓库 安装。使用以下命令安装最新版本:
[root@master ~]# wget https://github.com/helmfile/helmfile/releases/download/v0.163.0/helmfile_0.163.0_linux_amd64.tar.gz
[root@master ~]# tar -zxf helmfile_0.163.0_linux_amd64.tar.gz -C /usr/local/bin
[root@master ~]# helmfile version
▓▓▓ helmfile
Version 0.163.0
Git Commit 1100e50
Build Date 22 Mar 24 10:03 CST (1 month ago)
Commit Date 22 Mar 24 09:37 CST (1 month ago)
Dirty Build no
Go version 1.22.1
Compiler gc
Platform linux/amd64
│ A new release is available: 0.163.0 → v0.163.1
│ https://github.com/helmfile/helmfile/releases/tag/v0.163.1
使用 Helmfile 安装 Helm Chart
创建 Helm Chart
使用 Helm 创建一个新的 chart:
[root@master ~]# helm create helloworld
Creating helloworld
创建 Helmfile
在相同的位置创建 helmfile.yaml
文件:
[root@master ~]# cat helmfile.yaml
---
releases:
- name: helloworld
chart: ./helloworld
installed: true
installed: true
标志确保 Helmfile 将部署该 chart。
安装 Helm Chart
通过 helmfile sync
命令安装 Helm chart:
[root@master ~]# helmfile sync
Building dependency release=helloworld, chart=helloworld
Upgrading release=helloworld, chart=helloworld
Release "helloworld" does not exist. Installing it now.
NAME: helloworld
LAST DEPLOYED: Tue Apr 23 17:21:09 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helloworld,app.kubernetes.io/instance=helloworld" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Listing releases matching ^helloworld$
helloworld default 1 2024-04-23 17:21:09.562166346 +0800 CST deployed helloworld-0.1.0 1.16.0
UPDATED RELEASES:
NAME CHART VERSION DURATION
helloworld ./helloworld 0.1.0 1s
验证安装
使用 Helm 命令查看已部署的 releases:
[root@master ~]# helm list -a
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
helloworld default 1 2024-04-23 17:21:09.562166346 +0800 CST deployed helloworld-0.1.0 1.16.0
使用 Helmfile 卸载 Helm Chart
要卸载 chart,更改 helmfile.yaml
中的 installed
为 false
并再次同步:
[root@master ~]# cat helmfile.yaml
---
releases:
- name: helloworld
chart: ./helloworld
installed: false # 改为false
[root@master ~]# helmfile sync
Listing releases matching ^helloworld$
helloworld default 1 2024-04-23 17:21:09.562166346 +0800 CST deployed helloworld-0.1.0 1.16.0
Deleting helloworld
release "helloworld" uninstalled
DELETED RELEASES:
NAME DURATION
helloworld 0s
使用 GitHub 通过 Helmfile 安装 Helm Chart
GitHub 仓库内容
[root@master ~]# tree helm-charts/
helm-charts/
├── helloworld
│ ├── Chart.yaml
│ ├── templates
│ │ ├── deployment.yaml
│ │ ├── _helpers.tpl
│ │ ├── hpa.yaml
│ │ ├── ingress.yaml
│ │ ├── NOTES.txt
│ │ ├── serviceaccount.yaml
│ │ ├── service.yaml
│ │ └── tests
│ │ └── test-connection.yaml
│ └── values.yaml
└── index.yaml # 通过helm repo index helm-charts生成
3 directories, 11 files
确保仓库是公开的,其中包含 helloworld
chart 和 index.yaml
文件。
Helmfile 配置
配置 Helmfile 以使用 GitHub 上的 Helm charts:
[root@master ~]# cat helmfile.yaml
---
repositories:
- name: helloworld
url: git+https://github.com/fengji/helm-charts@helloworld?ref=master
releases:
- name: helloworld
chart: helm-charts/helloworld
安装 Helm Chart
运行 helmfile sync
来安装 GitHub 上的 Helm charts。
[root@master ~]# helmfile sync
Adding repo helloworld git+https://github.com/fengji/helm-charts@helloworld?ref=master
"helloworld" has been added to your repositories
Building dependency release=helloworld, chart=helm-charts/helloworld
Upgrading release=helloworld, chart=helm-charts/helloworld
Release "helloworld" does not exist. Installing it now.
NAME: helloworld
LAST DEPLOYED: Thu Apr 25 10:13:11 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helloworld,app.kubernetes.io/instance=helloworld" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Listing releases matching ^helloworld$
helloworld default 1 2024-04-25 10:13:11.917794161 +0800 CST deployed helloworld-0.1.0 1.16.0
UPDATED RELEASES:
NAME CHART VERSION DURATION
helloworld helm-charts/helloworld 0.1.0 1s
部署多个 Helm Chart
将多个 charts 推送到单个 GitHub 仓库,并在 Helmfile 中配置多个 releases:
[root@master ~]# cat helmfile.yaml
---
repositories:
- name: helloworld
url: git+https://github.com/fengji/helm-charts@helloworld?ref=master
releases:
- name: helloworld1
chart: helm-charts/helloworld1
installed: true
- name: helloworld2
chart: helm-charts/helloworld2
installed: true
安装 Helm Chart
使用 helmfile sync
命令安装所有定义的 Helm charts。
[root@master ~]# helmfile sync
Adding repo helloworld git+https://github.com/fengji/helm-charts@helloworld?ref=master
"helloworld" has been added to your repositories
Building dependency release=helloworld1, chart=helm-charts/helloworld1
Building dependency release=helloworld2, chart=helm-charts/helloworld2
Upgrading release=helloworld1, chart=helm-charts/helloworld1
Upgrading release=helloworld2, chart=helm-charts/helloworld2
Release "helloworld2" does not exist. Installing it now.
NAME: helloworld2
LAST DEPLOYED: Thu Apr 25 10:30:07 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helloworld2,app.kubernetes.io/instance=helloworld2" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Listing releases matching ^helloworld2$
Release "helloworld1" does not exist. Installing it now.
NAME: helloworld1
LAST DEPLOYED: Thu Apr 25 10:30:07 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=helloworld1,app.kubernetes.io/instance=helloworld1" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Listing releases matching ^helloworld1$
helloworld1 default 1 2024-04-25 10:30:07.271544883 +0800 CST deployed helloworld1-0.1.0 1.16.0
helloworld2 default 1 2024-04-25 10:30:07.272519801 +0800 CST deployed helloworld2-0.1.0 1.16.0
UPDATED RELEASES:
NAME CHART VERSION DURATION
helloworld2 helm-charts/helloworld2 0.1.0 2s
helloworld1 helm-charts/helloworld1 0.1.0 2s
结语
Helmfile 作为一个声明式的 Helm charts 部署工具,极大地简化了在 Kubernetes 上管理多个应用的复杂性。它支持 CI/CD 集成,环境特定的配置,并且可以轻松同步不同环境的状态。