程式庫圖表

程式庫圖表是一種 Helm 圖表,它定義了圖表基元或定義,這些基元或定義可以由其他圖表中的 Helm 範本共用。這允許使用者共用可以在圖表之間重複使用的程式碼片段,避免重複並保持圖表的 DRY

程式庫圖表是在 Helm 3 中引入的,用於正式識別自 Helm 2 以來一直被圖表維護者使用的通用圖表或輔助圖表。通過將其作為圖表類型包含在內,它提供了

  • 一種明確區分通用圖表和應用程式圖表的方法
  • 防止安裝通用圖表的邏輯
  • 不渲染通用圖表中的範本,這些範本可能包含發布成品
  • 允許依賴圖表使用匯入器的上下文

圖表維護者可以將通用圖表定義為程式庫圖表,並且現在可以確信 Helm 將以標準一致的方式處理圖表。這也意味著應用程式圖表中的定義可以通過更改圖表類型來共用。

建立簡單的程式庫圖表

如前所述,程式庫圖表是一種 Helm 圖表。這意味著您可以先建立一個鷹架圖表

$ helm create mylibchart
Creating mylibchart

您首先需要刪除 templates 目錄中的所有檔案,因為我們將在此範例中建立自己的範本定義。

$ rm -rf mylibchart/templates/*

也不需要值檔案。

$ rm -f mylibchart/values.yaml

在我們開始建立通用程式碼之前,讓我們快速回顧一些相關的 Helm 概念。命名範本(有時稱為部分範本或子範本)只是一個在檔案內定義並賦予名稱的範本。在 templates/ 目錄中,任何以下劃線 (_) 開頭的檔案都不應輸出 Kubernetes 資訊清單檔案。因此,按照慣例,輔助範本和部分範本會放在 _*.tpl_*.yaml 檔案中。

在此範例中,我們將編寫一個通用的 ConfigMap,它會建立一個空的 ConfigMap 資源。我們將在檔案 mylibchart/templates/_configmap.yaml 中定義通用的 ConfigMap,如下所示

{{- define "mylibchart.configmap.tpl" -}}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data: {}
{{- end -}}
{{- define "mylibchart.configmap" -}}
{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}}
{{- end -}}

ConfigMap 構造是在命名範本 mylibchart.configmap.tpl 中定義的。它是一個簡單的 ConfigMap,帶有一個空的資源 data。在此檔案中,還有另一個名為 mylibchart.configmap 的命名範本。此命名範本包含另一個名為 mylibchart.util.merge 的命名範本,它將採用兩個命名範本作為參數,即呼叫 mylibchart.configmapmylibchart.configmap.tpl 的範本。

輔助函數 mylibchart.util.mergemylibchart/templates/_util.yaml 中的一個命名範本。它是 通用 Helm 輔助圖表 中的一個方便的實用程式,因為它會合併兩個範本並覆寫兩者中的任何共同部分

{{- /*
mylibchart.util.merge will merge two YAML templates and output the result.
This takes an array of three values:
- the top context
- the template name of the overrides (destination)
- the template name of the base (source)
*/}}
{{- define "mylibchart.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- toYaml (merge $overrides $tpl) -}}
{{- end -}}

當圖表想要使用需要使用其配置自訂的通用程式碼時,這一點非常重要。

最後,讓我們將圖表類型更改為 library。這需要編輯 mylibchart/Chart.yaml,如下所示

apiVersion: v2
name: mylibchart
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
# type: application
type: library

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application and it is recommended to use it with quotes.
appVersion: "1.16.0"

程式庫圖表現在可以共用了,並且可以重複使用其 ConfigMap 定義。

在繼續之前,值得檢查 Helm 是否將圖表識別為程式庫圖表

$ helm install mylibchart mylibchart/
Error: library charts are not installable

使用簡單的程式庫圖表

現在是時候使用程式庫圖表了。這意味著再次建立一個鷹架圖表

$ helm create mychart
Creating mychart

讓我們再次清除範本檔案,因為我們只想建立一個 ConfigMap

$ rm -rf mychart/templates/*

當我們想要在 Helm 範本中建立一個簡單的 ConfigMap 時,它可能類似於以下內容

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data:
  myvalue: "Hello World"

然而,我們將重複使用在 mylibchart 中建立的通用程式碼。可以在檔案 mychart/templates/configmap.yaml 中建立 ConfigMap,如下所示

{{- include "mylibchart.configmap" (list . "mychart.configmap") -}}
{{- define "mychart.configmap" -}}
data:
  myvalue: "Hello World"
{{- end -}}

您可以看到,它通過繼承通用的 ConfigMap 定義來簡化我們必須完成的工作,該定義為 ConfigMap 添加了標準屬性。在我們的範本中,我們添加了配置,在這種情況下是資料鍵 myvalue 及其值。配置覆寫通用 ConfigMap 的空資源。這是可行的,因為我們在上一節中提到了輔助函數 mylibchart.util.merge

為了能夠使用通用程式碼,我們需要將 mylibchart 作為依賴項添加。將以下內容添加到檔案 mychart/Chart.yaml 的末尾

# My common code in my library chart
dependencies:
- name: mylibchart
  version: 0.1.0
  repository: file://../mylibchart

這包括從檔案系統作為動態依賴項的程式庫圖表,該程式庫圖表與我們的應用程式圖表位於同一父路徑中。由於我們將程式庫圖表作為動態依賴項包含在內,因此需要執行 helm dependency update。它會將程式庫圖表複製到您的 charts/ 目錄中。

$ helm dependency update mychart/
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts

我們現在準備部署我們的圖表。在安裝之前,最好先檢查渲染後的範本。

$ helm install mydemo mychart/ --debug --dry-run
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart

NAME: mydemo
LAST DEPLOYED: Tue Mar  3 17:48:47 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
imagePullSecrets: []
ingress:
  annotations: {}
  enabled: false
  hosts:
  - host: chart-example.local
    paths: []
  tls: []
mylibchart:
  global: {}
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
  port: 80
  type: ClusterIP
serviceAccount:
  annotations: {}
  create: true
  name: null
tolerations: []

HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mydemo
  name: mychart-mydemo

這看起來像我們想要的 ConfigMap,其中 myvalue: Hello World 的資料覆寫。讓我們安裝它

$ helm install mydemo mychart/
NAME: mydemo
LAST DEPLOYED: Tue Mar  3 17:52:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

我們可以檢索版本並查看是否加載了實際範本。

$ helm get manifest mydemo
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mydemo
  name: mychart-mydemo

程式庫圖表優點

由於程式庫圖表無法充當獨立圖表,因此它們可以利用以下功能

  • .Files 物件引用父圖表上的檔案路徑,而不是程式庫圖表本地的路徑
  • .Values 物件與父圖表相同,這與應用程式 子圖表 形成對比,後者接收在父圖表中其標題下配置的值部分。

通用 Helm 輔助圖表

Note: The Common Helm Helper Chart repo on Github is no longer actively maintained, and the repo has been deprecated and archived.

圖表 是通用圖表的原始模式。它提供了反映 Kubernetes 圖表開發最佳實務的實用程式。最重要的是,您在開發圖表時可以直接使用它,為您提供方便的共用程式碼。

這是一種快速使用它的方法。有關更多詳細信息,請查看 自述檔案

再次建立一個鷹架圖表

$ helm create demo
Creating demo

讓我們使用輔助圖表中的通用程式碼。首先,編輯部署 demo/templates/deployment.yaml,如下所示

{{- template "common.deployment" (list . "demo.deployment") -}}
{{- define "demo.deployment" -}}
## Define overrides for your Deployment resource here, e.g.
apiVersion: apps/v1
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "demo.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "demo.selectorLabels" . | nindent 8 }}

{{- end -}}

現在是服務檔案 demo/templates/service.yaml,如下所示

{{- template "common.service" (list . "demo.service") -}}
{{- define "demo.service" -}}
## Define overrides for your Service resource here, e.g.
# metadata:
#   labels:
#     custom: label
# spec:
#   ports:
#   - port: 8080
{{- end -}}

這些範本展示了如何繼承輔助圖表中的通用程式碼,從而將您的編碼簡化為資源的配置或自訂。

為了能夠使用通用程式碼,我們需要將 common 作為依賴項添加。將以下內容添加到檔案 demo/Chart.yaml 的末尾

dependencies:
- name: common
  version: "^0.0.5"
  repository: "https://charts.helm.sh/incubator/"

注意:您需要將 incubator 倉庫添加到 Helm 倉庫列表中(helm repo add)。

由於我們將圖表作為動態依賴項包含在內,因此需要執行 helm dependency update。它會將輔助圖表複製到您的 charts/ 目錄中。

由於輔助圖表使用了一些 Helm 2 構造,因此您需要將以下內容添加到 demo/values.yaml 中,以允許加載 nginx 映像,因為這已在 Helm 3 鷹架圖表中更新

image:
  tag: 1.16.0

您可以使用 helm linthelm template 命令在部署之前測試圖表範本是否正確。

如果一切順利,請使用 helm install 進行部署!