[Cloud Native] Explicación de la arquitectura Helm y la gramática básica

Directorio de artículos

I. Resumen

Podemos pensar en Helm como apt-get/yum en Kubernetes. Helm es el administrador de paquetes de kubernetes. Solo hay archivos de lista de configuración en el almacén de helm, pero no imágenes espejo. Los almacenes espejo siguen proporcionando imágenes espejo, como hub.docker.com y almacenes privados.

Documentación oficial: https://v3.helm.sh/zh/docs/

De hecho, escribí un artículo sobre helm antes [ Administrador de paquetes de Kubernetes (k8s) Helm (Helm3) introducción e instalación de Helm3 Harbor ], puede que no sea lo suficientemente detallado, aquí explicaré helm con más detalle.

2. Arquitectura del timón

inserte la descripción de la imagen aquí

3. Instalación del timón

Dirección de descarga: https://github.com/helm/helm/releases

# 下载包
$  wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
# 解压压缩包
$ tar -xf helm-v3.9.4-linux-amd64.tar.gz
# 制作软连接
$ ln -s /opt/helm/linux-amd64/helm /usr/local/bin/helm
# 验证
$ helm version
$ helm help

4. Componentes del timón y términos relacionados

  • Helm——Helm es una herramienta de cliente bajo la línea de comando . Se utiliza principalmente para la creación, el empaquetado y el lanzamiento de la aplicación Chart de Kubernetes, así como para la creación y gestión de almacenes Chart locales y remotos.
  • Chart- El gráfico representa un paquete de Helm . Contiene todas las definiciones de recursos necesarias para ejecutar una aplicación, herramienta o servicio dentro de un clúster de Kubernetes. Puede considerarlo como el equivalente de Kubernetes de la fórmula Homebrew, Apt dpkg o Yum RPM.
  • Release——Release es la instancia del gráfico que se ejecuta en el clúster de Kubernetes . Por lo general, un gráfico se puede instalar varias veces en el mismo clúster. Cada instalación crea una nueva versión.
  • Repoistory——El repositorio ( almacén ) es un lugar para almacenar y compartir gráficos. Es como la red de archivos CPAN de Perl o el repositorio de paquetes de Fedora, excepto que es para paquetes de Kubernetes.

5. Explicación detallada de Helm Chart

1) Estructura del directorio del gráfico

# 通过helm create命令创建一个新的chart包
helm create nginx
tree nginx

inserte la descripción de la imagen aquí

nginx/
├── charts  #依赖其他包的charts文件
├── Chart.yaml # 该chart的描述文件,包括ico地址,版本信息等
├── templates  # #存放k8s模板文件目录
│   ├── deployment.yaml # 创建k8s资源的yaml 模板
│   ├── _helpers.tpl # 下划线开头的文件,可以被其他模板引用
│   ├── hpa.yaml # 弹性扩缩容,配置服务资源CPU 内存
│   ├── ingress.yaml # ingress 配合service域名访问的配置
│   ├── NOTES.txt # 说明文件,helm install之后展示给用户看的内容
│   ├── serviceaccount.yaml # 服务账号配置
│   ├── service.yaml # kubernetes Serivce yaml 模板
│   └── tests # 测试模块
│       └── test-connection.yaml 
└── values.yaml # 给模板文件使用的变量

Puede haber paquetes de escritura y los siguientes directorios:

wordpress/
...
  LICENSE             # 可选: 包含chart许可证的纯文本文件
  README.md           # 可选: 可读的README文件
  values.schema.json  # 可选: 一个使用JSON结构的values.yaml文件
  charts/             # 包含chart依赖的其他chart
  crds/               # 自定义资源的定义
...

2) archivo Chart.yaml

apiVersion: chart API 版本 (必需)
name: chart名称 (必需)
version: chart 版本,语义化2 版本(必需)
kubeVersion: 兼容Kubernetes版本的语义化版本(可选)
description: 一句话对这个项目的描述(可选)
type: chart类型 (可选)
keywords:
  - 关于项目的一组关键字(可选)
home: 项目home页面的URL (可选)
sources:
  - 项目源码的URL列表(可选)
dependencies: # chart 必要条件列表 (可选)
  - name: chart名称 (nginx)
    version: chart版本 ("1.2.3")
    repository: (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
    condition: (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )
    tags: # (可选)
      - 用于一次启用/禁用 一组chart的tag
    import-values: # (可选)
      - ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
    alias: (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用
maintainers: # (可选)
  - name: 维护者名字 (每个维护者都需要)
    email: 维护者邮箱 (每个维护者可选)
    url: 维护者URL (每个维护者可选)
icon: 用做icon的SVG或PNG图片URL (可选)
appVersion: 包含的应用版本(可选)。不需要是语义化,建议使用引号
deprecated: 不被推荐的chart (可选,布尔值)
annotations:
  example: 按名称输入的批注列表 (可选).
  • A partir de v3.3.2, ya no se permiten campos adicionales. La forma recomendada es agregar metadatos personalizados annotationsen formato .
  • Cada gráfico debe tener un número de versión ( version). Las versiones deben seguir el estándar SemanticVersion 2. A diferencia de Helm clásico, Helm v2 y versiones posteriores usan números de versión como marcadores de versión. Los paquetes en un repositorio se identifican por su nombre seguido de un número de versión.

Por ejemplo, la versión del campo de versión: 1.2.3 del gráfico nginx se establece en:

nginx-1.2.3.tgz

[Recordatorio] appVersionLos campos no están relacionados con versioncampos. Esta es una forma de especificar la versión de la aplicación. Por ejemplo, este gráfico de Drupal podría tener una versión de aplicación: "8.2.1", lo que indica que la versión de Drupal incluida en el gráfico (de forma predeterminada) es 8.2.1.

3) Gestión de dependencias de gráficos (dependencias)

Otros gráficos de los que depende el gráfico actual se definirán como una lista en el campo de dependencias.

dependencies:
  - name: apache
    version: 1.2.3
    repository: https://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: https://another.example.com/charts
  • El campo de nombre es el nombre del gráfico que necesita
  • El campo de versión es la versión del gráfico que necesita
  • El campo del repositorio es la URL completa del repositorio de gráficos. Tenga en cuenta que debe agregar el repositorio localmente usando helm repo add
  • Puedes usar el nombre del repositorio en lugar de la URL

demostración de ejemplo:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm pull bitnami/wordpress
tar -xf wordpress
cat wordpress/Chart.yaml

inserte la descripción de la imagen aquí
Una vez que haya definido sus dependencias, la ejecución helm dependency updateusará sus dependencias para descargar todos los gráficos que especifique en su directorio charts/.

helm dependency update ./wordpress

Cuando la actualización de dependencia de helm extrae el gráfico, se formará un paquete de gráficos en el directorio charts/. Entonces, para el ejemplo anterior, esperaría ver los siguientes archivos en el directorio del gráfico:

wordpress/charts/
├── common
├── common-2.0.1.tgz
├── mariadb
├── mariadb-11.2.2.tgz
├── memcached
└── memcached-6.2.3.tgz

inserte la descripción de la imagen aquí

etiquetar y condicionar campos en dependencias

Además de los otros campos anteriores, cada elemento de requisito puede contener campos opcionales tagsy condition. Todos los gráficos se cargarán de forma predeterminada . Si hay etiquetas o campos de condición, se evaluarán y utilizarán para controlar la carga del gráfico al que se aplican.

  • Condition--El campo de campo de condición contiene una o más rutas YAML (separadas por comas). Si esta ruta ya existe en los valores de nivel superior y se resuelve en un valor booleano, el gráfico habilitará o deshabilitará el gráfico según el valor booleano. Solo se utilizará la primera ruta válida que se encuentre en la lista; si no se encuentra la ruta, la condición no tiene efecto.

  • Tags - tagCampos es una lista con formato YAML de etiquetas asociadas con el gráfico. En el valor de nivel superior, todos los gráficos etiquetados se pueden habilitar o deshabilitar especificando una etiqueta y un valor booleano.

# parentchart/Chart.yaml

dependencies:
  - name: subchart1
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart1.enabled, global.subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: subchart2
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart2.enabled,global.subchart2.enabled
    tags:
      - back-end
      - subchart2
# parentchart/values.yaml

subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true
  • En el ejemplo anterior, todos los gráficos con la etiqueta frontal se desactivarán, pero siempre que subchart1.enabledla ruta configurada en 'true', la condición anulará la etiqueta frontal y se habilitará subchart1 .
  • Una vez que subchart2 use la etiqueta de back-end y se establezca en true, se habilitará subchart2. También tenga en cuenta que aunque subchart2 especifica un campo de condición, el valor de nivel superior no tiene una ruta y un valor correspondientes, por lo que esta condición no tendrá efecto.

--setLos parámetros se pueden utilizar para establecer etiquetas y valores condicionales.

helm install --set tags.front-end=true --set subchart2.enabled=false

Análisis de etiquetas y condiciones:

  • La condición (cuando se establece en valor) siempre anulará la etiqueta. La ruta de la primera condición del gráfico ignorará la ruta siguiente, si existe.
  • Las banderas se definen como 'el gráfico se puede habilitar si alguna de las banderas del gráfico es verdadera'.
  • Las etiquetas y los valores condicionales deben establecerse en el valor de nivel superior.
  • Las etiquetas: clave en el valor debe ser una clave de nivel superior.

4) Importar valor secundario a través de la dependencia

  • En algunos casos, vale la pena permitir que los valores del gráfico secundario se pasen al gráfico principal como valores predeterminados públicos . Un beneficio adicional de usar exportsel formato es que permite que las herramientas futuras realicen una introspección de los valores configurables por el usuario.
  • Las claves importadas que contienen valores se pueden especificar como listas YAML en el import-valuescampo . Cada elemento de la lista es una clave importada del campo de exportaciones en el subgráfico.
  • Para importar valores no incluidos en la clave de exportaciones, utilice el formato child -parent . A continuación se describen ejemplos de ambos formatos.

Use el formato de exportación:
si el archivo de valores.yaml del gráfico secundario contiene el campo de exportación en el nodo raíz, su contenido se puede importar directamente al valor del gráfico principal especificando lo siguiente:

# parent's Chart.yaml file

dependencies:
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    import-values:
      - data
# child's values.yaml file

exports:
  data:
    myint: 99

Siempre que especifiquemos los datos clave en la lista de importación, Helm buscará la clave de datos en el campo de exportaciones del subgráfico e importará su contenido.

El valor principal final contendrá nuestros campos exportados:

# parent's values

myint: 99

[Nota] Los datos de la clave principal no se incluyen en el valor final de la clave principal. Si desea especificar esta clave principal, debe usarla '子-父' 格式.

En el siguiente ejemplo, import-valuesse indica a Helm que tome cualquier valor que se encuentre en el elemento secundario: ruta y lo copie en el elemento principal: ruta especificado.

# parent's Chart.yaml file

dependencies:
  - name: subchart1
    repository: http://localhost:10191
    version: 0.1.0
    ...
    import-values:
      - child: default.data
        parent: myimports

En el ejemplo anterior, el valor de default.data que se encuentra en subchart1 se importará a la clave myimports del gráfico principal, los detalles son los siguientes:

# parent's values.yaml file

myimports:
  myint: 0
  mybool: false
  mystring: "helm rocks!"
# subchart1's values.yaml file

default:
  data:
    myint: 999
    mybool: true

El valor resultante del gráfico principal será así:

# parent's final values

myimports:
  myint: 999
  mybool: true
  mystring: "helm rocks!"

六、Plantillas y valores

1) Introducción a Plantillas y Valores

  • La plantilla Helm Chart está escrita de acuerdo con el lenguaje de plantilla Go, agregando alrededor de 50 funciones de plantilla adicionales de la biblioteca Sprig y algunas otras funciones específicas.
  • Todos los archivos de plantilla se almacenan en la templates/carpeta . Cuando Helm representa un gráfico, recorre cada archivo del directorio a través del motor de plantillas.

El valor de la plantilla se proporciona de dos maneras:

  • Los desarrolladores de gráficos pueden proporcionar un archivo values.yamlcon el nombre . Este archivo contiene valores predeterminados.
  • Los usuarios de gráficos pueden proporcionar un archivo YAML que contenga valores. Puede especificar el archivo de valores al usar el comando helm install en la línea de comando -f.

ejemplo de plantilla

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

El ejemplo anterior, basado libremente en https://github.com/deis/charts , es una plantilla para un controlador de replicación de Kubernetes. Se pueden usar los siguientes cuatro valores de plantilla (generalmente definidos en el archivo values.yaml):

  • imageRegistry: el registro de origen de la imagen de Docker
  • dockerTag: la etiqueta de la imagen de Docker
  • pullPolicy: política de extracción de Kubernetes
  • almacenamiento: almacenamiento en segundo plano, el valor predeterminado es "minio"

2) Valores predefinidos

Los valores se proporcionan a través del archivo values.yaml (o mediante el parámetro --set) accesible por el objeto .Values ​​en la plantilla, pero se puede acceder a otros fragmentos de datos predefinidos en la plantilla.

Los siguientes valores están predefinidos, son válidos para cada plantilla y se pueden anular. Como todos los valores, los nombres distinguen entre mayúsculas y minúsculas.

  • Release.Name: nombre de la versión (no gráfico)
  • Release.Namespace: espacio de nombres de la versión del gráfico publicado
  • Release.Service: versión de la organización del servicio
  • Release.IsUpgrade: establecido en verdadero si la operación actual es una actualización o una reversión
  • Release.IsInstall: establecido en verdadero si la operación actual es una instalación
  • Chart: Chart.yamlcontenido. Por lo tanto, la versión del gráfico se puede obtener de Chart.Version y el mantenedor está en Chart.Maintainers.
  • Files: un objeto de diagrama de clases que contiene archivos no especiales en el gráfico. Esto no le permitirá acceder a las plantillas, sino a otros archivos existentes (a menos que estén excluidos por .helmignore). Use { { index .Files "file.name" }} para acceder a los archivos o use la función { { .Files.Get name }}. También puede usar { { .Files.GetBytes }} para acceder al contenido del archivo como []byte.
  • Capabilities: un objeto de diagrama de clases que contiene información de la versión de Kubernetes. ({ { .Capabilities.KubeVersion }}) y versiones compatibles de la API de Kubernetes ({ { .Capabilities.APIVersions.Has “batch/v1” }})

Considerando la plantilla del apartado anterior, values.yamllos valores necesarios que proporciona el archivo son los siguientes:

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

El archivo de valores se define en formato YAML. El gráfico contendrá un archivo de valores predeterminado.yaml. El comando de instalación de Helm permite a los usuarios anular este valor con valores YAML adicionales:

helm install --generate-name --values=myvals.yaml wordpress

3) Alcance, dependencias y valores

Un archivo de valores puede declarar valores para el gráfico de nivel superior, así como charts/cualquier otro gráfico contenido en el directorio. O dicho de otro modo, el archivo de valores puede proporcionar valores para el gráfico y cualquiera de sus dependencias . Por ejemplo, el gráfico de WordPress mostrado arriba tiene mysql y apache como dependencias. El archivo de valores puede proporcionar dependencias para todos estos componentes:

title: "My WordPress Site" # Sent to the WordPress template

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

Los gráficos de orden superior tienen acceso a todas las variables definidas a continuación . Entonces, el gráfico de WordPress puede acceder a la contraseña de MySQL con .Values.mysql.password . Pero los gráficos de nivel inferior no pueden acceder al gráfico principal , por lo que MySQL no puede acceder al atributo de título. Tampoco puedo acceder a apache.port.

4) Valores globales

A partir de 2.0.0-Alpha.2, Helm admite un valor "global" especial. Considere una versión modificada del ejemplo anterior:

title: "My WordPress Site" # Sent to the WordPress template

global:
  app: MyWordPress

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

Se agregó la sección global y una aplicación de valor: MyWordPress. Este valor es válido .Values.global.appen todos los gráficos .

Por ejemplo, la plantilla mysql puede { {.Values.global.app}}acceder a la aplicación y el gráfico de apache también puede acceder a ella. De hecho, el archivo de valores anterior se regenerará así:

title: "My WordPress Site" # Sent to the WordPress template

global:
  app: MyWordPress

mysql:
  global:
    app: MyWordPress
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  global:
    app: MyWordPress
  port: 8080 # Passed to Apache

7. Orden de instalación del recurso Helm

  • espacio de nombres
  • Política de red
  • Cuota de recursos
  • LímiteRango
  • SubSecurityPolicy
  • PodDisruptionPresupuesto
  • Cuenta de servicio
  • Secreto
  • Lista secreta
  • Mapa de configuración
  • clase de almacenamiento
  • PersistentVolumePersistentVolume
  • PersistentVolumeClaimPersistentVolumeClaim
  • Definición de recurso personalizado
  • ClusterRole
  • ClusterRoleList
  • ClusterRoleBinding
  • ClusterRoleBindingListClústerRoleBindingList
  • Role
  • Lista de roles
  • Enlace de roles
  • RoleBindingListRoleBindingList
  • Servicio
  • DaemonSet
  • Vaina
  • Controlador de replicación
  • conjunto de réplicas
  • Despliegue
  • HorizontalPodAutoscaler
  • StatefulSet
  • Trabajo
  • CronJob
  • Ingreso
  • APIServicio

8. Tres formas en que Helm puede instalar el paquete Chart

Helm viene con un poderoso comando de búsqueda que se puede usar para buscar desde dos fuentes:

  • helm search hubEncuentre y enumere gráficos de timón de Artifact Hub . Artifact Hub alberga una gran cantidad de repositorios diferentes.
  • helm search repohelm repo addBúsquedas de repositorios que agrega (usa ) a su cliente de helm local. Este comando busca en función de los datos locales y no requiere una conexión a Internet.
# 添加bitnami仓库源
helm repo add bitnami https://charts.bitnami.com/bitnami
# 从bitnami源查找所有chart包,不指定具体源的话,会查找本地添加的所有源地址的所有chart包
helm search repo bitnami

1) valores de paso de parámetros

Hay dos formas de pasar datos de configuración durante la instalación:

  • --values (或 -f): anula la configuración mediante un archivo YAML. Se puede especificar varias veces, y el archivo más a la derecha se usa primero.
  • --set: sobrescribe el elemento especificado a través de la línea de comando.

Si ambos métodos se usan al mismo tiempo, el valor en --set se combinará en --values, pero el valor --set en mayor prioridad . Las anulaciones en --set se guardarán en ConfigMap. Puede ver el valor establecido por --set en la versión especificadahelm get values <release-name> a través de . Los valores establecidos en --set también se pueden borrar ejecutando helm upgrade y especificando el campo --reset-values. Los ejemplos son los siguientes:

echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml
helm install -f values.yaml bitnami/wordpress --generate-name

2) [El primer método] La instalación directa en línea no necesita descargar el paquete al local primero

helm install mysql bitnami/mysql
helm list

3) [Segundo método] Instalación sin conexión directamente a través del paquete de instalación

# 先删除
helm uninstall mysql
# 拉包到本地
helm pull bitnami/mysql
# 不解压直接安装
helm install mysql ./mysql-9.3.1.tgz
helm list

4) [Tercer método] Instale el paquete descomprimido sin conexión e instálelo nuevamente

# 拉包到本地
helm pull bitnami/mysql
# 解压安装
tar -xf mysql-9.3.1.tgz

# 开始安装
helm install mysql ./mysql \
--namespace=mysql \
--create-namespace \
--set image.registry=myharbor.com \
--set image.repository=bigdata/mysql \
--set image.tag=8.0.30 \
--set primary.service.type=NodePort \
--set service.nodePorts.mysql=30306

# 查看在运行的Release
helm list

# 卸载
helm uninstall mysql -n mysql 

Nueve, Helm Gramática básica

1) variables

Las variablestemplates/ en la plantilla ( ) se colocan todas en , por ejemplo: representando el campo de imágenes debajo de . Los valores provienen de archivos o archivos yaml especificados, o establecen variables.{ {}}{ { .Values.images }}Values 对象values.yaml-f--set

【Recordatorio】 Use para eliminar espacios y saltos de línea, si desea eliminar otros espacios y saltos de línea en esa -línea, puede usar { {-o -}}, uno es para eliminar la suma de la izquierda 空格y el otro es para eliminar 换行符la suma de la correcto空格换行符 _

2) Objetos incorporados

  • Release: El objeto Release describe el lanzamiento en sí. Contiene los siguientes objetos:
    • Release.Name: nombre de la versión;
    • Release.Namespace: el espacio de nombres incluido en la versión (si no está cubierto por el manifiesto);
    • Release.IsUpgrade: si la operación actual es una actualización o una reversión, este valor se establecerá en verdadero
    • Release.IsInstall: si la operación actual es instalar, el valor se establecerá en verdadero
    • Release.Revision: El número de versión de esta revisión. Es 1 durante la instalación y se incrementará cada vez que se actualice o revierta;
    • Release.Service: este servicio se utiliza para representar la plantilla actual. Helm es siempre Helm.
  • Valuesvalues.yaml: el objeto de valores se pasa a la plantilla desde archivos y archivos proporcionados por el usuario. vacío por defecto
  • Chart: Chart.yamlcontenido del archivo. Se puede acceder a todos los datos en Chart.yaml aquí. Por ejemplo { { .Chart.Name }}-{ { .Chart.Version }} imprimirá mychart-0.1.0.
  • Template: contiene información sobre la plantilla actual que se está ejecutando
    • Template.Name: ruta del archivo de espacio de nombres de la plantilla actual (por ejemplo, mychart/templates/mytemplate.yaml);
    • Template.BasePath: La ruta del directorio de plantillas de gráficos actual (por ejemplo, mychart/templates).

3) Funciones integradas de uso común

1, comillas y comillas

Esta función convierte en una cadena entre comillas dobles ( quote) o **comillas simples ( squote)**. Los ejemplos son los siguientes:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {
    
    {
    
     .Values.favorite.drink | quote }}
  food: {
    
    {
    
     .Values.favorite.food | upper | quote }}

La inversión de comandos es una práctica común en las plantillas. a menudo se puede ver .val | quoteen lugar de quote .val. De hecho, ambas operaciones son posibles.

2, predeterminado

Esta función le permite especificar un valor predeterminado en la plantilla, en caso de que se ignore el valor.

# 如果.Values.favorite.drink是非空值,则使用它,否则会返回tea。
drink: {
    
    {
    
     .Values.favorite.drink | default "tea" | quote }}

# 还可以这样写,如果.Bar是非空值,则使用它,否则会返回foo。
default "foo" .Bar

La definición "vacío" depende de los siguientes tipos:

整型: 0
字符串: ""
列表: []
字典: {
    
    }
布尔: false
以及所有的nil (或 null)

3, imprimir

Devuelve la cadena combinada de cada parte y los tipos que no son cadenas se convertirán en cadenas.

print "Matt has " .Dogs " dogs"

[Recordatorio] Cuando dos parámetros adyacentes no son cadenas, se agregará un espacio entre ellos.

4, imprimir

Mismo efecto que imprimir, pero agrega una nueva línea al final.

5, imprimir

Devuelve la cadena formateada pasada por los parámetros en orden.

printf "%s has %d dogs." .Name .NumberDogs
{
    
    {
    
    - printf "%d" (.Values.externalCache.port | int ) -}}
{
    
    {
    
    - printf "%s" .Values.existingSecret -}}

{
    
    {
    
    - printf "%v" .context.Values.redis.enabled -}}

# %s 字符串占位符,未解析的二进制字符串或切片
# %d 数字占位符,十进制
# %v 默认格式的值,当打印字典时,加号参数(%+v)可以添加字段名称

Para un mayor uso de marcadores de posición, consulte la documentación oficial: https://helm.sh/zh/docs/chart_template_guide/function_list/

6, recortar

El número de línea de corte elimina los espacios de ambos lados de la cadena:

trim "   hello    "

7, recortar todo

Eliminar caracteres dados de una cadena:

trimAll "$" "$5.00"

El resultado de lo anterior es: 5.00 (como una cadena).

8, inferior

Convierte toda la cadena a minúsculas:

lower "HELLO"

El resultado anterior es: hola

9, superior

Convierte toda la cadena a mayúsculas:

upper "hello"

El resultado anterior es: HOLA

10, título

Convierte la primera letra a mayúscula:

title "hello world"

El resultado de lo anterior es: Hola Mundo

11, substr

Obtenga la subcadena de la cadena, hay tres parámetros:

  • empezar (int)
  • fin (int)
  • cadena (cadena)
substr 0 5 "hello world"

El resultado anterior es: hola

12. abreviatura

Truncar una cadena con puntos suspensivos (...)

abbrev 5 "hello world"
# 第一个参数:最大长度
# 第二个参数:字符串

El resultado de lo anterior es: he..., porque los puntos suspensivos se cuentan en la longitud.

13, contiene

Pruebe si una cadena está contenida dentro de otra cadena:

contains "cat" "catch"

14, gato

La función cat combina varias cadenas en una sola, separadas por espacios:

cat "hello" "beautiful" "world"

El resultado de lo anterior es: hola hermoso mundo

15, sangría

sangría sangra la línea de la cadena dada por la longitud especificada , útil cuando se alinean cadenas de varias líneas:

indent 4 $lots_of_text

El resultado anterior sangrará cada línea con 4 espacios.

dieciséis

La función nindent es la misma que la función de sangría, pero puede agregar una nueva línea al comienzo de la cadena.

nindent 4 $lots_of_text

El resultado anterior sangrará 4 caracteres en la línea donde se encuentra la cadena y agregará una nueva línea al principio.

17, reemplazar

Realice reemplazos de cadenas simples.

# 下面两行等价
replace " " "-" "I Am Henry VIII" 
"I Am Henry VIII" | replace " " "-"

# 参数1:待替换字符串
# 参数2:要替换字符串
# 参数3:源字符串

El resultado de lo anterior es: Yo-Soy-Henry-VIII

18, fecha

La función de fecha da formato a la fecha, y la fecha tiene el formato AÑO-MES-DÍA:

now | date "2006-01-02"

Para obtener más funciones integradas, consulte la documentación oficial: https://helm.sh/zh/docs/chart_template_guide/function_list/

4) Tipo de función de conversión

Helm proporciona las siguientes funciones de conversión de tipos:

  • atoi: Convierte una cadena en un entero.
  • float64: Convertir a float64.
  • int: Convierte a int de acuerdo con el ancho del entero del sistema.
  • int64: Convertir a int64.
  • toDecimal: Convierte unix octal a int64.
  • toString: Convertir a una cadena.
  • toStrings: Convierte una lista, sector o matriz en una lista de cadenas.
  • toJson (mustToJson): Convierta una lista, segmento, matriz, diccionario u objeto a JSON.
  • toPrettyJson (mustToPrettyJson): Convierta una lista, división, matriz, diccionario u objeto a formato JSON.
  • toRawJson (mustToRawJson): Convierta una lista, división, matriz, diccionario u objeto a JSON con caracteres HTML sin escape.

5) Expresiones Regulares

Helm incluye las siguientes funciones de expresión regular

  • RegexFind (negroRegexFind)
  • regexFindAll(debe RegexFindAll)
  • regexMatch (debe RegexMatch)
  • regexReplaceAll (debe RegexReplaceAll)
  • regexReplaceAllLiteral(debeRegexReplaceAllLiteral)
  • regexSplit (negroRegexSplit)

6) funciones de codificación y decodificación

Helm tiene las siguientes funciones de codificación y decodificación:

  • b64enc/b64dec: codificar o decodificar Base64
  • b32enc/b32dec: codificar o decodificar Base32

7)Diccionarios y funciones de dictado

Helm proporciona un tipo de almacenamiento de clave/valor llamado dict (abreviatura de "diccionario", también disponible en Python). dict es un tipo desordenado. Las claves del diccionario deben ser cadenas . Pero el valor puede ser de cualquier tipo, incluso otro dictado o lista .

1. Crea un diccionario (dict)

Lo siguiente crea un diccionario de tres pares clave-valor:

$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"

2. Obtener el valor (obtener)

Dado un mapa y una clave, obtenga el valor del mapa.

get $myDict "name1"

El resultado de lo anterior es: "valor1"

Tenga en cuenta que simplemente devuelve "" si no se encuentra. No se generará ningún error.

3. Agregar pares clave-valor (conjunto)

Use set para agregar un par clave-valor al diccionario.

$_ := set $myDict "name4" "value4"

Tenga en cuenta que set devuelve un diccionario (un requisito de las funciones de plantilla de Go), por lo que es posible que deba usar $_la asignación como se indicó anteriormente para obtener el valor.

4. Eliminar (desarmar)

Dado un mapa y una llave, quita la llave del mapa.

$_ := unset $myDict "name4"

Como set, se debe devolver un diccionario.

5. Clave de juicio (hasKey)

La función hasKey devuelve verdadero si la clave dada está contenida en el diccionario dado.

hasKey $myDict "name1"

Si no se encuentra la clave, se devolverá falso.

6, arrancar

La función de extracción recibe una clave y varias asignaciones y obtiene una lista de todas las coincidencias:

pluck "name1" $myDict $myOtherDict

Lo anterior devolverá una lista que contiene cada valor encontrado ([value1 otherValue1]).

7. Fusionar dictado (fusionar, debe fusionar)

Combine dos o más diccionarios en uno, el diccionario de destino primero:

$newdict := merge $dest $source1 $source2

8. Consigue todas las llaves

La función de claves devuelve una lista de todas las claves en uno o más tipos de dictado. Dado que los diccionarios no están ordenados, las claves no estarán en un orden predecible. Puede usar el almacenamiento sortAlpha.

keys $myDict | sortAlpha

Cuando se proporcionan varios diccionarios, las claves se concatenan. Utilice uniqla función y sortAlphapara obtener una lista ordenada única de claves.

keys $myDict $myOtherDict | uniq | sortAlpha

9. Obtenga todos los valores

La función de valores es similar a las claves, devolviendo una nueva lista que contiene todos los valores en el diccionario de origen (solo se admite un diccionario).

$vals := values $myDict

El resultado de lo anterior es: lista["valor1", "valor2", "valor 3"].

Tenga en cuenta que los valores no garantizan el orden de los resultados; si necesita orden, use sortAlpha.

8)Listas y funciones de lista

Helm proporciona un tipo de lista simple que contiene listas en cualquier orden. Similar a matrices o sectores, pero las listas están diseñadas para tipos de datos inmutables.

1. Crea una lista

$myList := list 1 2 3 4 5

Lo anterior generaría una lista [1 2 3 4 5].

2. Obtenga el primer elemento de la lista (first, mustFirst)

Para obtener el primer elemento de la lista, use primero.

first $myList
# 返回 1

Se producirá un error si hay un problema con first y se devolverá un error al motor de plantilla si hay un problema con mustFirst.

3. Obtenga el contenido final de la lista (rest, mustRest)

Obtenga el contenido de la cola de la lista (todo menos el primer elemento), usando resto.

rest $myList
# 返回 [2 3 4 5]

Se producirá un error cuando haya un problema con el descanso, y se devolverá un error al motor de plantilla cuando haya un problema con mustRest.

4. Obtenga el último elemento de la lista (last, mustLast)

Use last para obtener el último elemento de una lista:

last $myList 
# 返回 5。这大致类似于反转列表然后调用first。

5. Obtenga todo el contenido de la lista (inicial, mustInitial)

Devolviendo todos los elementos excepto el último.

 initial $myList
 # 返回 [1 2 3 4]。

Se producirá un error si hay un problema con initial, pero se devolverá un error al motor de plantilla si hay un problema con mustInitial.

6. Agregue elementos al final (agregar, debe agregar)

Agrega un elemento a una lista existente, creando una nueva lista.

$new = append $myList 6

La declaración anterior establecerá $nuevo en [1 2 3 4 5 6]. $myList permanecerá sin cambios.

Hay un error cuando falla la adición, pero mustAppend devuelve un error al motor de plantillas cuando hay un problema.

7. Agregue elementos al frente (anteponer, debe anteponer)

Añade elementos al principio de la lista, produciendo una nueva lista.

prepend $myList 0

La declaración anterior generaría [0 1 2 3 4 5]. $myList permanecerá sin cambios.

prepend arrojará un error, pero mustPrepend devolverá un error al motor de plantillas si hay un problema.

8. Conexión de lista múltiple (concat)

Concatenar cualquier número de listas en una sola.

concat $myList ( list 6 7 ) ( list 8 )

La declaración anterior produce [1 2 3 4 5 6 7 8]. $myList permanecerá sin cambios.

9. Marcha atrás (marcha atrás, mustReverse)

Invierta la lista dada para producir una nueva lista.

reverse $myList

La declaración anterior produce una lista: [5 4 3 2 1].

reverse arrojará un error, pero mustReverse devolverá un error al motor de plantillas.

10. Deduplicación (uniq, mustUniq)

Genere una lista con los duplicados eliminados.

list 1 1 1 2 | uniq

La declaración anterior generaría [1 2]

uniq arrojará un error cuando haya un problema, pero mustUniq devolverá un error al motor de plantillas si hay un problema.

11. Filtrado (sin, debeSin)

La función sin filtra el contenido de la lista.

without $myList 3
# 上述语句会生成 [1 2 4 5]

Un filtro puede filtrar múltiples elementos:

without $myList 1 3 5
# 这样会得到: [2 4]

Without arrojará un error, pero mustWithout devolverá un error al motor de plantillas.

12. Determinar si existe un elemento (has, mustHas)

Verifica que una lista tenga un elemento específico.

has 4 $myList

La declaración anterior devolverá verdadero, pero tiene "hola". $myList devolverá falso.

Has arrojará un error, pero mustHas devolverá un error al motor de plantillas.

13. Eliminar elementos vacíos (compacto, mustCompact)

Toma una lista y elimina elementos nulos.

$list := list 1 "a" "foo" ""
$copy := compact $list

compact devuelve una nueva lista con valores nulos (por ejemplo, "") eliminados.

compact arrojará un error, pero mustCompact devolverá un error al motor de plantillas.

14, índice

Use index list[n] para obtener el elemento n de la lista. Use la lista de índice [n] [m] ... para obtener elementos de lista de varios bits.

  • index $myList 0 devuelve 1, igual que myList[0]
  • índice $miLista 0 1 同 miLista[0][1]

15. Consigue algunos elementos (slice, mustSlice)

Para obtener algunos elementos de una lista, use la lista de segmentos[n][m]. Equivalente a lista[n:m].

  • slice $myList devuelve [1 2 3 4 5]. Equivalente a miLista[:].
  • slice $myList 3 devuelve [4 5] que es equivalente a myList[3:].
  • slice $myList 1 3 devuelve [2 3] que es equivalente a myList[1:3].
  • slice $myList 0 3 devuelve [1 2 3] que es equivalente a myList[:3].

slice arrojará un error, pero mustSlice devolverá un error al motor de plantillas si hay un problema.

16. Construye una lista de números enteros (hasta)

La función hasta construye un rango de enteros.

until 5

La declaración anterior produce una lista: [0, 1, 2, 3, 4].

Útil para bucles: rango $i, $e := hasta 5.

17 ss.

seq 5       => 1 2 3 4 5
seq -3      => 1 0 -1 -2 -3
seq 0 2     => 0 1 2
seq 2 -2    => 2 1 0 -1 -2
seq 0 2 10  => 0 2 4 6 8 10
seq 0 -2 -5 => 0 -2 -4

9) Funciones Matemáticas

1. Suma (sumar)

Utilice sumar a la suma. Acepta dos o más entradas.

add 1 2 3

2. Añadir 1 (añadir1)

Para incrementar en 1, use add1.

3. Resta (sub)

La resta usa sub.

4. Dividir (div)

Divisible usando div.

5. Módulo (mod)

Toma el mod usando mod.

6. Multiplicar (mul)

Para multiplicar usa mul. Acepta dos o más entradas.

mul 1 2 3

7. Obtenga el valor máximo (max)

Devuelve el entero más grande de un conjunto de enteros.

max 1 2 3
# 返回 3

8. Obtenga el valor mínimo (min)

Devuelve el número más pequeño de un conjunto de números.

min 1 2 3 
# 会返回 1。

9. Obtenga la longitud (len)

Devuelve la longitud del argumento como un número entero.

len .Arg

10)Funciones de red

Helm proporciona varias funciones de red:

  • getHostByNameRecibir un nombre de dominio y devolver una dirección IP.

  • getHostByName"www.google.com" devolverá la dirección correspondiente de www.google.com.

10) Declaración condicional

operador:

eq: 等于(equal to)
ne: 不等于(not equal to)
lt: 小于(less than)
le: 小于等于(less than or equal to)
gt: 大于(greater than)
ge: 大于等于(greater than or equal to)

uso if/else:

{
    
    {
    
    if 命令}}
{
    
    {
    
    else if 命令}}
{
    
    {
    
    else}}
{
    
    {
    
    end}}

Pipeline se establecerá en falso si:

布尔false
数字0
空字符串
nil (空或null)
空集合(map, slice, tuple, dict, array)

【Ejemplo】

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {
    
    {
    
     .Values.favorite.drink | default "tea" | quote }}
  food: {
    
    {
    
     .Values.favorite.food | upper | quote }}
  {
    
    {
    
     if eq .Values.favorite.drink "coffee" }}mug: "true"{
    
    {
    
     end }}

11) Cambiar alcance con

La siguiente estructura de control es withla operación. Esto se utiliza para controlar el alcance de la variable . Recuerde que .es una referencia al alcance actual. Eso .Valuesle dice a la plantilla que busque el objeto Valores en el ámbito actual.

La sintaxis de with es similar a la declaración if:

{
    
    {
    
     with PIPELINE }}
  # restricted scope
{
    
    {
    
     end }}

El alcance se puede cambiar. with le permite establecer el alcance actual ( .) para un objeto específico. Por ejemplo, ya estamos usando .Values.favorite. Modifique el alcance de .en el mapa de configuración para que apunte a .Values.favorite:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {
    
    {
    
    - with .Values.favorite }}
  drink: {
    
    {
    
     .drink | default "tea" | quote }}
  food: {
    
    {
    
     .food | upper | quote }}
  {
    
    {
    
    - end }}

Pero aquí hay una advertencia: dentro de un ámbito limitado, no puede utilizar para acceder a objetos en el ámbito principal. Ejemplos de errores son los siguientes:

{
    
    {
    
    - with .Values.favorite }}
drink: {
    
    {
    
     .drink | default "tea" | quote }}
food: {
    
    {
    
     .food | upper | quote }}
release: {
    
    {
    
     .Release.Name }}
{
    
    {
    
    - end }}

Esto informará un error porque Release.Nameno está .dentro del alcance limitado . Pero es normal si las últimas dos líneas están invertidas, porque el alcance se restablece después de { { end }}.

{
    
    {
    
    - with .Values.favorite }}
drink: {
    
    {
    
     .drink | default "tea" | quote }}
food: {
    
    {
    
     .food | upper | quote }}
{
    
    {
    
    - end }}
release: {
    
    {
    
     .Release.Name }}

Alternativamente, podemos usar $el objeto Release.Name para acceder desde el ámbito principal . Cuando una plantilla comienza a ejecutarse, $se asigna al ámbito raíz y no cambia durante la ejecución. El siguiente enfoque también funciona bien:

{
    
    {
    
    - with .Values.favorite }}
drink: {
    
    {
    
     .drink | default "tea" | quote }}
food: {
    
    {
    
     .food | upper | quote }}
release: {
    
    {
    
     $.Release.Name }}
{
    
    {
    
    - end }}

Las variables también se pueden definir fuera, siguiendo $name变量el formato y especificando un operador de asignación especial: :=. Podemos reescribir lo anterior con una variable para Release.Name.

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {
    
    {
    
    - $relname := .Release.Name -}}
  {
    
    {
    
    - with .Values.favorite }}
  drink: {
    
    {
    
     .drink | default "tea" | quote }}
  food: {
    
    {
    
     .food | upper | quote }}
  release: {
    
    {
    
     $relname }}
  {
    
    {
    
    - end }}

Tenga en cuenta la asignación antes de que comience el bloque with $relname := .Release.Name. Ahora, en el bloque with, la variable $relname todavía ejecuta el nombre de la versión.

12) declaración de bucle sonó

Muchos lenguajes de programación admiten el uso de bucles for, bucles foreach o mecanismos de métodos similares. En el lenguaje de plantillas de Helm, la forma de iterar sobre una colección es usar rangeoperadores.

definir valores

favorite:
  drink: coffee
  food: pizza
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions

Ahora tenemos una lista de PizzaToppings (llamados porciones en la plantilla). Modifique la plantilla para imprimir esta lista en el mapa de configuración:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {
    
    {
    
    - with .Values.favorite }}
  drink: {
    
    {
    
     .drink | default "tea" | quote }}
  food: {
    
    {
    
     .food | upper | quote }}
  {
    
    {
    
    - end }}
  toppings: |-
    {
    
    {
    
    - range .Values.pizzaToppings }}
    - {
    
    {
    
     . | title | quote }}
    {
    
    {
    
    - end }}    

A veces es útil poder crear rápidamente una lista en una plantilla y luego iterar, y las tuplas de plantilla de Helm lo hacen fácil. En informática, una tupla representa una colección similar a una lista de tamaño fijo, pero puede ser de cualquier tipo de datos. Esto expresa aproximadamente tupleel uso de .

  sizes: |-
    {
    
    {
    
    - range tuple "small" "medium" "large" }}
    - {
    
    {
    
     . }}
    {
    
    {
    
    - end }}    

La plantilla anterior generaría lo siguiente:

  sizes: |-
    - small
    - medium
    - large    

13) Nombra la plantilla

En este punto, debe pasar de la plantilla y comenzar a crear otro contenido. En esta sección, veremos cómo definir plantillas con nombre en un archivo y usarlas en otros lugares. Una plantilla con nombre (a veces llamada sección o subplantilla) es simplemente una plantilla definida dentro de un archivo con un nombre. Hay dos formas de crearlo y varias formas diferentes de usarlo.

  • Tres métodos para declarar y administrar plantillas: define, templatey block, En esta sección usaremos estas tres operaciones y presentaremos un includemétodo , similar a la operación de plantilla.
  • Hay un detalle importante a tener en cuenta al nombrar las plantillas: los nombres de las plantillas son globales . Si desea declarar dos plantillas con el mismo nombre, se utilizará la que se cargue en último lugar . Debido a que las plantillas en los gráficos secundarios se compilan con la plantilla de nivel superior, tenga cuidado con los nombres específicos del gráfico al nombrarlos.
  • Una convención de nomenclatura común es prefijar la plantilla con el nombre del gráfico: { { define "mychart.labels" }}. El prefijo con un nombre de gráfico específico evita los conflictos que pueden surgir si dos gráficos diferentes usan plantillas con el mismo nombre.

Antes de escribir los detalles de la plantilla, la convención de nomenclatura del archivo necesita atención:

  • Se considera que la mayoría de los archivos en templates/ contienen manifiestos de Kubernetes
  • NOTAS.txt es una excepción
  • Se supone que los archivos cuyos nombres comienzan con un guión bajo ( _) no tienen contenido manifiesto. Estos archivos no se representan como definiciones de objetos de Kubernetes, pero están disponibles en otras plantillas de gráficos.

Estos archivos se utilizan para almacenar objetos locales y auxiliares. De hecho, cuando creamos mychart por primera vez, veremos un _helpers.tplarchivo llamado. Este archivo es la ubicación predeterminada de la plantilla local .

1. Declarar y usar plantillas con define y template

La operación de definición nos permite crear una plantilla con nombre en el archivo de plantilla, la sintaxis es la siguiente:

{
    
    {
    
    - define "MY.NAME" }}
  # body of template here
{
    
    {
    
    - end }}

Por ejemplo, podemos definir una plantilla para encapsular etiquetas de Kubernetes:

{
    
    {
    
    - define "mychart.labels" }}
  labels:
    generator: helm
    date: {
    
    {
    
     now | htmlDate }}
{
    
    {
    
    - end }}

Ahora incrustamos la plantilla en el mapa de configuración existente y la incluimos usando template:

{
    
    {
    
    - define "mychart.labels" }}
  labels:
    generator: helm
    date: {
    
    {
    
     now | htmlDate }}
{
    
    {
    
    - end }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
  {
    
    {
    
    - template "mychart.labels" }}
data:
  myvalue: "Hello World"
  {
    
    {
    
    - range $key, $val := .Values.favorite }}
  {
    
    {
    
     $key }}: {
    
    {
    
     $val | quote }}
  {
    
    {
    
    - end }}

Cuando el motor de plantillas lee este archivo, almacena una referencia a mychart.labels hasta que se llama a la plantilla "mychart.labels". Luego, la plantilla se procesa fila por fila, por lo que el resultado se ve así:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: running-panda-configmap
  labels:
    generator: helm
    date: 2022-09-04
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"

Nota: define no tendrá salida a menos que se llame con una plantilla como este ejemplo.

Por convención, los gráficos de Helm colocan estas plantillas en archivos parciales, generalmente _helpers.tpl. Mueva este método allí:

{
    
    {
    
    /* Generate basic labels */}}
{
    
    {
    
    - define "mychart.labels" }}
  labels:
    generator: helm
    date: {
    
    {
    
     now | htmlDate }}
{
    
    {
    
    - end }}

2. Establecer el rango de plantilla

En la plantilla definida anteriormente, no usamos ningún objeto, solo métodos. Modifique la plantilla definida para incluir el nombre del gráfico y el número de versión:

{
    
    {
    
    /* Generate basic labels */}}
{
    
    {
    
    - define "mychart.labels" }}
  labels:
    generator: helm
    date: {
    
    {
    
     now | htmlDate }}
    chart: {
    
    {
    
     .Chart.Name }}
    version: {
    
    {
    
     .Chart.Version }}
{
    
    {
    
    - end }}

3, método de inclusión

Supongamos que una plantilla simple se define de la siguiente manera:

{
    
    {
    
    - define "mychart.app" -}}
app_name: {
    
    {
    
     .Chart.Name }}
app_version: "{
    
    { .Chart.Version }}"
{
    
    {
    
    - end -}}

Ahora supongamos que quiero insertar esto en las etiquetas: y datos: secciones de la plantilla:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
  labels:
    {
    
    {
    
     template "mychart.app" . }}
data:
  myvalue: "Hello World"
  {
    
    {
    
    - range $key, $val := .Values.favorite }}
  {
    
    {
    
     $key }}: {
    
    {
    
     $val | quote }}
  {
    
    {
    
    - end }}
{
    
    {
    
     template "mychart.app" . }}

Si renderizo esto, me sale el siguiente error:

$ helm install --dry-run measly-whippet ./mychart
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(ConfigMap): unknown field "app_name" in io.k8s.api.core.v1.ConfigMap, ValidationError(ConfigMap): unknown field "app_version" in io.k8s.api.core.v1.ConfigMap]

Para ver lo que se representa, --disable-openapi-validationvuelva a ejecutar con argumentos: helm install --dry-run --disable-openapi-validation measly-whippet ./mychart. La entrada no es lo que queremos:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: measly-whippet-configmap
  labels:
    app_name: mychart
app_version: "0.1.0"
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"
app_name: mychart
app_version: "0.1.0"

Tenga en cuenta que la sangría de app_version en ambos lugares es incorrecta , ¿por qué? Porque el texto en la plantilla reemplazada está alineado a la izquierda. Dado que templatees un comportamiento, no un método , la salida de la llamada no se puedetemplate pasar a otros métodos y los datos simplemente se insertan fila por fila .

Para manejar esto, Helm proporciona un includecontenido de plantilla que se puede importar a la canalización actual y luego pasar a otros métodos en la canalización. Aquí hay un ejemplo, usando indentla plantilla mychart.app correctamente sangrada:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {
    
    {
    
     .Release.Name }}-configmap
  labels:
{
    
    {
    
     include "mychart.app" . | indent 4 }}
data:
  myvalue: "Hello World"
  {
    
    {
    
    - range $key, $val := .Values.favorite }}
  {
    
    {
    
     $key }}: {
    
    {
    
     $val | quote }}
  {
    
    {
    
    - end }}
{
    
    {
    
     include "mychart.app" . | indent 2 }}

Ahora cada parte del YAML generado tiene la sangría correcta:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: edgy-mole-configmap
  labels:
    app_name: mychart
    app_version: "0.1.0"
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"
  app_name: mychart
  app_version: "0.1.0"

includeEn comparación con el uso de una plantilla, el uso de include en helm se considera una mejor manera de manejar mejor el formato de salida de los documentos YAML.

14) archivo NOTAS.txt

Esta sección presenta la herramienta Helm que proporciona instrucciones para los usuarios de gráficos . Al final del comando de instalación o actualización de helm, Helm imprimirá información útil para el usuario . Esta sección de información se puede personalizar en gran medida mediante plantillas.

Para agregar instrucciones de instalación a un gráfico, simplemente cree templates/NOTES.txtun archivo. El archivo es texto sin formato, pero se trata como una plantilla y todas las funciones y objetos normales de la plantilla están disponibles. Vamos a crear un archivo NOTES.txt simple:

Thank you for installing {
    
    {
    
     .Chart.Name }}.

Your release is named {
    
    {
    
     .Release.Name }}.

To learn more about the release, try:

  $ helm status {
    
    {
    
     .Release.Name }}
  $ helm get all {
    
    {
    
     .Release.Name }}

Ahora si ejecutamos helm install rude-cardinal ./mychart veremos en la parte inferior:

RESOURCES:
==> v1/Secret
NAME                   TYPE      DATA      AGE
rude-cardinal-secret   Opaque    1         0s

==> v1/ConfigMap
NAME                      DATA      AGE
rude-cardinal-configmap   3         0s


NOTES:
Thank you for installing mychart.

Your release is named rude-cardinal.

To learn more about the release, try:

  $ helm status rude-cardinal
  $ helm get all rude-cardinal

Usar NOTES.txt de esta manera es una excelente manera de proporcionar a los usuarios información detallada sobre cómo usar un gráfico recién instalado. Aunque no es obligatorio, se recomienda enfáticamente crear un NOTES.txtarchivo .

15) Depuración de plantillas

La depuración de plantillas puede ser complicada, ya que las plantillas procesadas se envían al servidor de la API de Kubernetes, que puede rechazar el archivo YAML por motivos distintos al formato. Los siguientes comandos son útiles para la depuración:

  • helm lintes la herramienta de elección para verificar que los gráficos siguen las mejores prácticas
  • helm install --dry-run --debugO helm template --debug: Ya hemos visto este truco, y es una excelente manera de hacer que el servidor genere una plantilla y luego devuelva el archivo de manifiesto resultante.
  • helm get manifest: Esta es una excelente manera de ver las plantillas instaladas en el servidor.

Cuando falla el análisis de su archivo YAML, pero desea saber qué se generó, una manera fácil de recuperar el YAML es comentar la parte infractora de la plantilla y luego volver a ejecutar helm install --dry-run --debug:

apiVersion: v2
# some: problem section
# {
    
    { .Values.foo | quote }}

Lo anterior se representará y devolverá el comentario completo:

apiVersion: v2
# some: problem section
#  "bar"

De hecho, esto es principalmente para clasificar los documentos oficiales y enumera la sintaxis de uso común. Si desea obtener más información, puede consultar los documentos oficiales. Los documentos oficiales son muy detallados. Si tiene alguna pregunta, deje envíame un mensaje. Continuaré compartiendo en el futuro. 【Cloud Native y Big Data】Artículos relacionados, espere pacientemente~

おすすめ

転載: blog.csdn.net/qq_35745940/article/details/126683755