什么是Helm? Kubernetes 初学者快速入门教程

什么是Helm? Kubernetes 初学者快速入门教程

<article style="max-width: 100%;">

在本教程中通过实践学习 Helm。了解 Helm 是什么以及如何使用 Helm 图表打包应用程序。管理 Kubernetes 中的升级和回滚

如今,Kubernetes 已成为 DevOps 从业者编排容器的必备工具。有了应用程序的 Docker 映像后,您必须编写 YAML 清单来定义 Kubernetes 工作负载。接下来,使用kubectl命令部署它们。

这种部署方式适用于只有一个应用程序的情况。当您开始拥有许多应用程序和多个环境时,它就会变得不堪重负。通常您会在 90% 的时间内定义相同的 YAML 文件。

在这里,我们将重点介绍如何使用 Helm 智能地管理应用程序。


什么是Helm?

[图片上传失败...(image-8fa3af-1684742728274)]

<figcaption style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; margin-top: 1em; width: 520px;">来自https://helm.sh/的 Helm 标志</figcaption>

Helm是 Kubernetes 的包管理器。Helm 是一个开源项目,最初由DeisLabs创建并捐赠给Cloud Native Foundation ( CNCF )。CNCF 现在维护并毕业了该项目。这意味着它已经成熟,而不仅仅是一种时尚。

包管理在软件行业中并不是一个新概念。在 Linux 发行版上,您可以使用YUM/RPMAPT等包管理器来管理软件安装和删除。在 Windows 上,您可以在 Mac 上使用ChocolateyHomebrew

Helm 让您可以在 Kubernetes 中打包和部署完整的应用程序。包称为“图表”。Helm 使用基于Go 模板的模板系统从图表中呈现 Kubernetes 清单。图表是分隔模板和值的一致结构。

作为一个包,图表还可以管理与其他图表的依赖关系。例如,如果您的应用程序需要 MySQL 数据库才能工作,您可以将图表作为依赖项包含在内。当 Helm 在 chart 目录的顶层运行时,它会安装整个依赖项。您只需一个命令即可将您的应用程序呈现并发布到 Kubernetes。

Helm 图表使用版本来跟踪清单中的更改——因此您可以为特定的基础设施配置安装特定的图表版本。Helm 在专用工作区中保留所有已部署图表的发布历史记录。如果发生错误,这使得应用程序更新和回滚更加容易。

Helm 允许您压缩图表。其结果是一个可与 Docker 镜像相媲美的工件。然后,您可以将其发送到远程存储库以实现可重用性和共享。


使用 Helm 有什么好处?

  • Helm 使您能够使用单个命令安装应用程序。图表可以包含其他图表作为依赖项。因此,您可以使用 Helm 部署整个堆栈。您可以像docker-compose一样使用 Helm ,但用于 Kubernetes。
  • 图表包括各种 Kubernetes 资源的模板,以形成一个完整的应用程序。这降低了微服务的复杂性并简化了它们在 Kubernetes 中的管理。
  • 可以压缩图表并将其发送到远程存储库。这为 Kubernetes 创建了一个应用程序工件。您还可以从存储库中获取和部署现有的 Helm 图表。这是可重用性和共享性的强项。
  • Helm 在 Helm 工作区中维护已部署发布版本的历史记录。当出现问题时,回滚到以前的版本很简单——Helm 促进了金丝雀发布以实现零停机部署。
  • Helm 使部署高度可配置。应用程序可以在部署期间即时定制。通过更改参数,您可以将同一个图表用于多个环境,例如开发、暂存和生产。
  • 简化 CI/CD 管道——转发 GitOps 最佳实践。

快速查看 Helm 解决的问题

Kubernetes 的基本做法是手动编写 YAML 清单。我们将创建最小的 YAML 文件以在 Kubernetes 中部署 NGINX。

这是将创建 Pod 的 Deployment:

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

<figcaption style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; margin-top: 1em; width: 520px;">部署.yaml</figcaption>

该服务将 NGINX 暴露给外部。与 pod 的链接是通过选择器完成的:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

<figcaption style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; margin-top: 1em; width: 520px;">用于 NGINX 的 Kubernetes 服务:service.yaml</figcaption>

现在我们必须使用 kubectl 命令创建以前的资源:

$ kubectl create -f deployment.yaml
$ kubectl create -f service.yaml

我们检查所有资源都已启动并正在运行:

$ 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   <none>        80/TCP    4m58s
  • YAML 清单中的特定值是硬编码的,不可重复使用。
  • 要指定的冗余信息(例如标签和选择器)会导致潜在的错误。
  • Kubectl 不会在执行后处理潜在的错误。您必须一个接一个地部署每个文件。
  • 没有变化的可追溯性。

从头开始创建 Helm Chart

Helm 可以在单个命令行中创建图表结构:

$ helm create nginx

了解 Helm 图表结构

[图片上传失败...(image-26dcb4-1684742728274)]

<figcaption style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; margin-top: 1em; width: 520px;">Helm 图表的树结构</figcaption>

  • Chart.yaml:包含有关图表信息的 YAML 文件。
  • charts:包含此图表所依赖的任何图表的目录。
  • templates:这是 Helm 为您的服务、部署和其他 Kubernetes 对象找到 YAML 定义的地方。您可以为自己添加或替换生成的 YAML 文件。
  • templates/NOTES.txt:这是一个模板化的纯文本文件,在成功部署图表后打印出来。这是一个有用的地方,可以简要描述使用图表的后续步骤。
  • templates/_helpers.tpl:该文件是模板部分的默认位置。假定名称以下划线开头的文件内部没有清单。这些文件不会呈现给 Kubernetes 对象定义,但在其他图表模板中随处可用以供使用。
  • templates/tests:验证图表在安装时是否按预期工作的测试
  • values.yaml:此图表的默认配置值

自定义模板

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: {}

<figcaption style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; margin-top: 1em; width: 520px;">值.yaml</figcaption>

您可以指定一个特定的values.yaml文件来为特定于环境的设置自定义部署


安装 Helm Chart

部署 Helm chart 之前的好建议是,如果您进行了更新,请运行 linter:

$ helm lint nginx
==> Linting nginx
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

运行 Helm 以试运行和调试模式安装图表以确保一切正常:

$ helm install --debug --dry-run nginx nginx 

在调试模式下使用 helm linter 和试运行安装将为您节省宝贵的开发时间。

要安装图表,请删除--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

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 

升级 Helm 版本

假设您想将容器映像升级到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

Pod 也在使用新的容器镜像:

$ kubectl get pod -l app.kubernetes.io/name=nginx -o jsonpath='{.items[0].spec.containers[0].image}'
nginx:1.21.6

升级在图表历史记录中可见:

$ 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

可以通过以下方式检查更改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:
              {}

回滚 Helm 版本

升级不是决定性的,你想回去。由于 Helm 保留了所有更改,因此回滚非常简单:

$ helm rollback nginx 1
Rollback was a success! Happy Helming!

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

卸载 Helm Chart

卸载 Helm chart 与安装一样简单:

$ helm uninstall nginx

重用现有的 Helm 图表

许多著名的项目都提供了 Helm 图表,使集成更加用户友好。他们通过存储库提供图表。您只需将其添加到您身边:

$ helm repo add bitnami https://charts.bitnami.com/bitnami

添加后,更新本地缓存以与远程存储库同步信息:

$ helm repo update

您现在可以在 Kubernetes 集群上安装图表:

$ helm install nginx bitnami/nginx

图表使用默认值部署。您可以启发并指定自定义values.yaml以满足您的需求!

$ helm install my-release bitnami/nginx -f values.yaml


</article>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容