Learn Helm by practice in this tutorial. Understand what Helm is and how to package an app with Helm charts. Manage upgrades and rollbacks in Kubernetes
在本教程中通过实践学习 Helm。了解什么是 Helm 以及如何使用 Helm Charts打包应用。在 Kubernetes 中管理升级和回滚。
Today, Kubernetes becomes a must for DevOps practitioners for orchestrating containers. Once you have a Docker image of your application, you have to write YAML manifests to define Kubernetes workloads. Next, you deploy them with the kubectl command.
如今,Kubernetes 成为 DevOps 从业者编排容器的必备条件。获得应用程序的 Docker 映像后,必须编写 YAML 清单来定义 Kubernetes 工作负载。接下来,使用 kubectl 命令部署它们。
This deployment way is when you've only one application. When you start to have many applications and multiple environments it becomes overwhelmed. Often you define the same YAML files 90% of the time.
这种部署方式是指只有一个应用程序的情况。当您开始拥有许多应用程序和多个环境时,它会变得不堪重负。通常,在 90% 的时间内定义相同的 YAML 文件。
Here, we are going to focus on how to manage applications smartly with Helm.
在这里,我们将重点介绍如何使用 Helm 智能地管理应用程序。
Helm is a package manager for Kubernetes. Helm is an open-source project originally created by DeisLabs and donated to the Cloud Native Foundation (CNCF). The CNCF now maintains and has graduated the project. This means that it is mature and not just a fad.
Helm 是 Kubernetes 的包管理器。Helm是一个开源项目,最初由DeisLabs创建并捐赠给云原生基金会(CNCF)。CNCF现在维护并已完成该项目。这意味着它是成熟的,而不仅仅是一种时尚。
Package management is not a new concept in the software industry. On Linux distros, you manage software installation and removal with package managers such as YUM/RPM or APT. On Windows, you can use Chocolatey or Homebrew on Mac.
包管理在软件行业并不是一个新概念。在 Linux 发行版上,您可以使用软件包管理器(如 YUM/RPM 或 APT)管理软件安装和删除。在 Windows 上,您可以使用 Chocolatey 或在 Mac 上使用Homebrew。
Helm lets you package and deploy complete applications in Kubernetes. A package is called a "Chart". Helm uses a templating system based on Go template to render Kubernetes manifests from charts. A chart is a consistent structure separating templates and values.
Helm 允许您在 Kubernetes 中打包和部署完整的应用程序。包称为“图表”。Helm 使用基于 Go 模板的模板系统从图表中呈现 Kubernetes 清单。图表是分隔模板和值的一致结构。
As a package, a chart can also manage dependencies with other charts. For example, if your application needs a MySQL database to work you can include the chart as a dependency. When Helm runs at the top level of the chart directory it installs whole dependencies. You have just a single command to render and release your application to Kubernetes.
作为一个包,Chart还可以管理与其他charts的依赖关系。例如,如果您的应用程序需要 MySQL 数据库才能工作,则可以将Chart作为依赖项包含在内。当 Helm 在Chart目录的顶层运行时,它会安装整个依赖项。你只有一个命令来渲染你的应用程序并将其发布到 Kubernetes。
Helm charts use versions to track changes in your manifests – thus you can install a specific chart version for specific infrastructure configurations. Helm keeps a release history of all deployed charts in a dedicated workspace. This makes easier application updates and rollbacks if something wrong happens.
Helm Chart使用版本来跟踪清单中的更改,因此您可以为特定基础结构配置安装特定的图表版本。Helm 在专用工作区中保存所有已部署图表的发布历史记录。这样可以在发生错误时更轻松地进行应用程序更新和回滚。
Helm allows you to compress charts. The result of that is an artifact comparable to a Docker image. Then, you can send it to a distant repository for reusability and sharing.
Helm允许您压缩图表。其结果是与 Docker 映像相当的工件。然后,您可以将其发送到远程存储库以进行可重用和共享。
Helm provides you the ability to install applications with a single command. A chart can contain other charts as dependencies. You can consequently deploy an entire stack with Helm. You can use Helm like docker-compose but for Kubernetes.
Helm 使您能够使用单个命令安装应用程序。图表可以包含其他图表作为依赖项。因此,您可以使用 Helm 部署整个堆栈。你可以像docker-compose一样使用Helm,但对于Kubernetes。
A chart includes templates for various Kubernetes resources to form a complete application. This reduces the microservices complexity and simplifies their management in Kubernetes.
图表包含各种 Kubernetes 资源的模板,以形成一个完整的应用程序。这降低了微服务的复杂性,并简化了它们在 Kubernetes 中的管理。
Charts can be compressed and sent to a distant repository. This creates an application artifact for Kubernetes. You can also fetch and deploy existing Helm charts from repositories. This is a strong point for reusability and sharing.
图表可以压缩并发送到远程存储库。这将为 Kubernetes 创建一个应用程序工件。您还可以从存储库中获取和部署现有的 Helm 图表。这是可重用性和共享的强项。
Helm maintains a history of deployed release versions in the Helm workspace. When something goes wrong, rolling back to a previous version is simply — canary release is facilitated with Helm for zero-downtime deployments.
Helm 在 Helm 工作区中维护已部署发布版本的历史记录。当出现问题时,只需回滚到以前的版本,即可使用 Helm 促进金丝雀发布,以实现零停机部署。
Helm makes the deployment highly configurable. Applications can be customized on the fly during the deployment. By changing parameters, you can use the same chart for multiple environments such as dev, staging, and production.
Helm 使部署具有高度可配置性。可以在部署期间动态自定义应用程序。通过更改参数,可以将同一图表用于多个环境,例如开发、暂存和生产。
Streamline CI/CD pipelines – Forward GitOps best practices.
简化 CI/CD 管道 – 转发 GitOps 最佳做法。
Basic Kubernetes practice is to write YAML manifests manually. We'll create minimum YAML files to deploy NGINX in Kubernetes.
Kubernetes 的基本做法是手动编写 YAML 清单。我们将创建最少的 YAML 文件以在 Kubernetes 中部署 NGINX。
Here is the Deployment that will create Pods: 以下是将创建 Pod 的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21.6
ports:
- containerPort: 80
The Service exposes NGINX to the outside. The link with pod is done via the selector:
该服务将NGINX暴露给外部。与 pod 的链接是通过选择器完成的:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 8080
Now we have to create the previous resources with the kubectl command:
现在我们必须使用 kubectl 命令创建以前的资源:
$ kubectl create -f deployment.yaml
$ kubectl create -f service.yaml
We check all resources are up and running:
我们检查所有资源是否已启动并正在运行:
$ kubectl get deployment -l app=nginx
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 8m29s
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-65b89996ff-dcfs9 1/1 Running 0 2m26s
$ kubectl get svc -l app=nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.106.79.171 80/TCP 4m58s
Specific values in YAML manifests are hardcoded and not reusable.
Redundant information to specify such as labels and selectors leads to potential errors.
Kubectl does not handle potential errors after execution. You've to deploy each file one after the other.
There's no change traceability.
YAML 清单中的特定值是硬编码的,不可重用。
要指定的冗余信息(如标签和选择器)会导致潜在错误。
Kubectl 在执行后不处理潜在错误。您必须一个接一个地部署每个文件。
没有更改可追溯性。
Helm can create the chart structure in a single command line:
Helm 可以在单个命令行中创建图表结构:
$ helm create nginx
Chart.yaml: A YAML file containing information about the chart.
charts: A directory containing any charts upon which this chart depends on.
templates: this is where Helm finds the YAML definitions for your Services, Deployments, and other Kubernetes objects. You can add or replace the generated YAML files for your own.
templates/NOTES.txt: This is a templated, plaintext file that gets printed out after the chart is successfully deployed. This is a useful place to briefly describe the next steps for using the chart.
templates/_helpers.tpl: That file is the default location for template partials. Files whose name begins with an underscore are assumed to not have a manifest inside. These files are not rendered to Kubernetes object definitions but are available everywhere within other chart templates for use.
templates/tests: tests that validate that your chart works as expected when it is installed
values.yaml: The default configuration values for this chart
Chart.yaml:包含图表相关信息的 YAML 文件。
charts:包含此图表所依赖的任何图表的目录。
templates:这是 Helm 查找服务、部署和其他 Kubernetes 对象的 YAML 定义的地方。您可以为自己添加或替换生成的 YAML 文件。
templates/NOTES.txt:这是一个模板化的纯文本文件,在成功部署图表后打印出来。这是简要描述使用图表的后续步骤的有用位置。
templates/_helpers.tpl: 该文件是模板部件的默认位置。假定名称以下划线开头的文件内部_没有_清单。这些文件不会呈现到 Kubernetes 对象定义中,而是在其他图表模板中的任何地方都可以使用。
templates/tests:验证图表在安装时是否按预期工作的测试
values.yaml:此图表的默认配置值
The is loaded automatically by default when deploying the chart. Here we set the image tag to : values.yaml 1.21.5
默认情况下,在部署图表时自动加载values.yaml 。在这里,我们将图像标签设置为:1.21.5
# Default values for nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.21.5"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
You can specify a specific file to customize the deployment for environment-specific settingsvalues.yaml
您可以指定特定文件以自定义特定于环境的设置的values.yaml, 例如:STG.yaml、PRD.yaml
Good advice before deploying a Helm chart is to run the linter if you made an update:
在部署 Helm 图表之前,很好的建议是在进行更新时运行 linter:
$ helm lint nginx
==> Linting nginx
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
Run Helm to install the chart in dry-run and debug mode to ensure all is ok:
运行 Helm 以在试运行和调试模式下安装图表,以确保一切正常:
$ helm install --debug --dry-run nginx nginx
Using helm linter and dry-run install with debug mode will save you precious time in your development.
使用Helm linter和带有调试模式的dry-run将节省您宝贵的开发时间。
To install the chart, remove the flag:--dry-run
要安装图表,请删除标志:--dry-run
$ helm install nginx nginx
NAME: nginx
LAST DEPLOYED: Mon Mar 14 12:01:46 2022
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=nginx,app.kubernetes.io/instance=nginx" -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
You can see the templated content of the explaining how to connect to the application. NOTES.txt Now, you can retrieve the release in the Helm workspace:
您可以看到说明如何连接到应用程序的模板化内容。NOTES.txt
现在,可以在 Helm 工作区中检索发布:
$ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
nginx default 1 2022-03-14 12:01:46.926038 +0100 CET deployed nginx-0.1.0 1.0.0
Imagine you want to upgrade the container image to for testing purposes. 1.21.6 Instead of creating a new , we'll change the setting from the command line. values.yaml
假设你想要将容器映像升级到以进行测试。1.21.6
我们将从命令行更改设置,而不是创建一个新的values.yaml。
$ helm upgrade nginx nginx --set image.tag=1.21.6
Release "nginx" has been upgraded. Happy Helming!
NAME: nginx
LAST DEPLOYED: Mon Mar 14 12:04:40 2022
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=nginx,app.kubernetes.io/instance=nginx" -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
The pod is using the new container image as well: 容器也正在使用新的容器映像:
$ kubectl get pod -l app.kubernetes.io/name=nginx -o jsonpath='{.items[0].spec.containers[0].image}'
nginx:1.21.6
The upgrade is visible in the chart history: 升级Chart在历史记录中可见:
$ helm history nginx
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Mon Mar 14 12:07:33 2022 superseded nginx-0.1.0 1.0.0 Install complete
2 Mon Mar 14 12:08:25 2022 deployed nginx-0.1.0 1.0.0 Upgrade complete
Change is inspectable with 更改可通过以下方式进行检查:helm diff
$ helm diff revision nginx 1 2
default, nginx, Deployment (apps) has changed:
# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
helm.sh/chart: nginx-0.1.0
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/version: "1.0.0"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
template:
metadata:
labels:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
spec:
serviceAccountName: nginx
securityContext:
{}
containers:
- name: nginx
securityContext:
{}
- image: "nginx:1.21.5"
+ image: "nginx:1.21.6"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}
The upgrade was not conclusive and you want to go back. As Helm keeps all the changes, rollback is very straightforward:
升级没有定论,您想返回。由于 Helm 保留了所有更改,因此回滚非常简单:
$ helm rollback nginx 1
Rollback was a success! Happy Helming!
The pod is now back to container image:1.21.5 Pod 现在返回到容器映像:1.21.5
$ kubectl get pod -l app.kubernetes.io/name=nginx -o jsonpath='{.items[0].spec.containers[0].image}'
nginx:1.21.5
Uninstalling a Helm chart is trivial as the installation: 卸载 Helm 图表与安装一样简单:
$ helm uninstall nginx
A lot of famous projects provide Helm charts to make the integration more user-friendly. They provide the charts through a repository. You have just to add it on your side:
许多著名的项目都提供了 Helm 图表,以使集成更加用户友好。他们通过存储库提供图表。您只需将其添加到您这边:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
Once added, update your local cache to synchronize info with remote repositories:
添加后,更新本地缓存以将信息与远程存储库同步:
$ helm repo update
You can now install the chart on your Kubernetes cluster:
您现在可以在 Kubernetes 集群上安装图表:
$ helm install nginx bitnami/nginx
Charts are deployed with default values. You can inspire and specify a custom to match your needs!values.yaml
图表使用默认值进行部署。您可以激发并指定自定义以满足您的需求!values.yaml
$ helm install my-release bitnami/nginx -f values.yaml
This article is translated from the original text for the purpose of learning:
https://getbetterdevops.io/helm-quickstart-tutorial/
Previous articles 往期推荐
用于应用开发的 CI/CD 与用于基础结构即代码的 CI/CD
Google SRE和开发者如何协作
如何将Secrets扫描加入到GitLab Pipeline
基础架构即代码 vs 配置管理 vs 基础架构预配
安全软件供应链6个交付管道安全最佳实践
Confluence 使用小技巧:开始、暂停和恢复工作的更好方式!
使用Jenkins Dashboard插件可视化部署
Jenkins Pipeline as code实践
If this article is helpful to you, please forward it, like it and share it. Your attention is the driving force for my continuous efforts. Thanks for attention.
如果这篇文章对您有帮助,欢迎转发点赞分享。您的关注是我持续努力的动力。感谢关注。Hava a good day!