跳转至

访问文件

访问文件

在上一节中我们介绍了几种创建和访问命名模板的方法,这使得从另一个模板中导入一个模板变得很容易,但是有时候需要导入一个不是模板的文件并注入其内容,而不通过模板渲染器获得内容。

Helm 提供了一个 .Files 对象对文件的访问,但是在模板中使用这个对象之前,还有几个需要注意的事项值得一提:

  • 可以在 Helm chart 中添加额外的文件,这些文件也会被打包,不过需要注意,由于 Kubernetes 对象的存储限制,Charts 必须小于 1M
  • 由于一些安全原因,通过 .Files 对象无法访问某些文件

    • 无法访问 templates/ 下面的文件
    • 无法访问使用 .helmignore 排除的文件
    • Chart 不会保留 UNIX 模式的信息,所以,当使用 .Files 对象时,文件级别的权限不会对文件的可用性产生影响。

基本示例

现在我们来编写一个模板,将3个文件读入到 ConfigMap 模板中,首先我们在 chart 中添加3个文件,将3个文件都直接放置在 mychart/ 目录中。

config1.toml:

message = Hello from config 1

config2.toml:

message = This is config 2

config3.toml:

message = Goodbye from config 3

3个文件都是简单的 TOML 文件,我们知道这些文件的名称,所以我们可以使用 range 函数来遍历它们,并将其内容注入到 ConfigMap 中去。

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

这里我们声明了一个 $files 的变量来保存 .Files 对象的引用,还使用了 tuple 函数来循环文件列表,然后我们打印每个文件夹 {{ . }}: |-,后面使用 {{ $files.Get . }} 获取文件内容。

现在我们渲染这个模板会产生包含3个文件内容的单个 ConfigMap:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-1576046462-configmap
data:
  configtoml: |-
    message = Hello from config 1

  configtoml: |-
    message = This is config 2

  configtoml: |-
    message = Goodbye from config 3

另外在处理文件的时候,对文件路径本身执行一些标准操作可能非常有用,为了解决这个问题,Helm 从 Go 的路径包中导入了许多功能供你使用,它们都可以使用与 Go 包中相同的相同名称来访问,但是首字母需要小写,比如 Base 需要变成 base,导入的函数有:- Base - Dir - Ext - IsAbs - Clean。

Glob 模式

随着 chart 的增长,你可能需要更多地组织文件,因此 Helm 提供了 Files.Glob 的方法来帮助我们获取具有 glob 模式的文件。

.Glob 返回 Files 类型,所以你可以在返回的对象上调用任何 Files 方法。比如,我们的文件目录结构如下所示:

foo/:
  foo.txt foo.yaml

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

我们可以用 Glob 进行多种选择:

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

或者

{{ range $path, $bytes := .Files.Glob "foo/*" }}
{{ $path }}: '{{ b64enc $bytes }}'
{{ end }}

ConfigMap 和 Secrets

想要将文件内容同时放入 ConfigMap 和 Secrets 中,以便在运行时安装到 Pod 中,这种需求很常见,为了解决这个问题,Helm 在 Files 类型上添加了一个实用的方法。

根据上面的目录结构,我们可以按照如下的方式进行处理:

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 "configtoml" | b64enc }}

上面将采用我们上面的 config1.toml 文件并对其内容进行 base64 编码,渲染会得到如下所示的结果:

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mychart-1576048287-secret
type: Opaque
data:
  token: |-
    bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK

Lines

有时,需要访问模板中文件的每一行内容,Helm 也提供了方法的 Lines 方法,我们可以使用 range 函数遍历没行内容:

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

在 Helm 安装的时候无法将文件传递到 chart 外部,所以,如果你要求用户提供数据的话,则必须使用 helm install -f 或者 helm install --set 来获取。