当前位置: 首页 > news >正文

【笔记】Helm-5 Chart模板指南-8 命名模板

命名模板

此时需要越过模板,开始创建其他内容了。该部分我们会看到如何在一个文件中定义 命名模板,并在其他地方使用。命名模板(有时称作一个部分或一个子模板)仅仅是在文件内部定义的模板,并使用了一个名字。有两种创建方式和几种不同的使用方法。

在 流控制 部分,我们介绍了三种声明和管理模板的方法:define,template,和block。在这部分,我们将使用这三种操作并介绍一种特殊用途的include方法,类似于template操作。

Helm | 流控制

命名模板时要记住一个重要细节:模板名称是全局的。如果您想声明两个相同名称的模板,哪个最后加载就使用哪个。因为在子chart中的模板和顶层模板一起编译,命名时要注意chart特定名称。

一个常见的名称惯例是用chart名称作为模板前缀:{{ define "mychart.labels" }}。使用特定chart名称作为前缀可以避免可能因为两个不同chart使用了相同名称的模板而引起的冲突。

这个规则同样适用于chart的不同版本。如果有mychart的1.0.0版本以一种方式定义了模板,mychart的2.0.0版本修改了已有的命名模板,那就会使用最后加载的版本。也可以在chart名称中添加版本来解决这个问题:{{ define "mychart.v1.labels" }}和{{ define "mychart.v2.labels" }}。

局部的和_文件

目前为止,我们已经使用了单个文件,且单个文件中包含了单个模板。但Helm的模板语言允许您创建命名的嵌入式模板,这样就可以在其他位置按名称访问。

在编写模板细节之前,文件的命名惯例需要注意:

1、templates/中的大多数文件被视为包含Kubernetes清单

2、NOTES.txt是个例外

3、命名以下划线(_)开始的文件则假定没有包含清单内容。这些文件不会渲染为Kubernetes对象定义,但在其他chart模板中都可用。

这些文件用来存储局部和辅助对象,实际上当我们第一次创建mychart时,会看到一个名为_helpers.tpl的文件,这个文件是模板局部的默认位置。

用define和template声明和使用模板

define操作允许我们在模板中创建一个命名模板,语法如下:

{{- define "MY.NAME" }}

  # body of template here

{{- end }}

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

比如我们可以定义一个模板封装Kubernetes的标签:

{{- define "mychart.labels" }}

  labels: 

    generator: helm

    data: {{ now | htmlData }}

{{- end }}

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

现在我们将模板嵌入到了已有的配置映射中,然后使用template包含进来:

{{- define "mychart.labels"}}

  labels:

    generator: helm

    date: {{ now | hemlDate }}

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

{{- define "mychart.labels" }}labels:generator: helmdate: {{ 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 }}

当模板引擎读取该文件时,它会存储mychart.labels的引用直到template "mychart.labels"被调用。然后会按行渲染模板,因此结果类似这样:

# Source: mychart/templates/configmap.yaml

apiVersion: v1

kind: ConfidMap

metadata:

  name: running-panda-configmap

  labels:

    generator: helm

    data: 2016-11-02

data:

  myvalues: "Hello World"

  drink: "coffee"

  food: "pizza"

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: running-panda-configmaplabels:generator: helmdate: 2016-11-02
data:myvalue: "Hello World"drink: "coffee"food: "pizza"

注意:define不会有输出,除非像本示例一样用模板调用它。

按照惯例,Helm chart将这些模板放置在局部文件中,一般是_helpers.tpl。把这个方法移到那里:

{{/* Generate basic labels */}}

{{- define "mychart.labels" }}

  labels:

    generator: helm

    date: {{ now | htmlDate }}

{{- end }}

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

按照惯例define方法会有个简单的文档块({{/*...*/}})来描述要做的事。

尽管这个定义是在_helpers.tpl中,但它仍能访问configmap.yaml:

apiVersion: v1

kind: ConfigMap

metadata:

  name: {{ .Release.Name }}-configmap

  {{- template "mychart.labels" }}

data:

  myvalues: "Hello World"

  {{- range $key, $val := .Values.favorite }}

  {{ $key }}: {{ $val | quote }}

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

如上所述,模板名称是全局的。因此,如果两个模板使用相同名字声明,会使用最后出现的那个。由于子chart中的模板和顶层模板一起编译,最好用chart特定名称命名您的模板。常用的命名规则是用chart的名字作为模板的前缀:{{ define "mychart.labels" }}

设置模板范围

在上面定义的模板中,我们没有使用任何对象,仅仅使用了方法。修改定义好的模板让其包含chart名称和版本号:

{{/* Generator basic labels */}}

{{-define "mychart.labels" }}

  labels:

    generator: helm

    data: {{ now| htmlDate }}

    chart: {{ .Chart.Name }}

    version: {{ .Chart.Version }}

{{- end }}

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

如果渲染这个,会得到以下错误:

$ helm install ---dry-run moldy-jaguar ./mychart

Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.metadata.labels.chart,unknown object type "nil" in ConfigMap.metadata.labels.version]

$ helm install --dry-run moldy-jaguar ./mychart
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.metadata.labels.chart, unknown object type "nil" in ConfigMap.metadata.labels.version]

要查看渲染了什么,可以用--disable-openapi-validation参数重新执行:helm install --dry-run --disable-openapi-validation moldy-jaguar ./mychart。如果并不是我们想要的:

# Source: mychart/templates/configmap.yaml

apiVersion: v1

kind: ConfigMap

metadata:

  name: modly-jaguar-configmap

  labels:

    generator: helm

    data: 2021-03-06

    chart:

    version:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: moldy-jaguar-configmaplabels:generator: helmdate: 2021-03-06chart:version:

名字和版本号怎么了?没有出现在我们定义的模板中。当一个(使用define创建的)命名模板被渲染时,会接收被template调用传入的内容。在我们的事例中,包含模板如下:

{{- template "mychart.labels" }}

{{- template "mychart.labels" }}

没有内容传入,所以模板中无法用.访问任何内容。但这个很容易解决,只需要传递一个范围给模板:

apiVersion: v1

kind: ConfigMap

metadata:

  name: {{ .Release.Name }}-configmap

  {{- template "mychart.labels" . }}

注意这个在template调用末尾传入的.,我们可以简单传入.Values或.Values.favorite或其他需求的范围。但一定要是顶层范围。

现在我们可以用helm install --dry-run --debug plinking-anaco ./mychart执行模板,然后得到:

# Source: mychart/templates/configmap.yaml

apiVersion: v1

kind: ConfigMap

metadata:

  name: plinking-anaco-configmap

  labels:

    generator: helm

    data: 2021-03-06

    chart: mychart

    version: 0.1.0

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: plinking-anaco-configmaplabels:generator: helmdate: 2021-03-06chart: mychartversion: 0.1.0

现在{{ .Chart.Name }}解析为mychart, {{ .Chart.Version }}解析为0.1.0。

include方法

假设定义了一个简单模板如下:

{{- define "mychart.app" -}}

app_name: {{ .Chart.Name }}

app_version: "{{ .Chart.Version }}"

{{- end -}}

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

现在假设我想把这个插入到模板的labels:部分和data:部分:

apiVersion: v1

kind: ConfigMap

metadata:

  name: {{ template "mychart.app"" . }}

data:

  myvalues: "Hello World"

data:

  myvalue: "Hello World"

  {{- range $key, $val := .Values.favorite }}

  {{ $key }}: {{ $val | quote }}

{{ template "mychart.app" . }}

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

如果渲染这个,会得到以下错误:

$ 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]

$ 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]

要查看渲染了什么,可以用--disable-openapi-validation参数重新执行:helm install --dry-run --disable-openapi-validation measly-whippet ./mychart。输入不是我们想要的:

# 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"

注意两处的app_version缩进都不对,为啥?因为被替换的模板中文本是左右对齐的。由于template是一个行为,不是方法,无法将template调用的输出传给其他方法,数据只是简单地按行插入。

为了处理这个问题,Helm提供了一个template的可选项,可以将模板内容导入当前管道,然后传递给管道中的其他方法。

下面这个示例,使用indent正确地缩进了mychart.app模板:

apiVersion: v1

kind: ConfigMap

metadata:

  name: {{ .Release.Name }}-configmap

  labels:

{{ include "mchart.app" . | indent 4 }}

data:

  myvalue: "Hello World"

  {{- range $key,$val := .Values.favorite }}

  {{ $key }}: {{ $ val | quote }}

  {{- end }}

{{ include "mychart.app" . | indent 2 }}

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

现在生成的YAML每一部分都可以正确缩进了:

# 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"

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

小贴士:相较于使用template,在helm中使用include被认为是更好的方式 只是为了更好地处理YAML文档的输出格式

有时我们需要导入内容,但不是作为模板,也就是按字面意义导入文件内容,可以通过使用.Files对象访问文件来实现,这将在下一部分展开描述。

————————————

仅用于本人学习

来源:Helm | Docs

相关文章:

【笔记】Helm-5 Chart模板指南-8 命名模板

命名模板 此时需要越过模板,开始创建其他内容了。该部分我们会看到如何在一个文件中定义 命名模板,并在其他地方使用。命名模板(有时称作一个部分或一个子模板)仅仅是在文件内部定义的模板,并使用了一个名字。有两种创…...

Github 2024-02-08 开源项目日报 Top9

根据Github Trendings的统计,今日(2024-02-08统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Ruby项目1HTML项目1Python项目1Scala项目1PLpgSQL项目1Rust项目1NASL项目1C项目1TypeScript项目1非开发语言项目…...

c语言贪食蛇游戏

演示视频 目录 一.概述 二.游戏开始前 修改控制台程序标题和大小 Win32 API GetStdHandle函数 GetConsoleCursorInfo函数和SetConsoleCursorInfo函数 SetConsoleCursorPosition函数 游戏开篇界面处理 创建地图 蛇身节点以及食物节点初始化 蛇身的初始化 整体蛇节点…...

国际物流数字化运输方式选择指南 | 箱讯科技

国际物流涉及多种运输方式,每种方式都有其独特的优势和适用场景。选择合适的运输方式对于确保货物安全、及时到达目的地并控制成本至关重要。以下是对六种主要国际运输方式的简要介绍和选择建议: 国际快递:适用于小件、高价值或急需的货物。…...

FPS游戏框架漫谈第二十天

今天我们聊的话题是: 《吃鸡中武器护甲逻辑》 当我们接到一个需求就是给我们游戏中的特定的模式指定的武器支持加护甲的功能 那么这个流程是什么样的呢? 第一步一般这个新增护甲的配置属性肯定是加载武器的Config json文件里面的呢,并且是支持…...

ChatGPT高效提问—prompt常见用法(续篇四)

ChatGPT高效提问—prompt常见用法(续篇四) 1.1 知识生成 ​ 知识生成是指使用自然语言处理技术,通过ChatGPT等AI模型生成与特定主题相关的知识、文本或回答。在知识生成过程中,模型接收prompt输入的问题、指令或上下文信息&…...

【蓝桥杯单片机记录】IO基础与LED控制

目录 一、IO基础 1.1 IAP15F2K61S2芯片原理图 1.2不同工作模式 二、新建工程的一些补充 2.1 keil中没有IAP15F2K61S2的头文件 解决:在isp软件中找到如下​编辑 2.2keil中的芯片选择 2.3推荐字体 三、sbit关键字 四、LED控制 4.1原理图 4.2不能直接通过IO…...

java 回答问题

1. How do you create a variable with the numeric value 5? int x 5; 2. The value of a string variable can be surrounded by single quotes. False 3. Which method can be used to return a string in upper case letters? toUpperCase()...

彻底学会系列:一、机器学习之线性回归(一)

1.基本概念(basic concept) 线性回归: 有监督学习的一种算法。主要关注多个因变量和一个目标变量之间的关系。 因变量: 影响目标变量的因素: X 1 , X 2 . . . X_1, X_2... X1​,X2​... ,连续值或离散值。 目标变量: …...

FPGA:我的零基础学习路线(2022秋招已上岸)持续更新中~

可内推简历,丝我即可 前言 初次接触FPGA是在2022年3月左右,正处在研二下学期,面临着暑假找工作,周围的同学大多选择了互联网,出于对互联网的裁员形势下,我选择了FPGA,对于硬件基础知识我几乎是…...

阿里云游戏服务器多少钱一个月?

阿里云游戏服务器租用价格表:4核16G服务器26元1个月、146元半年,游戏专业服务器8核32G配置90元一个月、271元3个月,阿里云服务器网aliyunfuwuqi.com分享阿里云游戏专用服务器详细配置和精准报价: 阿里云游戏服务器租用价格表 阿…...

Win32 SDK Gui编程系列之--ListView自绘OwnerDraw(续)

通过所有者绘制的列表视图(2) 所有者绘制列表视图的基础已在前一页中说明。本页将展示如何在所有者绘制列表视图中显示数据库表数据。 1、访问日志 正如在另一个页面中所述,本网站的访问日志目前是通过SQLite3数据库管理的。 以下是上述程序执行的结果。为…...

Android 应用添加系统签名权限的几种方式实现介绍

Android 应用添加系统签名权限的几种方式实现介绍 文章目录 Android 应用添加系统签名权限的几种方式实现介绍一、前言二、Android 应用添加系统签名权限的几种方式介绍1、在Android Studio添加系统签名文件2、源码编译apk添加系统签名Android.mkAndroid.bp 3、源码编译app代码…...

麒麟V10+飞腾处理器源码编译qt

1.下载qt源码 2.百度解压命令,进行解压 3.cd进文件目录 4.使用./configure命令进行配置(重点:记得看说明) Usage: configure [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir <dir>][-docdir <dir>] [-headerdir <dir&g…...

MacOS 查AirPods 电量技巧:可实现低电量提醒、自动弹窗

要怎么透过macOS 来查询AirPods 电量呢&#xff1f;当AirPods 和Mac 配对后&#xff0c;有的朋友想通过Mac来查询AirPods有多少电量&#xff0c;这个里有几个技巧&#xff0c;下面我们来介绍一下。 透过Mac 查AirPods 电量技巧 技巧1. 利用状态列上音量功能查询 如要使用此功能…...

python介绍,安装Cpython解释器,IDE工具pycharm的使用

python介绍 官方的Python解释器本质是基于C语言开发的一个软件&#xff0c;该软件的功能就是读取以py.结尾的文件内容&#xff0c;然后按照Guido定义好的语法和规则去翻译并执行相应的代码。这种C实现的解释器被称为Cpython。 python解释器的种类&#xff1a;Jython IPyth…...

服务器安装Docker (centOS)

1. 卸载旧版本的Docker&#xff08;如果有&#xff09; 首先&#xff0c;如果您的系统上安装了旧版本的Docker&#xff0c;需要将其卸载。Docker的旧版本称为docker或docker-engine。使用以下命令来卸载旧版本&#xff1a; sudo yum remove docker \ docker-client \ docker-…...

解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

今天又来继续我们的字符串函数的文章&#xff0c;这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。 目录 strchr strtok sprintf和sscanf strchr strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例&…...

备战蓝桥杯---搜索(进阶4)

话不多说&#xff0c;直接看题&#xff1a; 下面是分析&#xff1a; (ab)%c(a%cb%c)%c; (a*b)%c(a%c*b%c)%c; 因此&#xff0c;如果两个长度不一样的值%m为相同值&#xff0c;那就舍弃长的&#xff08;因为再加1位只不过是原来值*10那位值&#xff0c;因此他们得出的%m还是同…...

51单片机基础(C语言):定时器时钟

1.使用定时器 1 和LCD1602设计一个简易数字时钟。 main.c #include <REGX52.H> #include "Delay.h" #include "LCD1602.h" #include "Timer0.h"unsigned char Sec55,Min59,Hour23;void main() {LCD_Init();Timer0Init();LCD_ShowString(…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...