helm入门学习(三) helm char

                                            chart

Helm使用一种称为chart的打包格式。图表是描述一组相关Kubernetes资源的文件集合。单个chart可以用于部署简单的东西,如memcached pod,也可以用于部署复杂的东西,如包含HTTP服务器、数据库、缓存等的完整web应用程序堆栈。chart是以文件的形式创建的,放在特定的目录树中,然后可以将它们打包到版本化的归档中进行部署。本文档解释了chart格式,并提供了使用Helm构建chart的基本指导。

       chart 结构:chart被组织为目录中的文件集合。目录名称是chart的名称(没有版本信息)。因此描述WordPress的chart将存储在wordpress/ 目录中。在这个目录中,Helm将期望一个与此匹配的结构:

wordpress/
  Chart.yaml          # Yaml文件,用于描述Chart的基本信息,包括名称版本等
  LICENSE             # [可选] 包含图表许可证的纯文本文件
  README.md           # [可选] 一个人类可读的自述文件当前Chart的介绍
  values.yaml         # Chart的默认配置文件
  requirements.yaml   # [可选] 用于存放当前Chart依赖的其它Chart的说明文件
  charts/             # [可选]: 该目录中放置当前Chart依赖的其它Chart
  templates/          # [可选]: 部署文件模版目录,模版使用的值来自values.yaml和由Tiller提供的值
  templates/NOTES.txt # [可选]: 包含简短用法说明的纯文本文件

Helm保留使用 charts/templates/目录和列表中文件名称。其他文件将保持原样。chart需要一个Chart.yaml 。它包含以下字段:

apiVersion:  API 版本, 通常 "v1" (必须)
name:   chart名字(必须)
version: Chart的版本号,版本号必须符合 SemVer 2:http://semver.org/ (必须)
description: 简单对chart的描述 (optional)
keywords:
  - 工程的关键字列表 (optional)
sources:
  - 当前Chart的下载地址列表 (optional)
maintainers: # (optional)
  - name: The maintainer's name (required for each maintainer)
    email: The maintainer's email (optional for each maintainer)
    url: A URL for the maintainer (optional for each maintainer)
deprecated: Whether this chart is deprecated (optional, boolean)
tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)

        结构中字段:每个chart必须有一个版本号。一个版本必须遵循SemVer 2标准。与Helm Classic不同,Kubernetes Helm使用版本号作为发布标志。仓库中的包由名称和版本标识。注:虽然Helm Classic和部署管理器在chart方面都非常面向GitHub,但是Kubernetes Helm并不依赖或需要GitHub,甚至Git。因此,它根本不使用Git SHA进行版本控制。Chart.yaml中的version字段被许多Helm工具使用,包括CLI和Tiller服务商。在生成包时,helm package命令将使用它在 Chart.yaml中找到的版本作为包名称中的标记(token)。系统假设chart包名称中的版本号与图Chart.yaml中的版本号匹配。不符合这一假设将会导致错误。appVersion字段,appVersion字段与version字段不相关。它是一种指定应用程序版本的方法。例如,drupal chart可能有一个appVersion: 8.2.1,这表示chart中包含的drupal版本(默认情况下)是8.2.1。此字段是信息性的,对chart版本计算没有影响。

       废弃chart:在chart仓库中管理chart时,有时需要废弃chartChart.yaml中可选的deprecated 字段可用于将chart标记为已废弃。如果仓库中chart的最新版本被标记为已废弃,则认为整个chart已弃用。随后可以通过发布未标记为已弃用的新版本来重用chart名称。废弃chart的工作流程如下:1) 更新chart的 Chart.yaml文件,将chart标记为已废弃,碰撞版本。2)在chart仓库中发布新的chart版本。3)从源代码仓库中删除chart(例如git)。chart还可以包含描述chart的安装、配置、使用和许可证的文件。许可证是包含chart许可证的纯文本文件。chart可以包含一个许可证,因为它可能在模板中有编程逻辑,因此不只是配置。如果需要,还可以为chart安装的应用程序提供单独的许可证。图表的自述应该是Markdown (README.md)格式的,并且通常应该包含:1)chart提供的应用程序或服务的描述;2)运行chart的任何前提条件或要求;3)values.yaml文件中选项的描述和默认值;4)与chart的安装或配置相关的任何其他信息。

    templates/NOTES.txchart还可以包含一个简短的纯文本 templates/NOTES.txt文件,该文件将在安装之后以及查看发布状态时打印出来。此文件作为模板进行计算,可用于显示使用说明、下一步操作或与chart发布相关的任何其他信息。例如,可以提供连接数据库或访问web UI的指令。由于该文件在运行helm installhelm status时被打印为标准输出,因此建议保持内容简短,并指向README以获得更详细的信息。

       chart依赖: 在Helm中,一个chart可以依赖于任意数量的其他图表。这些依赖关系可以通过 requirements.yaml文件动态链接或导入到 charts/目录并手动管理。尽管手动管理依赖项有一些团队需要,但优点很少,使用chart中的一个 requirements.yaml文件是首选方式。注:来自Helm Classic的Chart.yamldependencies: 部分已经被完全移除。使用requirements.yaml管理依赖,一个requirements.yaml文件是一个列出依赖项的简单文件。

dependencies:
  - name: apache
    version: 1.2.3
    repository: http://example.com/charts
        condition: subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: mysql
    version: 3.2.1
    alias: new-subchart-2
    repository: http://another.example.com/charts

name字段是你想要的chart的名称。version字段是你想要的chart的版本。repository字段是chart仓库的完整URL。请注意,你还必须使用helm repo add命令在本地添加该仓库。一旦你有了一个依赖文件,你可以运行 helm dependency update,它会使用你的依赖文件为你下载所有指定的chart到你的charts/目录中。当helm dependency update检索chart时,它将把它们作为chart归档文件存储在charts/目录中。因此,对于上面的示例,可以在charts/目录中看到以下文件:charts/   apache-1.2.3.tgz      mysql-3.2.1.tgz.  使用 requirements.yaml可以轻松地更新chart,requirements.yaml中的alias字段,每个需求条目可能包含可选的alias字段。为依赖chart添加alias会将chart放入依赖项中,并使用别名作为新依赖项的名称。除了上面的其他字段外,每个需求条目可能包含可选字段tagscondition。所有chart都是默认加载的。如果存在tagscondition字段,则将对它们进行计算,并使用它们来控制所应用的chart的加载。条件:condition字段包含一个或多个YAML路径(由逗号分隔)。如果此路径存在于父chart的值中并解析为布尔值,则将根据该布尔值启用或禁用chart。只计算列表中找到的第一个有效路径,如果没有路径存在,则条件无效。对于多级依赖项,该条件由到父chart的路径预先确定。标签:tags字段是与此图表相关联的标签的YAML列表。在顶层的父chart值中,通过指定标签和布尔值,可以启用或禁用所有带有标答的chart。

      模板与值: Helm Chart模板是用Go模板语言编写的,从Sprig库中添加了大约50个附加模板函数和一些其他的专用函数。所有模板文件都存储在chart的templates/文件夹中。Go附带了几个内置函数,我们还添加了许多其他函数。出于安全考虑,删除了两个:envexpandenv(这将允许chart作者访问Tiller环境)。还添加了两个特殊的模板函数:includerequiredinclude函数允许你引入另一个模板,然后将结果传递给其他模板函数。如下模板片段包含一个名为mytpl的模板,然后将结果小写,然后用双引号括起来。value: {{ include "mytpl" . | lower | quote }};required函数允许你声明模板渲染所需的特定值条目。如果该值为空,模板渲染将失败,并抛出用户提交的错误消息。下面的示例函数声明.Values.who条目是必需的,当该条目不存在时,将打印一个错误消息:value: {{ required "A valid .Values.who entry required!" .Values.who }};使用include函数时,可以使用dict函数将当前上下文构建的自定义对象树传递给它:{{- include "mytpl" (dict "key1" .Values.originalKey1 "key2" .Values.originalKey2) }};为字符串添加引号,不要为整数添加引号,当你在处理字符串数据时,为字符串添加引号总是比只留下单词更安全:name: {{ .Values.MyName | quote }};但是在处理整数时,不需要添加引号。在许多情况下,这可能导致Kubernetes内部的解析错误。port: {{ .Values.Port }};此备注不适用于字符串环境变量值的情况,即使它们表示整数:

env:
  -name: HOST
    value: "http://host"
  -name: PORT
    value: "1234"

 使用include函数,Go提供了一种使用内置的template指令将一个模板包含到另一个模板中的方法。但是在Go模板管道中不能使用内置指令;为了能够包含一个模板,然后对模板的输出执行一个操作,Helm有一个特殊的include函数:{{- include "toYaml" $value | nindent 2 }};上面包含一个名为toYaml的模板,将$value传递给它,然后将该模板的输出传递给nindent函数。使用 {{- ... | nindent _n_ }}模式使在上下文中读取include更加容易,因为它将删除左边的空格(包括前面的换行),然后nindent重新添加换行,并按请求的数量缩进包含的内容。因为YAML认为缩进层次和空白很重要,所以这是一种包含代码片段的好方法,但是要在相关上下文中处理缩进。使用required函数:Go提供了一种设置模板选项的方法,用于控制在map的键不存在时的行为。通常使用template.Options("missingkey=option")设置,其中option可以是defaultzeroerror。虽然将此选项设置为error将停止执行并出现错误,但这将适用于map中每个丢失的键。在某些情况下,chart开发人员可能希望强制在values.yaml文件中选择值。required函数使开发人员能够声明模板渲染所需的值条目。如果条目在values.yaml中为空。模板将不会呈现,并将返回由开发人员提供的错误消息。如:{{ required "A valid foo is required!" .Values.foo }};上面的代码将在定义了.Values.foo时渲染模板。但在未定义.Values.foo时将无法呈现并退出。使用tpl函数:tpl函数允许开发人员在模板中将字符串作为模板进行计算。这对于将模板字符串作为值传递给chart或渲染外部配置文件非常有用。语法为:{{ tpl TEMPLATE_STRING VALUES }}创建镜像拉取Secret:镜像拉取Secret本质上是仓库、用户名和密码的组合。你可能需要在部署的应用程序中使用它们,但是创建它们需要运行多次base64命令。我们可以编写一个帮助模板来组成Docker配置文件,作为Secret的有效负载。

当Helm渲染chart时,它将通过模板引擎传递该目录中的每个文件。模板的值有两种提供方式:1)chart开发人员可能会在chart中提供一个名为values.yaml的文件。这个文件可以包含默认值。2)chart用户可以提供包含值的YAML文件。这可以在helm install的命令行中提供。当用户提供自定义值时,这些值将覆盖chart的values.yaml中的值。模板文件:模板文件遵循编写Go模板的标准约定。一个模板文件的例子可能是这样的:

apiVersion: v1
kind: ReplicationController
metadata:
  name: deis-database
  namespace: deis
  labels:
    app.kubernetes.io/managed-by: deis
spec:
  replicas: 1
  selector:
    app.kubernetes.io/name: deis-database
  template:
    metadata:
      labels:
        app.kubernetes.io/name: deis-database
    spec:
      serviceAccount: deis-database
      containers:
        - name: deis-database
          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
          imagePullPolicy: {{.Values.pullPolicy}}
          ports:
            - containerPort: 5432
          env:
            - name: DATABASE_STORAGE
              value: {{default "minio" .Values.storage}}

上面的示例松散地基于https://github.com/deis/charts,是Kubernetes副本控制器的模板。它可以使用了以下四个模板值(常在一个values.yaml中定义):1)imageRegistry:Docker镜像的源仓库,2)dockerTag:Docker镜像的标签(tag),3)pullPolicy:Kubernetes的镜像拉取策略,4)storage:存储后端,默认设置为"minio"所有这些值都是由模板作者定义的。Helm不需要或定义参数。通过values.yaml--set选项提供的值可以从模板中的.Values对象访问。但是你可以在模板中访问其他预定义的数据片段。以下值是预先定义的,每个模板都可以使用,并且不能被覆盖。与所有值一样,名称是区分大小写的。

  • Release.Name:发布的名称(不是chart的名称)
  • Release.Time:chart发布最后一次更新的时间。这将匹配发布对象上的 Last Released时间。
  • Release.Namespace:chart发布所在的命名空间。
  • Release.Service:管理发布的服务。通常为Tiller
  • Release.IsUpgrade:如果当前操作是升级或回滚,则将其设置为true
  • Release.IsInstall:如果当前操作是安装,则将其设置为true
  • Release.Revision:修订号。它从1开始,每 helm upgrade一次,其值加1。
  • ChartChart.yaml的内容,因此,可以通过Chart.Version获取chart版本,Chart.Maintainers获取维护者。
  • Files:包含chart中所有非特殊文件的类似于Map的对象。你不能访问模板,但可以访问存在的其他文件(除非使用.helmignore排除它们)。可以使用 {{index .Files "file.name"}}或使用{{.Files.Get name}}{{.Files.GetString name}}函数访问文件。你也可以使用 {{.Files.GetBytes}}获取文件内容的字节数据([]byte)。
  • Capabilities:一个类似地图的对象,它包含关于Kubernetes版本({{.Capabilities.KubeVersion}})、Tiller版本({{.Capabilities.TillerVersion}})和支持的Kubernetes API版本({{.Capabilities.APIVersions.Has "batch/v1")信息。

任何未知的Chart.yaml字段将被删除。它们在Chart对象内部不可访问。因此,Chart.yaml不能用于将任意结构的数据传递到模板中。但是,values.yaml文件可以用于此目的。values.yaml文件,一个values.yaml文件提供必要的值应该是这样的:

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"

    values.yaml文件是YAML格式的。chart可以包含一个提供默认值的values.yaml文件。helm install命令允许用户通过提供额外的YAML值来覆盖这些值:chart中包含的默认值文件必须命名为values.yaml。但是在命令行中指定的文件可以命名为任何名称。如果在helm installhelm upgrade时使用了--set选项,那么这些值将在客户端被简单地转换为YAML。如果值(values)文件中存在任何必需的条目,可以使用required函数在chart模板中进行声明。一个values文件可以向chart及其任何依赖的chart提供值。更高层次的chart可以访问下层chart定义的所有变量。但是下层chart不能访问父chart中的内容。全局值(global: value)从2.0.0-Alpha.2开始,Helm支持特殊的“全局”值。这提供了一种与所有子chart共享一个顶层变量的方法,这对于设置标签等metadata属性非常有用。如果子chart声明了一个全局变量,那么该全局变量将向下传递(传递到子chart的子chart),而不是向上传递到父chart。子chart无法影响父chart的值。此外,父chart的全局变量优先于子chart的全局变量。

       使用Helm管理chart:helm工具有几个处理chart的命令。helm create mychart它可以为你创建一个新的chart:一旦你已经编辑了一个chart,helm可以为你把它打包成一个chart归档:$ helm package mychart;你也可以使用helm来帮助你发现chart格式或信息方面的问题:$ helm lint mychart ;chart仓库:chart仓库是一个HTTP服务器,其中存放一个或多个打包的chart。虽然helm可用于管理本地chart目录,但在共享chart时,首选的机制是chart仓库。任何能够提供YAML文件和tar文件并能够响应GET请求的HTTP服务器都可以作为仓库服务器。Helm自带用于开发人员测试的内置包服务器(helm serve)。Helm团队已经测试了其他服务器,包括启用了网站模式的谷歌云存储和启用了网站模式的S3。仓库的主要特征是存在一个称为index.yaml的特殊文件,该文件包含仓库提供的所有包的列表,以及允许检索和验证这些包的元数据。在客户端,仓库由helm repo命令管理。但是,Helm不提供将chart上传到远程仓库服务器的工具。这是因为这样做会给实现服务器增加大量的要求,从而增加了设置仓库的障碍。

       helm hooks: Helm提供了一个钩子机制,允许chart开发人员在发布生命周期的某些阶段进行干预。例如你可以使用钩子:1) 在安装过程中,在加载任何其他chart之前加载ConfigMap或Secret。2) 在安装新chart之前执行备份数据库作业,然后在升级之后执行第二个作业以恢复数据。3) 在删除发布之前运行作业,以便在删除服务之前优雅地停止作业。钩子的工作方式与常规模板类似,但是它们有特殊的注解,这导致Helm以不同的方式使用它们。钩子在清单的元数据部分用注解进行声明与可用钩子:

apiVersion: ...
kind: ....
metadata:
  annotations:
    "helm.sh/hook": "pre-install"
# ...
  • pre-install:在模板渲染后执行,但在Kubernetes中创建任何资源之前执行。
  • post-install:在所有资源加载到Kubernetes后执行。
  • pre-delete:在收到了删除请求但未从Kubernetes中删除任何资源之前执行。
  • post-delete:在收到了删除请求并从Kubernetes中删除所有资源之后执行。
  • pre-upgrade:在模板被渲染之后收到了升级请求,但是在任何资源被加载到Kubernetes之前(例如,在Kubernetes apply操作之前)执行。
  • post-upgrade:在收到了升级请求并升级完所有资源之后执行。
  • pre-rollback:在模板被渲染之后收到了回滚请求,但在任何资源被回滚之前执行。
  • post-rollback:在收到了回滚请求并回滚完所有资源之后执行。
  • crd-install:在添加CRD资源时,运行任何其他检查之前执行。这仅用于chart中其他清单使用的CRD定义。
  • test-success:在运行helm test并且pod成功返回(返回码== 0)时执行。
  • test-failure:在运行helm test并且pod成功失败(返回码!= 0)时执行。

       钩子使chart开发人员有机会在发布生命周期的某阶段执行操作。如一个helm install的生命周期。默认情况下,生命周期是这样的:1)用户运行helm install foo; 2) chart加载至Tiller; 3) 进行一些校验后,Tiller渲染foo模板; 4) Tiller加载结果资源至Kubernetes;5)Tiller返回发布名称和其它数据给客户端;6)客户端退出。Helm为install生命周期定义了两个钩子: pre-installpost-install

          如果foo chart的开发者同时实现了这两个钩子,那么它的生命周期就会这样改变:1)用户运行helm install foo;2)chart加载至Tiller;3)进行一些校验后,Tiller渲染foo模板;4)Tiller准备执行pre-install钩子(加载钩子资源至Kubernetes);5)Tiller按权重(默认为0)(具有相同权重则按名称)对钩子进行升序排序。6)然后,Tiller首先加载权重最低的钩子(负数 至 正数);7)Tiller等待钩子“就绪(Ready)”(除了CRD);8)Tiller将结果资源装载到Kubernetes中。请注意,如果设置了--wait选项,Tiller将一直等待,直到所有资源都处于就绪(Ready)状态,并且在准备就绪之前不会运行post-install钩子。9)Tiller运行post-install钩子(加载钩子资源);10)Tiller等待钩子“就绪(Ready)”;11)Tiller返回发布名称和其它数据给客户端;12)客户端退出。

        等待钩子就绪是什么意思?这取决于钩子中声明的资源。如果资源是Job类型,Tiller将等待作业成功运行到完成。如果作业失败,则发布失败。这是一个阻塞操作,所以Helm客户端将在作业运行时暂停。对于所有其他资源类型,只要Kubernetes将资源标记为已加载(已添加或已更新),资源就被认为是“就绪”的。当在一个钩子中声明许多资源时,这些资源是串行执行的。如果它们有钩子权重,则按权重升序顺序执行。否则无法保证顺序。(在Helm 2.3.0及之后,它们按字母顺序排序。不过这种行为并不具有约束力,将来可能会改变。)添加钩子权重是一种很好的做法,如果权重不重要,则将其设置为0。钩子资源不是由相应的发布来管理,钩子创建的资源不作为发布的一部分进行跟踪或管理。一旦Tiller验证钩子已经达到了它的就绪状态,它就会离开钩子资源。实际上,这意味着如果你在一个钩子中创建资源,你不能依靠helm delete来删除资源。要销毁这些资源,你需要编写代码在 pre-deletepost-delete的钩子中执行此操作,或者在钩子模板文件中添加"helm.sh/hook-delete-policy" 注解。钩子权重可以是正数或负数,但必须用字符串表示。当Tiller开始执行某种类型的钩子(例如pre-install钩子或post-install钩子等)时,它将按升序对这些钩子进行排序。

         使用crd-install钩子定义CRD,(CRD)是Kubernetes中的一种特殊类型。它们提供了一种定义其他类型(kind)的方法。有时,chart需要定义一种类型,然后使用它。这是通过crd-install钩子完成的。在安装过程中,在验证其余清单之前,很早就执行了crd-install钩子。可以使用这个钩子对CRD添加注解,以便在引用CRD的任何实例之前安装它们。这样当稍后进行验证时,CRD就可用了。自动删除钩子从以前的发布:当使用钩子的helm发布(release)更新时,钩子资源可能集群中已经存。此时,默认情况下,Helm将无法安装钩子资源,出现 "... already exists"错误。钩子资源可能已经存在的一个常见原因是,它在以前的安装或升级中使用后没有被删除。实际上,有很好的理由可以解释为什么要保留这个钩子:例如,为了在出现问题时帮助手工调试。在这种情况下,确保后续创建钩子不会失败的建议方法是定义一个"hook-delete-policy"来处理: "helm.sh/hook-delete-policy": "before-hook-creation"。此钩子注解使在安装新钩子之前删除任何已存在的钩子。如果想在每次使用后删除钩子(而不是在以后的使用中处理它,如上所示),那么可以使用删除策略 "helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"来实现。

发布了105 篇原创文章 · 获赞 86 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/dingyahui123/article/details/105477767