iT邦幫忙

2021 iThome 鐵人賽

DAY 11
2
DevOps

k8s 入門學習 30天系列 第 11

IT 鐵人賽 k8s 入門30天 -- day11 Helm - Package Manager

前言

今天要來講說 Helm 這個工具

因為 Helm 版本會不斷推陳出新, 因此在今天的內容著重再概念上的說明

而實作的部份不太多琢磨

什麼是 Helm

對 k8s 叢集來說, Helm 是一個套件管理工具

如同 apt 之於 Debain, yum 之於 Fedora, Homebrew 之於 MacOS

假設今天要佈署一個 Elastic stack for logging 在一個已發佈的 app 上

基本上會需要一個 StatefulSet 因為需要紀錄狀態

可能還需要一個 Secret 來儲存機敏資料

一個 ConfigMap 來儲存共用變數

可能還會需要設定 k8s User Permission 來限制存取權限等等

當然 應該會佈署幾個 Service 來做運行

要做這些設定其實不是很容易

假設今天工作團隊中的其他人也要做類似的功能

這時我們就可以透過 Helm 把這些發佈過的設定檔 (yaml files) 打包成一個 Package (Chart) 放到某個 Chart Repository 讓其他團隊成員使用

讓降低其他團隊成員要佈署類似功能的複雜度

Chart Repositroy

參考 Helm Chart Repostiory 官方文件定義

這本篇文章提到 Repository 都是指 Chart Repository

Chart Repositroy 是一個 HTTP 的伺服器, 用來存放打包好的 Chart 供其他人使用

因為 Chart Repository 主要是支援放置打包過的 yaml 或是 tar 這類打包檔案, 因此以下都是可以用來當作 Chart Repository 的選項, GCS(Google Cloud Storage), AWS S3 Bucket, Github Pages, 或是自己建立的 Web Serser.

個別設定內容可以參考官方設定

Registry

在這邊這個 Registry 就筆者理解是跟 Docker Registry 一樣的概念

Helm 在 v3.x.x 開始支援 OCI-based 的存放 Chart 方式

透過 Docker 來跑一個自行建立的 Registry自行建立 local Registry

docker run -dp 5000:5000 --restart=always --name registry registry

如果你希望這個 Registry 可以再重開之後保存狀態可以在上面指令後加入 -v $(pwd)/registry:/var/lib/registry 參數, 讓狀態用 docker volume 掛載在 host 機器上

加入 Auth

首先, 建立 auth.htpasswd 檔案使用以下指令:

htpasswd -cB -b auth.htpasswd myuser mypass

然後透過以下指令跑 Docker

docker run -dp 5000:5000 --restart=always --name registry \
  -v $(pwd)/auth.htpasswd:/etc/docker/registry/auth.htpasswd \
  -e REGISTRY_AUTH="{htpasswd: {realm: localhost, path: /etc/docker/registry/auth.htpasswd}}" \
  registry

Helm Chart

把多個設定檔(yaml files) 針對某個功能打包成的 Package 就是所謂的 Helm Chart

而產生出來的 Helm Chart 會放到 Chart Repository 讓其他人使用

Helm 使用情境

共用常用佈署

有一些常用到 database app(mongodb, mysql), elastic search, monitoring app(promothes)這些都可以在 Helm repository找到

都可以透過 Helm 工具快速建制使用

建制 app 的時候, 可以使用 helm search hub $功能關鍵字

來查詢是否已經有建制過的 Helm Charts 可以直接拿到使用

或者到 artifact hub 搜索

而這些 Helm Charts 可以放在公開的 Repository 或是私有的

因為有些公司內部建制內部使用的 Package 不會公開

範本引擎

Helm 的另一個功用是用來做範本引擎

舉例來說:

假設我們要發佈的多個容器服務建制內容只有差在名稱跟版本其他是一樣的

就可以一樣的地方寫出一個建立範本, 然後在不同的地方使用變數代入

如 container-pod-template.yaml

apiVersion: v1
kind: Pod
metadata:
  name: {{ .Values.name }}
spec:
  containers:
  - name: {{ .Values.container.name }}
    image: {{ .Values.container.image }}
    port: {{ .Values.container.port }}

還有對應的 values.yaml

name: my-app
container:
  name: my-app-container
  image: my-app-image
  port: 9001

注意的是, 這邊的 Values 物件除了可以透過 yaml 來設定也可以使用 helm install 指令加上 --set 來設定

發佈同一個應用在不同環境

另外一個使用 Helm 的情境是在不同建制環境中佈署相同的應用

只要把原本的應用打包成一個 Chart, 然後發佈在不同環境的 k8s 叢集上

佈署版本管控

Helm 在發佈之後, 都會紀錄每次發佈的版本

可以用以下指令查看過去發佈的歷史

helm history $release_name

透過以下指令察看 $release_name 目前狀況

helm status $release_name

如果這個 $release_name 狀態不好

可以使用以下指令做回復到上一個版本

helm rollback $release_name

要注意的是, 當已經做 helm install 某個 chart 之後

下一次, 如果要對 chart 做更新會使用 helm upgrade 這樣就會只更新修改的部份

而不是重新起一個新的 Deployment 產生過多的 Deployment

value 注入 template 的機制

這邊想對於注入值的機制做一些說明

因為基本上, values.yaml 的值是 .Value 物件的預設值

然而, 這個預設值可以在 helm install 指令透過以下兩個方式複寫掉

1 指定 values 參數到另一個設定值 my-values.yaml

helm install --values=my-values.yaml $chart_name

2 加入 --set 指定參數值

helm install --set version=2.0.0

安裝 Helm

ref https://helm.sh/docs/intro/install/

這邊是以 v3.7.0 版本來說明

筆者這邊以 snap 在 Ubuntu 20.04 做安裝指令為範例如下:

sudo snap install helm --classic

其他 OS 的安裝方式可以參考 官方網站

Helm 版本差異

在 v2.x.x 的版本

Helm 分成 client 與 server 的部份

而 server 又被稱為 Tiller

主要由 client 發送指令給 Tiller, Tiller 負責實際發佈 service

在這樣架構下, Tiller 可以對 k8s 叢集新增修改服務, 具有極大的掌控權

因此會擔心當 Tiller 被攻擊時, 會有資安疑慮

所以在 v3.x.x 的版本移除掉了 Tiller, 只剩下 client 的部份

Helm 搜尋套件指令

這邊指令, 以 v3.7.0 版來說明

直接從 https://artifiacthub.io 來搜尋

helm search hub $chart_name

舉例來說: 搜尋 elasticsearch 的 chart

helm search hub elasticsearch

另外可以自行設定要搜尋的 Repository

helm repo add $repo_name $repo_url

在已經加入的 Repository 搜尋 chart

helm search repo $chart_name

Helm 建立

在 v3.7.0 可以透過以下指令來建立 chart

helm create $chart_name [flag]

Chart 結構

本文以 v3.7.0 為範例:

每個chart 本身會已 Chart 的名稱為資料夾

而內部會有幾個重要的檔案:

1 Chart.yaml

記載關於 Chart 一些 metadata, 比如說 apiVersion, kubeversion 之類

2 values.yaml

預設的一些 .Value 物件的一些參數值

3 charts 資料夾

有所有跟這個 Chart 有依賴的 chart yaml 檔案

4 templates 資料夾

保存這個 Chart 有用到的範本檔案, 這些範本檔案可以存取 values.yaml 裡面的設定值

5 crds 資料夾

保存可以自訂資源定義檔, 這個在 v2.x.x 版本沒有這個資料夾

6 README.md

關於這個 Chart 的說明檔, 非必要存在

7 LICENSE

關於這個 Chart 的授權聲明檔, 非必要存在

舉 wordpress 這個 chart 為例:

wordpress/
  Chart.yaml          # A YAML file containing information about the chart
  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
  README.md           # OPTIONAL: A human-readable README file
  values.yaml         # The default configuration values for this chart
  values.schema.json  # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
  charts/             # A directory containing any charts upon which this chart depends.
  crds/               # Custom Resource Definitions
  templates/          # A directory of templates that, when combined with values,
                      # will generate valid Kubernetes manifest files.
  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

Helm Save Chart 到 local cache

在 v3.7.0 可以透過以下指令來儲存目前 chart 到 local cache

helm chart save $chart_directory $repo_url_with_chart_name_and_version

Helm Push Chart 到 Repository

在 v3.7.0 可以透過以下指令來把建立好的 chart 推送到 Repository

helm chart push $repo_url_with_chart_name_and_version 

上一篇
IT 鐵人賽 k8s 入門30天 -- day10 K8s Ingress explained
下一篇
IT 鐵人賽 k8s 入門30天 -- day12 Persisting Data in K8s with Volumes
系列文
k8s 入門學習 30天30

尚未有邦友留言

立即登入留言