在範本中存取檔案

在上一節中,我們探討了幾種建立和存取命名範本的方法。這使得從一個範本中匯入另一個範本變得容易。但有時我們希望匯入一個*非範本的檔案*,並將其內容注入,而不將內容傳送給範本渲染器。

Helm 透過 .Files 物件提供對檔案的存取。不過,在我們開始範例之前,有一些關於其運作方式的注意事項

  • 可以將額外的檔案新增到 Helm 圖表中。這些檔案將會被捆綁。但請小心,由於 Kubernetes 物件的儲存限制,圖表必須小於 1M。
  • 某些檔案無法透過 .Files 物件存取,通常是出於安全考量。
    • 無法存取 templates/ 中的檔案。
    • 無法存取使用 .helmignore 排除的檔案。
    • 無法存取 Helm 應用程式 子圖表 之外的檔案,包括父圖表的檔案。
  • 圖表不會保留 UNIX 模式資訊,因此檔案級別的權限對 .Files 物件的檔案可用性沒有影響。

基本範例

有了這些注意事項後,讓我們編寫一個範本,將三個檔案讀取到我們的 ConfigMap 中。首先,我們將三個檔案新增到圖表中,將這三個檔案直接放在 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 模式

隨著圖表的增長,您可能會發現需要更好地組織檔案,因此我們提供了一個 Files.Glob(pattern string) 方法來協助您使用 glob 模式 的所有彈性來提取特定檔案。

.Glob 會傳回 Files 類型,因此您可以在傳回的物件上呼叫任何 Files 方法。

例如,想像一下目錄結構

foo/:
  foo.txt foo.yaml

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

您可以使用 Globs 執行多個選項

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

或者

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

ConfigMap 和 Secrets 工具函數

(Helm 2.0.2 及之後版本可用)

我們經常希望將檔案內容同時放置在 ConfigMaps 和 Secrets 中,以便在執行時掛載到您的 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 }}

編碼

您可以匯入檔案,並讓範本對其進行 base-64 編碼,以確保成功傳輸

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: |-
        bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK

有時我們希望在範本中存取檔案的每一行。我們為此提供了一個方便的 Lines 方法。

您可以使用 range 函數迴圈處理 Lines

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

helm install 期間無法傳遞圖表外部的檔案。因此,如果您要求使用者提供資料,則必須使用 helm install -fhelm install --set 載入資料。

本次討論總結了我們對 Helm 範本編寫工具和技術的深入探討。在下一節中,我們將看到如何使用一個特殊檔案 templates/NOTES.txt 向圖表的使用者發送安裝後說明。