使用 Helm 的 13 个最佳实践

Helm是将应用程序部署到Kubernetes集群不可或缺的工具。但只有遵循最佳实践,您才能真正获得Helm的好处。这里有13个最佳实践,可帮助您使用Helm创建、操作和升级应用程序。


https://cloudnativehub.com/uploads/article/20211015/03801f55ad1cd55e6e18bfcc55148a26.png


将你的Helm提升到一个新的水平

Helm是Kubernetes的包管理器。由于其模板方法和可重用和生产就绪包(也称为Helm图表)的丰富生态系统,它减少了部署复杂应用程序的工作量。使用Helm,将打包的应用程序部署为一组版本化、预配置的Kubernetes资源。



假设您正在使用Kubernetes部署一个数据库——包括多个Deployment、containers、secrets,volumes和services。Helm允许您使用单个命令和一组值安装相同的数据库。其声明性和幂等性命令使Helm成为持续交付(CD)的理想工具。


Helm是一个CloudNativeComputingFoundation(CNCF)项目,创建于2015年,2020年4月毕业。随着Helm3的最新版本,它更加融入了Kubernetes生态系统。


本文介绍了创建Helm图表以管理在Kubernetes中运行的应用程序的13个最佳实践。


1、利用Helm生态系统

Helm使您可以获取丰富的社区专业知识——这也许是该工具的最大好处。它从世界各地的开发人员那里收集Charts图表,然后通过图表存储库共享。您可以检查ArtifactHub以获取可用的Helm图表存储库。


找到图表存储库后,您可以将其添加到本地设置中,如下所示:

$helmrepoaddbitnamihttps://charts.bitnami.com/bitnami

然后就可以搜索图表了,比如MySQL:

$helmsearchhubmysql
URLCHARTVERSIONAPPVERSIONDESCRIPTIONhttps://hub.helm.sh/charts/bitnami/mysql8.6.38.0.25CharttocreateaHighlyavailableMySQLcluster


2. 使用subcharts来管理你的依赖

由于部署到Kubernetes的应用程序由细粒度、相互依赖的部分组成,因此它们的Helm图表具有各种资源模板和依赖项。例如,假设您的后端依赖于一个数据库和一个消息队列。数据库和消息队列已经是独立的应用程序(例如PostgreSQL和RabbitMQ)。因此,建议为独立应用程序创建或使用单独的图表并将它们添加到父图表(parentcharts)。依赖的应用程序在此处被命名为子图(subchart)。


创建和配置子图表有三个基本要素:


1.图表结构

文件夹结构应按以下顺序排列:

backend-chart-Chart.yaml-charts-message-queue-Chart.yaml-templates-values.yaml-database-Chart.yaml-templates-values.yaml-values.yaml


2.chart.yaml

此外,父图表中的chart.yaml应列出所有依赖项和条件:

apiVersion:v2name:backend-chartdescription:AHelmchartforbackend...dependencies:-name:message-queuecondition:message-queue.enabled-name:databasecondition:database.enabled


3.values.yaml

最后,您可以使用以下values.yaml文件设置或覆盖父图表中子图表的值:

message-queue:enabled:trueimage:repository:acme/rabbitmqtag:latestdatabase:enabled:false


创建和使用子图在父应用程序和依赖应用程序之间建立了一个抽象层。这些单独的图表使在Kubernetes中部署、调试和更新应用程序及其单独的值和升级生命周期变得容易。您可以在像bitnami/wordpress这样的示例图表中浏览文件夹结构、依赖项和值文件。


3、使用标签轻松查找资源

标签对于Kubernetes的内部运营和Kubernetes运维人员的日常工作至关重要。Kubernetes中的几乎每个资源都为不同的目的提供标签,例如分组、资源分配、负载平衡或调度。

单个Helm命令将允许您安装多个资源。但了解这些资源的来源至关重要。标签使您能够快速找到由Helm版本创建的资源。


最常用的方法是在helpers.tpl中定义标签,如下所示:

{{/*Commonlabels*/}}
{{-define"="">common.labels"="">-}}app.kubernetes.io/instance:{{.Release.Name}}app.kubernetes.io/managed-by:{{.Release.Service}}{{-end-}}


然后,您需要在资源模板中使用带有标签的“include”函数:

apiVersion:apps/v1kind:Deploymentmetadata:name:my-queuelabels:{{include"="">common.labels"="">.|indent4}}...


现在您应该能够使用标签选择器列出所有资源。例如,您可以使用该kubectlgetpods-lapp.kubernetes.io/instance=[NameoftheHelmRelease]命令列出my-queue部署的所有pod。这一步对于定位和调试Helm管理的资源至关重要。


4、记录你的图表

文档对于确保可维护的Helm图表至关重要。在资源模板和README中添加注释可帮助团队开发和使用Helm图表。


您应该使用以下三个选项来记录您的图表:


  • 注释:模板和值文件是YAML文件。您可以添加注释并提供有关YAML文件中字段的有用信息。

  • README:图表的README是一个Markdown文件,解释了如何使用图表。您可以使用以下命令检查README文件的内容:helmshowreadme[NameoftheChart]

  • NOTES.txt:这是一个位于的特殊文件templates/NOTES.txt,提供有关版本部署的有用信息。NOTES.txt文件的内容也可以使用类似于资源模板的函数和值进行模板化:

Youhavedeployedthefollowingrelease:{{.Release.Name}}.Togetfurtherinformation,youcanrunthecommands:$helmstatus{{.Release.Name}}$helmgetall{{.Release.Name}}


在helminstall或helmupgrade命令结束时,Helm会打印出NOTES.txt的内容,如下所示:

RESOURCES:==>v1/SecretNAMETYPEDATAAGEmy-secretOpaque10s
==>v1/ConfigMapNAMEDATAAGEdb-configmap30s
NOTES:Youhavedeployedthefollowingrelease:precious-db.Togetfurtherinformation,youcanrunthecommands:$helmstatusprecious-db$helmgetallprecious-db

5、测试你的图表


Helmcharts由多个要部署到集群的资源组成。必须检查是否在集群中创建的所有资源都具有正确的值。例如,在部署数据库时,您应该检查数据库密码设置是否正确。


幸运的是,Helm提供了一个在集群中运行一些容器以验证应用程序的测试功能。例如,注解的资源模板"="">helm.sh/hook":test-success由Helm作为测试用例运行。="">


假设您正在使用MariaDB数据库部署WordPress。Bitnami维护的Helmchart有一个pod来验证数据库连接,定义如下:

...apiVersion:v1kind:Podmetadata:name:"="">{{.Release.Name}}-credentials-test"="">annotations:"="">helm.sh/hook"="">:test-success...env:-name:MARIADB\_HOSTvalue:{{include"="">wordpress.databaseHost"="">.|quote}}-name:MARIADB\_PORTvalue:"="">3306"="">-name:WORDPRESS\_DATABASE\_NAMEvalue:{{default"="">"="">.Values.mariadb.auth.database|quote}}-name:WORDPRESS\_DATABASE\_USERvalue:{{default"="">"="">.Values.mariadb.auth.username|quote}}-name:WORDPRESS\_DATABASE\_PASSWORDvalueFrom:secretKeyRef:name:{{include"="">wordpress.databaseSecretName"="">.}}key:mariadb-passwordcommand:-/bin/bash--ec-|mysql--host=$MARIADB\_HOST--port=$MARIADB\_PORT--user=$WORDPRESS\_DATABASE\_USER--password=$WORDPRESS\_DATABASE\_PASSWORDrestartPolicy:Never{{-end}}...



建议为您的图表编写测试并在安装后运行它们。例如,您可以使用helmtest命令运行测试。这些测试是用于验证和发现使用Helm安装的应用程序中的问题的宝贵资产。


6、确保Secrests安全

敏感数据(例如密钥或密码)作为secrets存储在Kubernetes中。尽管可以在Kubernetes端保护secrets,但它们大多作为Helm模板和值的一部分存储为文本文件。


在Helm,secrets插件提供secrets的管理和保护您的重要信息。它将secrets加密委托给MozillaSOPS,后者支持AWSKMS、GCP上的CloudKMS、AzureKeyVault和PGP。

假设您已将敏感数据收集在名为secrets.yaml的文件中,如下所示:


postgresql:postgresqlUsername:postgrespostgresqlPassword:WoZpCAlBsgpostgresqlDatabase:wp


您可以使用插件加密文件:

$helmsecretsencsecrets.yamlEncryptingsecrets.yamlEncryptedsecrets.yaml


现在,文件将被更新并且所有值都将被加密:

postgresql:postgresqlUsername:ENC\[AES256\_GCM,data:D14/CcA3WjY=,iv...==,type:str\]postgresqlPassword:ENC\[AES256\_GCM,data:Wd7VEKSoqV...,type:str\]postgresqlDatabase:ENC\[AES256\_GCM,data:8ur9pqDxUA==,iv:R...,type:str\]sops:...


上面secrets.yaml中的数据并不安全,helm-secrets解决了将敏感数据存储为Helmcharts的问题。



">">">

7. 使用模板函数使您的Helm图表可重用

Helm支持60多个可在模板中使用的函数。这些函数在Go模板语言和Sprig模板库中定义。模板文件中的函数显著简化了Helm操作。


我们以下面的模板文件为例:

apiVersion:v1kind:ConfigMapmetadata:name:{{.Release.Name}}-configmapdata:environment:{{.Values.environment|default"="">dev"="">|quote}}region:{{.Values.region|upper|quote}}


当没有提供环境值时,模板函数会默认。当您检查区域字段时,您会看到模板中没有定义默认值。但是,该字段具有另一个称为upper的函数,用于将提供的值转换为大写。


另一个重要且有用的功能是required.它使您能够根据模板渲染的需要设置一个值。例如,假设您需要使用以下模板为ConfigMap命名:

...metadata:name:{{required"="">Nameisrequired"="">.Values.configName}}...


如果该条目为空,则模板渲染将失败并显示错误Nameisrequired。创建Helm图表时,模板函数非常有用。它们可以改进模板、减少代码重复,并可用于在将应用程序部署到Kubernetes之前验证值。


8. 当 ConfigMaps 或 Secrets 改变时更新你的部署

将ConfigMaps或secrets安装到容器是很常见的。尽管部署和容器镜像会随着新版本而变化,但ConfigMap或secrets不会经常更改。以下注释可以在ConfigMap更改时滚动更新部署:

kind:Deploymentspec:template:metadata:annotations:checksum/config:{{include(print$.Template.BasePath"="">/configmap.yaml"="">).|sha256sum}}...


ConfigMap中的任何更改都将计算sha256sum新的部署版本并创建新版本。这确保部署中的容器将使用新的ConfigMap重新启动。


9. 使用资源策略选择退出资源删除

在典型的设置中,安装Helmchart后,Helm将在集群中创建多个资源。然后,您可以通过更改值以及添加或删除资源来升级它。一旦您不再需要该应用程序,您可以将其删除,这会从集群中移除所有资源。但是,即使在运行Helm卸载之后,某些资源也应保留在集群中。假设您已经使用PersistentVolumeClaim部署了一个数据库,并且即使您要删除数据库版本也希望存储卷。对于此类资源,您需要使用资源策略注释,如下所示:

kind:Secretmetadata:annotations:"="">helm.sh/resource-policy"="">:keep...


Helm命令(例如卸载、升级或回滚)会导致删除上述Secrets。但是通过使用如图所示的资源策略,Helm将跳过Secrets的删除并允许它成为孤立的。因此,应该非常小心地使用注释,并且仅用于在HelmReleases被删除后所需的资源。


10. 调试 Helm Chart 的有用命令

Helm模板文件带有许多不同的功能和用于创建Kubernetes资源的多个值来源。了解部署到集群的内容是用户的基本职责。因此,您需要学习如何调试模板和验证Helm图表。有四个基本命令可用于调试:


  • helmlint:linter工具进行一系列测试以确保您的图表正确形成。

  • helminstall--dry-run--debug:此函数呈现模板并显示生成的资源清单。您还可以在部署之前检查所有资源,并确保设置了值并且模板功能按预期工作。


  • helmgetmanifest:此命令检索安装到集群的资源的清单。如果发布未按预期运行,这应该是您用来找出集群中正在运行的内容的第一个命令。


  • helmgetvalues:此命令用于检索安装到集群的版本值。如果您对计算值或默认值有任何疑问,这绝对应该在您的工具带中。


11.使用查找功能避免Secrets再生

Helm函数用于生成随机数据,例如密码、密钥和证书。随机生成会在每次部署和升级时创建新的任意值并更新集群中的资源。例如,它可以在每次版本升级时替换集群中的数据库密码。这会导致客户端在更改密码后无法连接到数据库。


为了解决这个问题,建议随机生成值并覆盖集群中已有的值。例如:

{{-$rootPasswordValue:=(randAlpha16)|b64enc|quote}}{{-$secret:=(lookup"="">v1"="">"="">Secret"="">.Release.Namespace"="">db-keys"="">)}}{{-if$secret}}{{-$rootPasswordValue=index$secret.data"="">root-password"="">}}{{-end-}}apiVersion:v1kind:Secretmetadata:name:db-keysnamespace:{{.Release.Namespace}}type:Opaquedata:root-password:{{$rootPasswordValue}}


上面的模板首先创建一个16个字符的randAlpha值,然后检查集群中的Secrets及其对应的字段。如果找到,它会覆盖并重用rootPasswordValue作为root-password。


12. 迁移到 Helm 3 以获得更简单、更安全的 Kubernetes 应用程序

最新的Helm版本Helm3提供了许多新功能,使其成为更轻巧、更精简的工具。推荐使用Helmv3,因为它增强了安全性和简单性。这包括:


删除Tiller:Tiller是Helm服务器端组件,但由于在早期版本中对集群进行更改所需的详尽权限已从v3中删除。这也造成了安全风险,因为任何获得Tiller访问权限的人都会对您的集群拥有过多的权限。


改进的图表升级策略:Helmv2依赖于双向策略合并补丁。它将新版本与ConfigMap存储中的版本进行比较并应用更改。相反,Helmv3比较旧清单、集群中的状态和新版本。因此,在升级Helm版本时,您的手动更改不会丢失。这简化了升级过程并增强了应用程序的可靠性。

有一个helm-2to3插件,您可以使用以下命令安装升级它:


$helm3plugininstallhttps://github.com/helm/helm-2to3


这是一个小而有用的插件,带有清理、转换和移动命令,可帮助您迁移和清理v2配置并为v3创建版本。


13. 保持持续交付管道的幂等性

Kubernetes资源是声明性的,因为它们的规范和状态存储在集群中。同样,Helm需要创建声明性模板和发布。因此,您需要在使用Helm时将持续交付和发布管理设计为幂等的。幂等操作是您可以多次应用而不改变第一次运行后的结果的操作。


有两个基本规则需要遵循:

  1. 始终使用该helmupgrade--install命令。如果图表尚未安装,它会安装图表。如果它们已经安装,它会升级它们。


  2. 使用--atomic标志在helm升级期间操作失败时回滚更改。这确保Helm版本不会停留在失败状态。


总结

Helm是将应用程序部署到Kubernetes集群不可或缺的工具。但只有遵循最佳实践,您才能真正获得Helm的好处。


本文中介绍的最佳实践将帮助您的团队创建、操作和升级生产级分布式应用程序。从开发方面来看,您的Helm图表将更易于维护和保护。在操作方面,您将享受自动更新的部署、从删除中节省资源,并学习如何测试和调试。


Helm的官方主题指南是检查Helm命令和理解其设计理念的另一个很好的资源。有了这些资源以及本文章中概述的最佳实践和示例,您一定会武装并准备好创建和管理在Kubernetes上运行的生产级Helm应用程序。


0 个评论

要回复文章请先登录注册

咨询在线客服

1156141327

服务热线

13720071711

咨询时间 9:00 - 18:00

扫一扫联系我们

扫一扫联系我们