跳到主要内容
版本:3.19.0

在模板内部访问文件

在上一节中,我们介绍了创建和访问命名模板的几种方法。这使得在模板之间相互导入变得很容易。但有时你需要导入的是一个非模板文件,并直接注入其内容,而不经过模板渲染引擎处理。

Helm 通过 .Files 对象提供对文件的访问。不过在使用模板示例之前,有几点需要注意:

  • 可以在 chart 中添加额外的文件,这些文件会被一起打包。但要注意,由于 Kubernetes 对象的存储限制,chart 大小必须小于 1M。
  • 出于安全考虑,某些文件无法通过 .Files 对象访问:
    • 无法访问 templates/ 目录中的文件。
    • 无法访问被 .helmignore 排除的文件。
    • 无法访问 Helm 应用 子 chart 之外的文件,包括父 chart 中的文件。
  • chart 不保留 UNIX 模式信息,因此文件级权限不会影响 .Files 对象对文件的可用性。

基本示例

了解了这些注意事项后,让我们编写一个模板,将三个文件读取到 ConfigMap 中。首先,在 chart 中添加三个文件,直接放在 mychart/ 目录下。

config1.toml

message = "Hello from config 1"

config2.toml

message = "This is config 2"

config3.toml

message = "Goodbye from config 3"

每个文件都是简单的 TOML 文件(类似于早期 Windows 的 INI 文件)。我们知道这些文件的名称,因此可以使用 range 函数遍历它们,并将内容注入到 ConfigMap 中。

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end }}

这个 ConfigMap 使用了前面章节讨论过的技术。例如,我们创建了一个 $files 变量来保存对 .Files 对象的引用,并使用 tuple 函数创建了要遍历的文件列表。然后打印每个文件名({{ . }}: |-),接着通过 {{ $files.Get . }} 打印文件内容。

执行这个模板会生成一个包含所有三个文件内容的 ConfigMap:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: quieting-giraf-configmap
data:
config1.toml: |-
message = "Hello from config 1"

config2.toml: |-
message = "This is config 2"

config3.toml: |-
message = "Goodbye from config 3"

路径辅助函数

处理文件时,对文件路径执行一些标准操作会很有用。为此,Helm 从 Go 的 path 包中导入了一些函数供你使用。这些函数使用与 Go 包相同的名称,但首字母小写。例如 Base 变成 base,以此类推。

导入的函数包括:

  • Base
  • Dir
  • Ext
  • IsAbs
  • Clean

Glob 模式

随着 chart 规模增长,你可能需要更好地组织文件。为此我们提供了 Files.Glob(pattern string) 方法,它支持使用 glob 模式 灵活地提取特定文件。

.Glob 返回一个 Files 类型,因此你可以在返回的对象上调用任何 Files 方法。

例如,假设有以下目录结构:

foo/:
foo.txt foo.yaml

bar/:
bar.go bar.conf baz.yaml

使用 Glob 有多种方式:

{{ $currentScope := .}}
{{ range $path, $_ := .Files.Glob "**.yaml" }}
{{- with $currentScope}}
{{ .Files.Get $path }}
{{- end }}
{{ end }}

或者

{{ range $path, $_ :=  .Files.Glob  "**.yaml" }}
{{ $.Files.Get $path }}
{{ end }}

ConfigMap 和 Secret 实用函数

(Helm 2.0.2 及更高版本可用)

将文件内容放入 ConfigMap 和 Secret 以便在运行时挂载到 Pod 是很常见的需求。为此,我们在 Files 类型上提供了一些实用方法。

结合 Glob 方法使用这些方法可以更好地组织文件。

使用上面 Glob 模式 示例中的目录结构:

---
apiVersion: v1
kind: ConfigMap
metadata:
name: conf
data:
{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}
---
apiVersion: v1
kind: Secret
metadata:
name: very-secret
type: Opaque
data:
{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }}

编码

你可以导入文件并使用 base64 编码,以确保传输成功:

apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-secret
type: Opaque
data:
token: |-
{{ .Files.Get "config1.toml" | b64enc }}

上面的模板使用之前的 config1.toml 文件并对其进行编码:

# Source: mychart/templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: lucky-turkey-secret
type: Opaque
data:
token: |-
bWVzc2FnZSA9ICJIZWxsbyBmcm9tIGNvbmZpZyAxIgo=

逐行读取

有时需要在模板中逐行访问文件内容。我们为此提供了便捷的 Lines 方法。

你可以使用 range 函数遍历 Lines

data:
some-file.txt: {{ range .Files.Lines "foo/bar.txt" }}
{{ . }}{{ end }}

helm install 过程中无法将 chart 外部的文件传入。因此,如果需要用户提供数据,必须使用 helm install -fhelm install --set 加载。

本节总结了编写 Helm 模板所需工具和技术的深入讨论。下一节我们将介绍如何使用特殊文件 templates/NOTES.txt 向 chart 用户发送安装后说明。