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

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

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

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

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

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


什么是Helm?

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

来自https://helm.sh/的 Helm 标志

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

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

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

部署.yaml

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

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

用于 NGINX 的 Kubernetes 服务:service.yaml

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

从头开始创建 Helm Chart

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

$ helm create nginx

了解 Helm 图表结构

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

Helm 图表的树结构

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

值.yaml

您可以指定一个特定的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


你可能感兴趣的:(什么是Helm? Kubernetes 初学者快速入门教程)