我們學習了命名模板的使用,命名模板是 Helm 模板中非常重要的一個功能,在我們實際開發 Helm Chart 包的時候非常有用,到這里我們基本上就把 Helm 模板中經常使用到的一些知識點和大家介紹完了。但是仍然還是有一些在開發中值得我們注意的一些知識點,比如 `NOTES.txt` 文件的使用、子 Chart 的使用、全局值的使用。
## 1. 子 chart 包
我們到目前為止都只用了一個 chart,但是 chart 也可以有 子 chart 的依賴關系,它們也有自己的值和模板,在學習字 chart 之前,我們需要了解幾點關于子 chart 的說明:
- 子 chart 是獨立的,所以子 chart 不能明確依賴于其父 chart
- 子 chart 無法訪問其父 chart 的值
- 父 chart 可以覆蓋子 chart 的值
- Helm 中有全局值的概念,可以被所有的 chart 訪問
## 2. 創建子 chart
現在我們就來創建一個子 chart,還記得我們在創建 mychart 包的時候,在根目錄下面有一個空文件夾 charts 目錄嗎?這就是我們的子 chart 所在的目錄,在該目錄下面添加一個新的 `chart`:
```bash
$ cd mychart/charts
$ helm create mysubchart
Creating mysubchart
$ rm -rf mysubchart/templates/*.*
$ tree ..
..
├── charts
│ └── mysubchart
│ ├── charts
│ ├── Chart.yaml
│ ├── templates
│ └── values.yaml
├── Chart.yaml
├── templates
│ ├── configmap.yaml
│ ├── _helpers.tpl
│ └── NOTES.txt
└── values.yaml
5 directories, 7 files
```
同樣的,我們將子 chart 模板中的文件全部刪除了,接下來,我們為子 chart 創建一個簡單的模板和 values 文件了。
```bash
$ cat > mysubchart/values.yaml <<EOF
in: mysub
EOF
$ cat > mysubchart/templates/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap2
data:
in: {{ .Values.in }}
EOF
```
我們上面已經提到過每個子 chart 都是獨立的 `chart`,所以我們可以單獨給 `mysubchart` 進行測試:
```bash
$ helm install --dry-run --debug ./mysubchart
[debug] Created tunnel using local port: '33568'
......
---
# Source: mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: washed-indri-configmap2
data:
in: mysub
```
我們可以看到正常渲染出了結果。
## 3. 值覆蓋
現在 `mysubchart` 這個子 chart 就屬于 `mychart` 這個父 `chart` 了,由于 `mychart` 是父級,所以我們可以在 `mychart` 的 `values.yaml` 文件中直接配置子 chart 中的值,比如我們可以在 `mychart/values.yaml` 文件中添加上子 chart 的值:
```bash
course:
k8s: devops
python: django
courselist:
- k8s
- python
- search
- golang
mysubchart:
in: parent
```
注意最后兩行,`mysubchart` 部分內的任何指令都會傳遞到 `mysubchart` 這個子 chart 中去的,現在我們在 `mychart` 根目錄中執行調試命令,可以查看到子 `chart` 也被一起渲染了:
```bash
$ helm install --dry-run --debug .
[debug] Created tunnel using local port: '44798'
......
---
# Source: mychart/charts/mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ideal-ostrich-configmap2
data:
in: parent
---
# Source: mychart/templates/configmap.yaml
......
```
我們可以看到子 `chart` 中的值已經被頂層的值給覆蓋了。但是在某些場景下面我們還是希望某些值在所有模板中都可以使用,這就需要用到全局 `chart` 值了。
## 4. 全局值
全局值可以從任何 chart 或者子 `chart`中進行訪問使用,`values` 對象中有一個保留的屬性是`Values.global`,就可以被用來設置全局值,比如我們在父 chart 的 `values.yaml` 文件中添加一個全局值:
```bash
course:
k8s: devops
python: django
courselist:
- k8s
- python
- search
- golang
mysubchart:
in: parent
global:
allin: helm
```
我們在 `values.yaml` 文件中添加了一個 `global` 的屬性,這樣的話無論在父 `chart` 中還是在子 `chart` 中我們都可以通過`{{ .Values.global.allin }}`來訪問這個全局值了。比如我們在 `mychart/templates/configmap.yaml` 和 `mychart/charts/mysubchart/templates/configmap.yaml` 文件的 data 區域下面都添加上如下內容:
```bash
...
data:
allin: {{ .Values.global.allin }}
...
```
現在我們在 mychart 根目錄下面執行 `debug` 調試模式:
```bash
$ helm install --dry-run --debug .
[debug] Created tunnel using local port: '32775'
......
MANIFEST:
---
# Source: mychart/charts/mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wistful-spaniel-configmap2
data:
allin: helm
in: parent
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wistful-spaniel-configmap
......
data:
allin: helm
......
```
我們可以看到兩個模板中都輸出了`allin: helm`這樣的值,全局變量對于傳遞這樣的信息非常有用,不過也要注意我們不能濫用全局值。
另外值得注意的是我們在學習命名模板的時候就提到過父 chart 和子 chart 可以共享模板。任何 chart 中的任何定義塊都可用于其他 chart,所以我們在給命名模板定義名稱的時候添加了 chart 名稱這樣的前綴,避免沖突。