Helm Charts 保姆级入门教程
通过简单易懂的 Helm Chart 教程了解如何创建 Helm 图表。本指南涵盖结构、组件和最佳实践。因此,如果您想学习 helm chart 基础知识并亲身体验 helm chart,您会喜欢本指南。先决条件若要开始使用 helm 图表,需要具备以下条件。什么是 Helm Chart?为了便于解释,我选择一个非常基本的示例,即在 Kubernetes 上使用 Nginx 进行网站前端部署假设您
通过简单易懂的 Helm Chart 教程了解如何创建 Helm 图表。本指南涵盖结构、组件和最佳实践。
因此,如果您想学习 helm chart 基础知识并亲身体验 helm chart,您会喜欢本指南。
先决条件
若要开始使用 helm 图表,需要具备以下条件。
- 正常工作的 Kubernetes 集群
- 在 workstation 安装 Helm
- 用于连接到集群的有效 kubeconfig
- Kubernetes 和 YAML 相关知识。
什么是 Helm Chart?
为了便于解释,我选择一个非常基本的示例,即在 Kubernetes 上使用 Nginx 进行网站前端部署
假设您的项目中有四个不同的环境。 开发、QA、预生产和生产。每个环境都有不同的 Nginx 部署参数。例如
- 在 Dev 和 QA 中,您可能只需要一个副本。
- 在预生产和生产中,您将拥有更多具有 Pod 自动缩放的副本。
- 每个环境中的入口路由规则都不同。
- 每个环境的配置和机密都不同。
由于每个环境的配置和部署参数发生了变化,您需要为每个环境维护不同的 Nginx 部署文件。或者,您将有一个部署文件,并且需要编写自定义 shell 或 python 脚本来替换基于环境的值。但是,它不是一种可扩展的方法。
Helm 图表是 Kubernetes YAML 清单模板和特定于 helm 的文件的组合。你可以称它为 helm 包。由于 Kubernetes YAML 清单可以模板化,因此您不必维护不同环境的多个 helm 图表。Helm 使用 go 模板引擎来实现模板功能。
您只需要有一个 helm 图表,只需更改一个值文件即可修改每个环境的部署参数。Helm 将负责将这些值应用于模板。我们将在下一节中实际了解有关它的更多信息。
在较高层次上,Helm Chart 降低了复杂性,而 kubernetes 仅使用一个模板就体现了每个环境的冗余。(dev, uat, cug, prod)
Helm 图表结构
为了理解 Helm 图表,我们以 Nginx 部署为例。若要在 Kubernetes 上部署 Nginx,通常需要以下 YAML 文件。
nginx-deployment
├── configmap.yaml
├── deployment.yaml
├── ingress.yaml
└── service.yaml
现在,如果我们为上述 Nginx 部署创建一个 Helm Chart,它将具有以下目录结构。
nginx-chart/
|-- Chart.yaml
|-- charts
|-- templates
| |-- NOTES.txt
| |-- _helpers.tpl
| |-- deployment.yaml
| |-- configmap.yaml
| |-- ingress.yaml
| |-- service.yaml
| `-- tests
| `-- test-connection.yaml
`-- values.yaml
如您所见,部署 YAML 文件是模板目录的一部分(以粗体突出显示),并且有特定于 helm 的文件和文件夹。让我们看一下 helm chart 中的每个文件和目录,并了解它们的重要性。
- .helmignore:它用于定义我们不想包含在 helm 图表中的所有文件。它的工作方式与
.gitignore
文件类似。 - Chart.yaml:它包含有关 helm chart 的信息,如版本、名称、描述等。
- values.yaml:在此文件中,我们定义 YAML 模板的值。例如,映像名称、副本计数、HPA 值等。正如我们之前所解释的,每个环境中只有文件会更改。此外,您可以动态覆盖这些值,也可以在安装 chart 时使用命令覆盖这些值。
values.yaml
--values
--set
- charts:如果我们的主图表对其他图表有一定的依赖性,我们可以在此目录中添加另一个图表的结构。默认情况下,此目录为空。
- templates: 此目录包含构成应用程序的所有 Kubernetes 清单文件。可以将这些清单文件模板化,以访问 values.yaml 文件中的值。Helm 为 Kubernetes 对象创建了一些默认模板,如 deployment.yaml、service.yaml 等,我们可以直接使用、修改或覆盖我们的文件。
- templates/NOTES.txt:这是一个纯文本文件,在成功部署图表后打印出来。
- templates/_helpers.tpl:该文件包含多个方法和子模板。这些文件不会呈现给 Kubernetes 对象定义,但在其他图表模板中的任何地方都可以使用。
- emplates/tests/:我们可以在图表中定义测试,以验证您的图表在安装时是否按预期工作。
Helm Chart 教程 GitHub 存储库
本 Helm Chart 教程中使用的示例 helm chart 和清单托管在 Helm Chart Github 存储库中。您可以克隆它并使用它来遵循指南。
git clone https://github.com/techiescamp/helm-tutorial.git
从头开始创建 Helm 图表
为了亲身体验 helm chart 的创建,让我们从头开始创建一个 Nginx helm chart。
执行以下命令以创建图表样板。它创建一个具有默认文件和文件夹名称的图表。nginx-chart
helm create nginx-chart
如果检查创建的图表,它将包含以下文件和目录。
nginx-chart
│ ├── Chart.yaml
│ ├── charts
│ ├── templates
│ │ ├── NOTES.txt
│ │ ├── _helpers.tpl
│ │ ├── deployment.yaml
│ │ ├── hpa.yaml
│ │ ├── ingress.yaml
│ │ ├── service.yaml
│ │ ├── serviceaccount.yaml
│ │ └── tests
│ │ └── test-connection.yaml
│ └── values.yaml
cd 进入生成的图表目录。
cd nginx-chart
我们将根据部署要求逐个编辑文件。
Chart.yaml
如上所述,我们将图表的详细信息存档。将 的默认内容替换为以下内容。Chart.yaml
chart.yaml
apiVersion: v2
name: nginx-chart
description: My First Helm Chart
type: application
version: 0.1.0
appVersion: "1.0.0"
maintainers:
- email: contact@devopscube.com
name: devopscube
- apiVersion:这表示图表 API 版本。v2 用于 Helm 3,v1 用于以前的版本。
- name: 表示图表的名称。
- description: 表示 helm 图表的描述。
- Type:图表类型可以是“应用程序”或“库”。应用程序图表是您在 Kubernetes 上部署的内容。库图表是可重复使用的图表,可与其他图表一起使用。编程中类似的库概念。
- version:图表版本。
- appVersion:这表示我们应用程序(Nginx)的版本号。
- maintainers:有关图表所有者的信息。
每次对应用程序进行更改时,version
appVersion
应该递增。还有一些其他字段,如dependencies,icons 等。
templates
Helm 创建的目录中有多个文件。在我们的例子中,我们将进行简单的 Kubernetes Nginx 部署。templates
从模板目录中删除所有默认文件。
rm -rf templates/*
我们将添加我们的 Nginx YAML 文件并将它们更改为模板,以便更好地理解。
创建一个文件并复制以下内容。deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "nginx:1.16.0"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
上面的 YAML 文件,则值是静态的。helm chart 的想法是将 YAML 文件模板化,以便我们可以通过动态地为它们分配值来在多个环境中重用它们。
要对值进行模板化,只需在大括号内添加 object 参数,如下所示。它被称为模板指令,语法特定于 Go 模板
{{ .Object.Parameter }}
首先,让我们了解什么是对象。以下是我们将在此示例中使用的三个对象。
- 发布:每个 helm 图表都将使用发布名称进行部署。如果要使用发布名称或访问模板中与发布相关的动态值,可以使用发布对象。
- 图表:如果要使用 chart.yaml 中提到的任何值,可以使用图表对象。
- 值:values.yaml 文件中的所有参数都可以使用 Values 对象进行访问。
要了解有关支持的对象的更多信息,请查看 Helm 内置对象文档。
下图显示了如何在模板中替换内置对象。
首先,您需要弄清楚哪些值可以更改或要模板化哪些值。我正在选择名称、副本、容器名称、图像和 imagePullPolicy,我在 YAML 文件中以粗体突出显示了它们。
- name: :我们每次都需要更改部署名称,因为 Helm 不允许我们安装具有相同名称的版本。因此,我们将使用发布名称模板化部署名称,并随之插值 -nginx。现在,如果我们使用名称 frontend 创建发布,则部署名称将为 frontend-nginx。这样,我们将有保证的唯一名称。
name: {{ .Release.Name }}-nginx
- container name: :对于容器名称,我们将使用 Chart 对象,并使用 chart.yaml 中的图表名称作为容器名称。
{{ .Chart.Name }}
- Replicas:我们将从 values.yaml 文件中访问副本值。
{{ .Values.replicaCount }}
- image: 在这里,我们在一行中使用多个模板指令,并从 Values 文件中访问映像键下的存储库和标记信息。
"{{ .Values.image.repository }}:{{ .Values.image.tag }}"
同样,您可以在 YAML 文件中模板化所需的值。
这是应用模板后的最终 deployment.yaml
文件。模板化部分以粗体突出显示。将部署文件内容替换为以下内容。
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
labels:
app: nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
创建文件并复制以下内容。service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
spec:
selector:
app.kubernetes.io/instance: {{ .Release.Name }}
type: {{ .Values.service.type }}
ports:
- protocol: {{ .Values.service.protocol | default "TCP" }}
port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
在协议模板指令中,您可以看到一个管道。它用于将协议的默认值定义为 TCP。因此,这意味着我们不会在 values.yaml
文件中定义协议值,或者如果它为空,它将采用 TCP 作为协议的值。( | )
创建一个configmap.yaml
,并在其中添加以下内容。在这里,我们将默认的 Nginx index.html 页面替换为自定义 HTML 页面。此外,我们还添加了一个模板指令来替换 HTML 中的环境名称。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-index-html-configmap
namespace: default
data:
index.html: |
<html>
<h1>Welcome</h1>
</br>
<h1>Hi! I got deployed in {{ .Values.env.name }} Environment using Helm Chart </h1>
</html
values.yaml
该文件包含我们在模板中使用的模板指令中需要替换的所有值。例如,template 包含一个模板指令,用于从 values.yaml
文件中获取映像存储库、标记和 pullPolicy。如果检查以下 values.yaml
文件,则在映像键下嵌套了 repository、tag 和 pullPolicy 键值对。这就是我们使用 Values.image.repository
的原因values.yaml
deployment.yaml
现在,将默认值 values.yaml
内容替换为以下内容。
replicaCount: 2
image:
repository: nginx
tag: "1.16.0"
pullPolicy: IfNotPresent
service:
name: nginx-service
type: ClusterIP
port: 80
targetPort: 9000
env:
name: dev
现在我们已经准备好了 Nginx helm chart,最终的 helm chart 结构如下所示。
nginx-chart
├── Chart.yaml
├── charts
├── templates
│ ├── configmap.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
验证 Helm Chart
现在,为了确保我们的图表有效并且所有缩进都很好,我们可以运行以下命令。确保您位于图表目录中。
helm lint .
如果您从 nginx-chart 目录外部执行它,请提供 nginx-chart
的完整路径
helm lint /path/to/nginx-chart
如果没有错误或问题,它将显示此结果
==> Linting ./nginx
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
若要验证模板中的值是否被替换,可以使用以下命令呈现具有值的模板化 YAML 文件。它将生成并显示所有带有替换值的清单文件。
helm template .
我们也可以使用命令来检查。这将假装将图表安装到集群中,如果存在问题,它将显示错误。--dry-run
helm install --dry-run my-release nginx-chart
如果一切正常,您将看到将部署到群集中的清单输出。
部署 Helm Chart
部署图表时,Helm 将从文件中读取图表和配置值,并生成清单文件。然后它会将这些文件发送到 Kubernetes API 服务器,Kubernetes 将在集群中创建请求的资源。values.yaml
现在我们准备安装图表了。
执行以下命令,其中 is release name 和 is the chart name。它将 nginx-chart
安装在默认命名空间中
helm install frontend nginx-chart
您将看到如下所示的输出。
NAME: frontend
LAST DEPLOYED: Tue Dec 13 10:15:56 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
现在,您可以使用以下命令检查版本列表:
helm list
执行kubectl命令,查看部署、服务和Pod。
kubectl get deployment
kubectl get services
kubectl get configmap
kubectl get pods
我们可以看到部署 frontend-nginx、nginx-service
和 pod 已启动并运行,如下所示。
我们讨论了如何使用不同的 values.yaml
文件将单个 helm 图表用于多个环境。若要使用外部文件安装 helm 图表,可以将以下命令与值文件的标志和路径一起使用。values.yaml
--values
helm install frontend nginx-chart --values env/prod-values.yaml
将 Helm 作为 CI/CD 管道的一部分时,可以编写自定义逻辑,以根据环境传递所需的值文件。
Helm 升级和回滚
现在假设您要修改图表并安装更新版本,我们可以使用以下命令:
helm upgrade frontend nginx-chart
例如,我们将副本从 2 更改为 1。您可以看到修订号为 2,并且只有 1 个 pod 在运行。
现在,如果我们想回滚刚刚完成的更改并再次部署上一个更改,我们可以使用 rollback 命令来执行此操作。
helm rollback frontend
上面的命令会将 helm 版本回滚到上一个版本。
回滚后,我们可以看到 2 个 pod 再次运行。请注意,Helm 将回滚作为新修订版,这就是我们将修订版作为 3 的原因。
如果我们想回滚到特定版本,我们可以像这样输入修订号。
helm rollback <release-name> <revision-number>
例如
helm rollback frontend 2
卸载 Helm 版本
要卸载 helm 版本,请使用 uninstall 命令。它将删除与图表的上一个版本关联的所有资源。
helm uninstall frontend
我们可以将图表打包并部署到 Github、S3 或任何其他平台。
helm package frontend
调试 Helm Chart
我们可以使用以下命令来调试 helm chart 和模板。
helm lint:
此命令采用图表的路径,并运行一系列测试以验证图表的格式是否正确。helm get values:
此命令将输出安装到群集的发布值。helm install --dry-run:
使用此函数,我们可以检查所有资源清单并确保所有模板都正常工作。helm get manifest:
此命令将输出群集中运行的清单。helm diff:
它将输出两个修订版本之间的差异。
helm diff revision nginx-chart 1 2
Helm Chart 可能的错误
如果尝试安装现有的 Helm 包,将出现以下错误。
Error: INSTALLATION FAILED: cannot re-use a name that is still in use
要更新或升级版本,您需要运行 upgrade 命令。
如果您尝试从其他位置安装图表,而没有给出图表的绝对路径,则会出现以下错误。
Error: non-absolute URLs should be in form of repo_name/path_to_chart
要解决此问题,您应该从拥有图表的目录执行 helm 命令,或者提供图表目录的绝对路径或相对路径。
Helm Charts 最佳实践
以下是开发 helm 图表时要遵循的一些最佳实践。
- 通过添加注释和 README 文件来记录图表,因为文档对于确保 Helm 图表的可维护性至关重要。
- 我们应该在对象的 Kind 之后命名 Kubernetes 清单文件,即 deployment、service、secret、ingress 等。
- 仅将图表名称放在小写字母中,如果它包含多个单词,则用连字符 (-) 分隔
- 在 values.yaml 文件中,字段名称应为小写。
- 始终将字符串值括在引号之间。
- 使用 Helm 版本 3 进行更简单、更安全的发布。有关更多详细信息,请查看此文档
结论
总而言之,
- 我们详细讨论了 Helm Chart 及其结构。
- 我们从头开始创建了一个 helm 图表并部署了它。
- 还学习了如何升级、回滚和卸载它。
Helm 是一个非常有用的 Kubernetes 包管理器。当您有不同的环境具有自定义部署要求时,helm 提供了一种根据我们的需求模板化 kubernetes 清单的好方法。
特定于 Helm 的功能,如图表依赖和图表可重用性,使其成为优秀的 kubernetes 工具之一。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)