helm入門學習(三) helm char

                                            chart

Helm使用一種稱爲chart的打包格式。圖表是描述一組相關Kubernetes資源的文件集合。單個chart可以用於部署簡單的東西,如memcached pod,也可以用於部署複雜的東西,如包含HTTP服務器、數據庫、緩存等的完整web應用程序堆棧。chart是以文件的形式創建的,放在特定的目錄樹中,然後可以將它們打包到版本化的歸檔中進行部署。本文檔解釋了chart格式,並提供了使用Helm構建chart的基本指導。

       chart 結構:chart被組織爲目錄中的文件集合。目錄名稱是chart的名稱(沒有版本信息)。因此描述WordPress的chart將存儲在wordpress/ 目錄中。在這個目錄中,Helm將期望一個與此匹配的結構:

wordpress/
  Chart.yaml          # Yaml文件,用於描述Chart的基本信息,包括名稱版本等
  LICENSE             # [可選] 包含圖表許可證的純文本文件
  README.md           # [可選] 一個人類可讀的自述文件當前Chart的介紹
  values.yaml         # Chart的默認配置文件
  requirements.yaml   # [可選] 用於存放當前Chart依賴的其它Chart的說明文件
  charts/             # [可選]: 該目錄中放置當前Chart依賴的其它Chart
  templates/          # [可選]: 部署文件模版目錄,模版使用的值來自values.yaml和由Tiller提供的值
  templates/NOTES.txt # [可選]: 包含簡短用法說明的純文本文件

Helm保留使用 charts/templates/目錄和列表中文件名稱。其他文件將保持原樣。chart需要一個Chart.yaml 。它包含以下字段:

apiVersion:  API 版本, 通常 "v1" (必須)
name:   chart名字(必須)
version: Chart的版本號,版本號必須符合 SemVer 2:http://semver.org/ (必須)
description: 簡單對chart的描述 (optional)
keywords:
  - 工程的關鍵字列表 (optional)
sources:
  - 當前Chart的下載地址列表 (optional)
maintainers: # (optional)
  - name: The maintainer's name (required for each maintainer)
    email: The maintainer's email (optional for each maintainer)
    url: A URL for the maintainer (optional for each maintainer)
deprecated: Whether this chart is deprecated (optional, boolean)
tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)

        結構中字段:每個chart必須有一個版本號。一個版本必須遵循SemVer 2標準。與Helm Classic不同,Kubernetes Helm使用版本號作爲發佈標誌。倉庫中的包由名稱和版本標識。注:雖然Helm Classic和部署管理器在chart方面都非常面向GitHub,但是Kubernetes Helm並不依賴或需要GitHub,甚至Git。因此,它根本不使用Git SHA進行版本控制。Chart.yaml中的version字段被許多Helm工具使用,包括CLI和Tiller服務商。在生成包時,helm package命令將使用它在 Chart.yaml中找到的版本作爲包名稱中的標記(token)。系統假設chart包名稱中的版本號與圖Chart.yaml中的版本號匹配。不符合這一假設將會導致錯誤。appVersion字段,appVersion字段與version字段不相關。它是一種指定應用程序版本的方法。例如,drupal chart可能有一個appVersion: 8.2.1,這表示chart中包含的drupal版本(默認情況下)是8.2.1。此字段是信息性的,對chart版本計算沒有影響。

       廢棄chart:在chart倉庫中管理chart時,有時需要廢棄chartChart.yaml中可選的deprecated 字段可用於將chart標記爲已廢棄。如果倉庫中chart的最新版本被標記爲已廢棄,則認爲整個chart已棄用。隨後可以通過發佈未標記爲已棄用的新版本來重用chart名稱。廢棄chart的工作流程如下:1) 更新chart的 Chart.yaml文件,將chart標記爲已廢棄,碰撞版本。2)在chart倉庫中發佈新的chart版本。3)從源代碼倉庫中刪除chart(例如git)。chart還可以包含描述chart的安裝、配置、使用和許可證的文件。許可證是包含chart許可證的純文本文件。chart可以包含一個許可證,因爲它可能在模板中有編程邏輯,因此不只是配置。如果需要,還可以爲chart安裝的應用程序提供單獨的許可證。圖表的自述應該是Markdown (README.md)格式的,並且通常應該包含:1)chart提供的應用程序或服務的描述;2)運行chart的任何前提條件或要求;3)values.yaml文件中選項的描述和默認值;4)與chart的安裝或配置相關的任何其他信息。

    templates/NOTES.txchart還可以包含一個簡短的純文本 templates/NOTES.txt文件,該文件將在安裝之後以及查看發佈狀態時打印出來。此文件作爲模板進行計算,可用於顯示使用說明、下一步操作或與chart發佈相關的任何其他信息。例如,可以提供連接數據庫或訪問web UI的指令。由於該文件在運行helm installhelm status時被打印爲標準輸出,因此建議保持內容簡短,並指向README以獲得更詳細的信息。

       chart依賴: 在Helm中,一個chart可以依賴於任意數量的其他圖表。這些依賴關係可以通過 requirements.yaml文件動態鏈接或導入到 charts/目錄並手動管理。儘管手動管理依賴項有一些團隊需要,但優點很少,使用chart中的一個 requirements.yaml文件是首選方式。注:來自Helm Classic的Chart.yamldependencies: 部分已經被完全移除。使用requirements.yaml管理依賴,一個requirements.yaml文件是一個列出依賴項的簡單文件。

dependencies:
  - name: apache
    version: 1.2.3
    repository: http://example.com/charts
        condition: subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: mysql
    version: 3.2.1
    alias: new-subchart-2
    repository: http://another.example.com/charts

name字段是你想要的chart的名稱。version字段是你想要的chart的版本。repository字段是chart倉庫的完整URL。請注意,你還必須使用helm repo add命令在本地添加該倉庫。一旦你有了一個依賴文件,你可以運行 helm dependency update,它會使用你的依賴文件爲你下載所有指定的chart到你的charts/目錄中。當helm dependency update檢索chart時,它將把它們作爲chart歸檔文件存儲在charts/目錄中。因此,對於上面的示例,可以在charts/目錄中看到以下文件:charts/   apache-1.2.3.tgz      mysql-3.2.1.tgz.  使用 requirements.yaml可以輕鬆地更新chart,requirements.yaml中的alias字段,每個需求條目可能包含可選的alias字段。爲依賴chart添加alias會將chart放入依賴項中,並使用別名作爲新依賴項的名稱。除了上面的其他字段外,每個需求條目可能包含可選字段tagscondition。所有chart都是默認加載的。如果存在tagscondition字段,則將對它們進行計算,並使用它們來控制所應用的chart的加載。條件:condition字段包含一個或多個YAML路徑(由逗號分隔)。如果此路徑存在於父chart的值中並解析爲布爾值,則將根據該布爾值啓用或禁用chart。只計算列表中找到的第一個有效路徑,如果沒有路徑存在,則條件無效。對於多級依賴項,該條件由到父chart的路徑預先確定。標籤:tags字段是與此圖表相關聯的標籤的YAML列表。在頂層的父chart值中,通過指定標籤和布爾值,可以啓用或禁用所有帶有標答的chart。

      模板與值: Helm Chart模板是用Go模板語言編寫的,從Sprig庫中添加了大約50個附加模板函數和一些其他的專用函數。所有模板文件都存儲在chart的templates/文件夾中。Go附帶了幾個內置函數,我們還添加了許多其他函數。出於安全考慮,刪除了兩個:envexpandenv(這將允許chart作者訪問Tiller環境)。還添加了兩個特殊的模板函數:includerequiredinclude函數允許你引入另一個模板,然後將結果傳遞給其他模板函數。如下模板片段包含一個名爲mytpl的模板,然後將結果小寫,然後用雙引號括起來。value: {{ include "mytpl" . | lower | quote }};required函數允許你聲明模板渲染所需的特定值條目。如果該值爲空,模板渲染將失敗,並拋出用戶提交的錯誤消息。下面的示例函數聲明.Values.who條目是必需的,當該條目不存在時,將打印一個錯誤消息:value: {{ required "A valid .Values.who entry required!" .Values.who }};使用include函數時,可以使用dict函數將當前上下文構建的自定義對象樹傳遞給它:{{- include "mytpl" (dict "key1" .Values.originalKey1 "key2" .Values.originalKey2) }};爲字符串添加引號,不要爲整數添加引號,當你在處理字符串數據時,爲字符串添加引號總是比只留下單詞更安全:name: {{ .Values.MyName | quote }};但是在處理整數時,不需要添加引號。在許多情況下,這可能導致Kubernetes內部的解析錯誤。port: {{ .Values.Port }};此備註不適用於字符串環境變量值的情況,即使它們表示整數:

env:
  -name: HOST
    value: "http://host"
  -name: PORT
    value: "1234"

 使用include函數,Go提供了一種使用內置的template指令將一個模板包含到另一個模板中的方法。但是在Go模板管道中不能使用內置指令;爲了能夠包含一個模板,然後對模板的輸出執行一個操作,Helm有一個特殊的include函數:{{- include "toYaml" $value | nindent 2 }};上面包含一個名爲toYaml的模板,將$value傳遞給它,然後將該模板的輸出傳遞給nindent函數。使用 {{- ... | nindent _n_ }}模式使在上下文中讀取include更加容易,因爲它將刪除左邊的空格(包括前面的換行),然後nindent重新添加換行,並按請求的數量縮進包含的內容。因爲YAML認爲縮進層次和空白很重要,所以這是一種包含代碼片段的好方法,但是要在相關上下文中處理縮進。使用required函數:Go提供了一種設置模板選項的方法,用於控制在map的鍵不存在時的行爲。通常使用template.Options("missingkey=option")設置,其中option可以是defaultzeroerror。雖然將此選項設置爲error將停止執行並出現錯誤,但這將適用於map中每個丟失的鍵。在某些情況下,chart開發人員可能希望強制在values.yaml文件中選擇值。required函數使開發人員能夠聲明模板渲染所需的值條目。如果條目在values.yaml中爲空。模板將不會呈現,並將返回由開發人員提供的錯誤消息。如:{{ required "A valid foo is required!" .Values.foo }};上面的代碼將在定義了.Values.foo時渲染模板。但在未定義.Values.foo時將無法呈現並退出。使用tpl函數:tpl函數允許開發人員在模板中將字符串作爲模板進行計算。這對於將模板字符串作爲值傳遞給chart或渲染外部配置文件非常有用。語法爲:{{ tpl TEMPLATE_STRING VALUES }}創建鏡像拉取Secret:鏡像拉取Secret本質上是倉庫、用戶名和密碼的組合。你可能需要在部署的應用程序中使用它們,但是創建它們需要運行多次base64命令。我們可以編寫一個幫助模板來組成Docker配置文件,作爲Secret的有效負載。

當Helm渲染chart時,它將通過模板引擎傳遞該目錄中的每個文件。模板的值有兩種提供方式:1)chart開發人員可能會在chart中提供一個名爲values.yaml的文件。這個文件可以包含默認值。2)chart用戶可以提供包含值的YAML文件。這可以在helm install的命令行中提供。當用戶提供自定義值時,這些值將覆蓋chart的values.yaml中的值。模板文件:模板文件遵循編寫Go模板的標準約定。一個模板文件的例子可能是這樣的:

apiVersion: v1
kind: ReplicationController
metadata:
  name: deis-database
  namespace: deis
  labels:
    app.kubernetes.io/managed-by: deis
spec:
  replicas: 1
  selector:
    app.kubernetes.io/name: deis-database
  template:
    metadata:
      labels:
        app.kubernetes.io/name: deis-database
    spec:
      serviceAccount: deis-database
      containers:
        - name: deis-database
          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
          imagePullPolicy: {{.Values.pullPolicy}}
          ports:
            - containerPort: 5432
          env:
            - name: DATABASE_STORAGE
              value: {{default "minio" .Values.storage}}

上面的示例鬆散地基於https://github.com/deis/charts,是Kubernetes副本控制器的模板。它可以使用了以下四個模板值(常在一個values.yaml中定義):1)imageRegistry:Docker鏡像的源倉庫,2)dockerTag:Docker鏡像的標籤(tag),3)pullPolicy:Kubernetes的鏡像拉取策略,4)storage:存儲後端,默認設置爲"minio"所有這些值都是由模板作者定義的。Helm不需要或定義參數。通過values.yaml--set選項提供的值可以從模板中的.Values對象訪問。但是你可以在模板中訪問其他預定義的數據片段。以下值是預先定義的,每個模板都可以使用,並且不能被覆蓋。與所有值一樣,名稱是區分大小寫的。

  • Release.Name:發佈的名稱(不是chart的名稱)
  • Release.Time:chart發佈最後一次更新的時間。這將匹配發布對象上的 Last Released時間。
  • Release.Namespace:chart發佈所在的命名空間。
  • Release.Service:管理髮布的服務。通常爲Tiller
  • Release.IsUpgrade:如果當前操作是升級或回滾,則將其設置爲true
  • Release.IsInstall:如果當前操作是安裝,則將其設置爲true
  • Release.Revision:修訂號。它從1開始,每 helm upgrade一次,其值加1。
  • ChartChart.yaml的內容,因此,可以通過Chart.Version獲取chart版本,Chart.Maintainers獲取維護者。
  • Files:包含chart中所有非特殊文件的類似於Map的對象。你不能訪問模板,但可以訪問存在的其他文件(除非使用.helmignore排除它們)。可以使用 {{index .Files "file.name"}}或使用{{.Files.Get name}}{{.Files.GetString name}}函數訪問文件。你也可以使用 {{.Files.GetBytes}}獲取文件內容的字節數據([]byte)。
  • Capabilities:一個類似地圖的對象,它包含關於Kubernetes版本({{.Capabilities.KubeVersion}})、Tiller版本({{.Capabilities.TillerVersion}})和支持的Kubernetes API版本({{.Capabilities.APIVersions.Has "batch/v1")信息。

任何未知的Chart.yaml字段將被刪除。它們在Chart對象內部不可訪問。因此,Chart.yaml不能用於將任意結構的數據傳遞到模板中。但是,values.yaml文件可以用於此目的。values.yaml文件,一個values.yaml文件提供必要的值應該是這樣的:

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"

    values.yaml文件是YAML格式的。chart可以包含一個提供默認值的values.yaml文件。helm install命令允許用戶通過提供額外的YAML值來覆蓋這些值:chart中包含的默認值文件必須命名爲values.yaml。但是在命令行中指定的文件可以命名爲任何名稱。如果在helm installhelm upgrade時使用了--set選項,那麼這些值將在客戶端被簡單地轉換爲YAML。如果值(values)文件中存在任何必需的條目,可以使用required函數在chart模板中進行聲明。一個values文件可以向chart及其任何依賴的chart提供值。更高層次的chart可以訪問下層chart定義的所有變量。但是下層chart不能訪問父chart中的內容。全局值(global: value)從2.0.0-Alpha.2開始,Helm支持特殊的“全局”值。這提供了一種與所有子chart共享一個頂層變量的方法,這對於設置標籤等metadata屬性非常有用。如果子chart聲明瞭一個全局變量,那麼該全局變量將向下傳遞(傳遞到子chart的子chart),而不是向上傳遞到父chart。子chart無法影響父chart的值。此外,父chart的全局變量優先於子chart的全局變量。

       使用Helm管理chart:helm工具有幾個處理chart的命令。helm create mychart它可以爲你創建一個新的chart:一旦你已經編輯了一個chart,helm可以爲你把它打包成一個chart歸檔:$ helm package mychart;你也可以使用helm來幫助你發現chart格式或信息方面的問題:$ helm lint mychart ;chart倉庫:chart倉庫是一個HTTP服務器,其中存放一個或多個打包的chart。雖然helm可用於管理本地chart目錄,但在共享chart時,首選的機制是chart倉庫。任何能夠提供YAML文件和tar文件並能夠響應GET請求的HTTP服務器都可以作爲倉庫服務器。Helm自帶用於開發人員測試的內置包服務器(helm serve)。Helm團隊已經測試了其他服務器,包括啓用了網站模式的谷歌雲存儲和啓用了網站模式的S3。倉庫的主要特徵是存在一個稱爲index.yaml的特殊文件,該文件包含倉庫提供的所有包的列表,以及允許檢索和驗證這些包的元數據。在客戶端,倉庫由helm repo命令管理。但是,Helm不提供將chart上傳到遠程倉庫服務器的工具。這是因爲這樣做會給實現服務器增加大量的要求,從而增加了設置倉庫的障礙。

       helm hooks: Helm提供了一個鉤子機制,允許chart開發人員在發佈生命週期的某些階段進行干預。例如你可以使用鉤子:1) 在安裝過程中,在加載任何其他chart之前加載ConfigMap或Secret。2) 在安裝新chart之前執行備份數據庫作業,然後在升級之後執行第二個作業以恢復數據。3) 在刪除發佈之前運行作業,以便在刪除服務之前優雅地停止作業。鉤子的工作方式與常規模板類似,但是它們有特殊的註解,這導致Helm以不同的方式使用它們。鉤子在清單的元數據部分用註解進行聲明與可用鉤子:

apiVersion: ...
kind: ....
metadata:
  annotations:
    "helm.sh/hook": "pre-install"
# ...
  • pre-install:在模板渲染後執行,但在Kubernetes中創建任何資源之前執行。
  • post-install:在所有資源加載到Kubernetes後執行。
  • pre-delete:在收到了刪除請求但未從Kubernetes中刪除任何資源之前執行。
  • post-delete:在收到了刪除請求並從Kubernetes中刪除所有資源之後執行。
  • pre-upgrade:在模板被渲染之後收到了升級請求,但是在任何資源被加載到Kubernetes之前(例如,在Kubernetes apply操作之前)執行。
  • post-upgrade:在收到了升級請求並升級完所有資源之後執行。
  • pre-rollback:在模板被渲染之後收到了回滾請求,但在任何資源被回滾之前執行。
  • post-rollback:在收到了回滾請求並回滾完所有資源之後執行。
  • crd-install:在添加CRD資源時,運行任何其他檢查之前執行。這僅用於chart中其他清單使用的CRD定義。
  • test-success:在運行helm test並且pod成功返回(返回碼== 0)時執行。
  • test-failure:在運行helm test並且pod成功失敗(返回碼!= 0)時執行。

       鉤子使chart開發人員有機會在發佈生命週期的某階段執行操作。如一個helm install的生命週期。默認情況下,生命週期是這樣的:1)用戶運行helm install foo; 2) chart加載至Tiller; 3) 進行一些校驗後,Tiller渲染foo模板; 4) Tiller加載結果資源至Kubernetes;5)Tiller返回發佈名稱和其它數據給客戶端;6)客戶端退出。Helm爲install生命週期定義了兩個鉤子: pre-installpost-install

          如果foo chart的開發者同時實現了這兩個鉤子,那麼它的生命週期就會這樣改變:1)用戶運行helm install foo;2)chart加載至Tiller;3)進行一些校驗後,Tiller渲染foo模板;4)Tiller準備執行pre-install鉤子(加載鉤子資源至Kubernetes);5)Tiller按權重(默認爲0)(具有相同權重則按名稱)對鉤子進行升序排序。6)然後,Tiller首先加載權重最低的鉤子(負數 至 正數);7)Tiller等待鉤子“就緒(Ready)”(除了CRD);8)Tiller將結果資源裝載到Kubernetes中。請注意,如果設置了--wait選項,Tiller將一直等待,直到所有資源都處於就緒(Ready)狀態,並且在準備就緒之前不會運行post-install鉤子。9)Tiller運行post-install鉤子(加載鉤子資源);10)Tiller等待鉤子“就緒(Ready)”;11)Tiller返回發佈名稱和其它數據給客戶端;12)客戶端退出。

        等待鉤子就緒是什麼意思?這取決於鉤子中聲明的資源。如果資源是Job類型,Tiller將等待作業成功運行到完成。如果作業失敗,則發佈失敗。這是一個阻塞操作,所以Helm客戶端將在作業運行時暫停。對於所有其他資源類型,只要Kubernetes將資源標記爲已加載(已添加或已更新),資源就被認爲是“就緒”的。當在一個鉤子中聲明許多資源時,這些資源是串行執行的。如果它們有鉤子權重,則按權重升序順序執行。否則無法保證順序。(在Helm 2.3.0及之後,它們按字母順序排序。不過這種行爲並不具有約束力,將來可能會改變。)添加鉤子權重是一種很好的做法,如果權重不重要,則將其設置爲0。鉤子資源不是由相應的發佈來管理,鉤子創建的資源不作爲發佈的一部分進行跟蹤或管理。一旦Tiller驗證鉤子已經達到了它的就緒狀態,它就會離開鉤子資源。實際上,這意味着如果你在一個鉤子中創建資源,你不能依靠helm delete來刪除資源。要銷燬這些資源,你需要編寫代碼在 pre-deletepost-delete的鉤子中執行此操作,或者在鉤子模板文件中添加"helm.sh/hook-delete-policy" 註解。鉤子權重可以是正數或負數,但必須用字符串表示。當Tiller開始執行某種類型的鉤子(例如pre-install鉤子或post-install鉤子等)時,它將按升序對這些鉤子進行排序。

         使用crd-install鉤子定義CRD,(CRD)是Kubernetes中的一種特殊類型。它們提供了一種定義其他類型(kind)的方法。有時,chart需要定義一種類型,然後使用它。這是通過crd-install鉤子完成的。在安裝過程中,在驗證其餘清單之前,很早就執行了crd-install鉤子。可以使用這個鉤子對CRD添加註解,以便在引用CRD的任何實例之前安裝它們。這樣當稍後進行驗證時,CRD就可用了。自動刪除鉤子從以前的發佈:當使用鉤子的helm發佈(release)更新時,鉤子資源可能集羣中已經存。此時,默認情況下,Helm將無法安裝鉤子資源,出現 "... already exists"錯誤。鉤子資源可能已經存在的一個常見原因是,它在以前的安裝或升級中使用後沒有被刪除。實際上,有很好的理由可以解釋爲什麼要保留這個鉤子:例如,爲了在出現問題時幫助手工調試。在這種情況下,確保後續創建鉤子不會失敗的建議方法是定義一個"hook-delete-policy"來處理: "helm.sh/hook-delete-policy": "before-hook-creation"。此鉤子註解使在安裝新鉤子之前刪除任何已存在的鉤子。如果想在每次使用後刪除鉤子(而不是在以後的使用中處理它,如上所示),那麼可以使用刪除策略 "helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"來實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章