k8s 通過helm釋出應用

iqsing發表於2022-02-14

什麼是helm?


Helm 是 Kubernetes 的包管理器。Helm 是查詢、分享和使用軟體構建 Kubernetes 的最優方式。

在紅帽系的Linux中我們使用yum來管理RPM包,類似的,在K8s中我們可以使用helm來管理資源物件(Deployment、Service、Ingress...)實現K8s中應用的快速釋出、升級、維護和分享。helm官方文件

helm中的幾個關鍵概念


  • Chart 是Helm 中的包。包含一組用於部署應用程式的 K8s 資源物件定義(即資源清單的集合)。
  • Repository 即chart圖表的倉庫。我們可以從網路倉庫中搜尋、下載和安裝chart。
  • Release 即chart部署後的例項。通過helm install命令,在 Kubernetes 叢集上安裝該chart的新版本。

helm實現哪些功能?


Helm (v3版本)為 K8s 提供的功能包括:

  1. 通過單個 CLI 命令部署 Kubernetes 應用(chart)。實現本地chart的建立、管理和釋出。
  2. Helm 將chart中資源物件配置檔案模板化,實現在多個叢集環境中重用一個 Helm chart,同時可打包進行網路共享。
  3. Helm 通過自動維護髮布的所有版本來簡化 Kubernetes 應用程式的回滾,防止部署問題。
  4. 通過helm輕鬆實現 Kubernetes 中工作負載的 CI/CD 管道。

helm 基本使用


Helm可以用原始碼或構建的二進位制版本安裝。參考:安裝Helm

Artifact Hub 是一個開源專案,我們通過它來查詢、安裝或釋出k8s應用。image-20220213193213721

除了通過web搜尋,也可以通過helm命令列方式:

#helm search hub redis
URL                                               	CHART VERSION	APP VERSION     	DESCRIPTION
https://hub.helm.sh/charts/bitnami/redis          	16.4.0       	6.2.6           	Redis(TM) is an opensource, advanced key-value...
https://hub.helm.sh/charts/wenerme/redis          	16.4.0       	6.2.6           	Redis(TM) is an opensource, advanced key-value...
...

找到redis版本為6.2.6,chart版本16.4.0的包,訪問 url https://hub.helm.sh/charts/bitnami/redis 新版本已被重定向到artifacthub.io

image-20220213195117548

由圖上資訊可以知redis是一個來自Bitnami倉庫(由VMware主導的開源軟體倉庫),通過驗證的版本,倉庫地址https://charts.bitnami.com/bitnami

要安裝這個應用我們應先將Bitnami倉庫新增到本地配置中。

#helm repo add bitnami https://charts.bitnami.com/bitnami

安裝redis,release名稱為redis-dev

# helm install redis-dev bitnami/redis
NAME: redis-dev
LAST DEPLOYED: Sun Feb 13 20:09:30 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: redis
CHART VERSION: 16.4.0
APP VERSION: 6.2.6

這樣我們可以輕鬆釋出一個一主三從的redis叢集到k8s中

# helm list
NAME                           	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART 	APP VERSION
redis-dev                      	default  	1       	2022-02-13 20:09:30.755534484 +0800 CST	deployed	redis-16.4.0

Helm 通過向資源物件中新增標籤來跟蹤安裝在 Kubernetes 叢集上的chart。這些標籤看起來像app.kubernetes.io/managed-by=Helmapp.kubernetes.io/instance: myapp

#  kubectl get all -l app.kubernetes.io/instance=redis-dev
NAME                       READY   STATUS    RESTARTS   AGE
pod/redis-dev-master-0     1/1     Running   0          27m
pod/redis-dev-replicas-0   1/1     Running   0          27m
pod/redis-dev-replicas-1   1/1     Running   0          24m
pod/redis-dev-replicas-2   1/1     Running   0          23m

NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/redis-dev-headless   ClusterIP   None            <none>        6379/TCP   27m
service/redis-dev-master     ClusterIP   10.96.52.104    <none>        6379/TCP   27m
service/redis-dev-replicas   ClusterIP   10.96.230.162   <none>        6379/TCP   27m

NAME                                  READY   AGE
statefulset.apps/redis-dev-master     1/1     27m
statefulset.apps/redis-dev-replicas   3/3     27m

刪除redis-dev的釋出,將會移除標籤跟蹤的所有資源物件。

# helm uninstall redis-dev
release "redis-dev" uninstalled

建立自己的helm chart


顯然大多數時候我們更想釋出自己的應用到K8s中或者需要對將要釋出的開源軟體做一些配置上的修改,所以我們可以通過helm自己構建一個chart或者使用helm pull下載一個chart做修改後再上傳的內部或外部倉庫中。

下面來建立一個簡易的nginx chart

# helm create chart-nginx
Creating chart-nginx

chart的目錄結構,你可以刪除模板中的所有檔案自建或使用預設模板

# tree chart-nginx/
chart-nginx/
├── charts  #依賴的chart目錄
├── Chart.yaml #chart版本資訊
├── templates #資源物件模板目錄
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt #提示資訊
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml #模板值

3 directories, 10 files

Chart.yaml宣告瞭版本資訊,我們可以進行自定義

# Chart.yaml
apiVersion: v2
name: chart-nginx
description: A Helm chart for Kubernetes
type: application
version: 0.1.0 #chart版本
appVersion: 1.0.0 #app版本

helm預設建立的模板檔案deployment.yaml如下:

image-20220213233227742

helm 採用go模板,官方文件Chart模板

通過deployment模板中可以看到image的值會引用value檔案中定義的image.repository和tag,如果tag值為空則返回預設引用Chart.appVersion的值。

接著根據需要更新value.yaml檔案中imageservice等相關資訊,同時關閉serviceAccount、ingress、hpa的建立。

image-20220214001633434

模板檔案service.yaml定義好了type和pod的引用。

image-20220214001344997

一個基本的nginx chart建立好了。通過helm template 命令渲染模板檢視一下

# helm template chart-nginx
---
# Source: chart-nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: RELEASE-NAME-chart-nginx
  labels:
    helm.sh/chart: chart-nginx-0.1.0
    app.kubernetes.io/name: chart-nginx
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: chart-nginx
    app.kubernetes.io/instance: RELEASE-NAME
---
# Source: chart-nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: RELEASE-NAME-chart-nginx
  labels:
    helm.sh/chart: chart-nginx-0.1.0
    app.kubernetes.io/name: chart-nginx
...

再通過helm lint檢查語法

==> Linting chart-nginx
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

ok,通過helm install釋出到k8s,參照NOTES說明可進行訪問。

# helm install chart-nginx --generate-name
NAME: chart-nginx-1644771770
LAST DEPLOYED: Mon Feb 14 01:02:50 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services chart-nginx-1644771770)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

檢視資源正常。

# kubectl get all -l app.kubernetes.io/name=chart-nginx
NAME                                          READY   STATUS    RESTARTS   AGE
pod/chart-nginx-1644771770-69bbb4fdf8-gqdk7   1/1     Running   0          3m59s
pod/chart-nginx-1644771770-69bbb4fdf8-wwxw2   1/1     Running   0          3m59s

NAME                             TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/chart-nginx-1644771770   NodePort   10.96.231.61   <none>        80:32631/TCP   3m59s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/chart-nginx-1644771770   2/2     2            2           3m59s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/chart-nginx-1644771770-69bbb4fdf8   2         2         2       3m59s

通過倉庫分發應用


首先通過helm packge將chart-nginx打包

# helm package chart-nginx
Successfully packaged chart and saved it to: .../../chart-nginx-0.1.0.tgz

建立chart私有倉庫,可參考開源專案chartmuseum,如有必要你也可將倉庫提交至artifacthub釋出到網際網路。

chart-nginx-0.1.0.tgz上傳至倉庫後,通過curl列出chart資訊如下:

# curl http://192.168.1.123:8088/api/charts |python -m json.tool
{
    "chart-nginx": [
        {
            "apiVersion": "v2",
            "appVersion": "1.0.0",
            "created": "2022-02-13T17:37:43.653117345Z",
            "description": "A Helm chart for Kubernetes",
            "digest": "58a687be62a2a2a2b1dd177675bbc5aa49ac754df2219149bb4798636662b57c",
            "name": "chart-nginx",
            "type": "application",
            "urls": [
                "charts/chart-nginx-0.1.0.tgz"
            ],
            "version": "0.1.0"
        }
    ]
}

將倉庫新增到你的其他k8s叢集helm中,實現應用共享和釋出。

# helm repo add chartmuseum http://192.168.1.123:8088
"chartmuseum" has been added to your repositories

搜尋chart-nginx

# helm search repo chart-nginx
NAME                   	CHART VERSION	APP VERSION	DESCRIPTION
chartmuseum/chart-nginx	0.1.0        	1.0.0      	A Helm chart for Kubernetes

通過倉庫釋出chart-nginx

# helm install my-chart-nginx chartmuseum/chart-nginx
NAME: my-chart-nginx
LAST DEPLOYED: Mon Feb 14 01:54:34 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
...

以上我們對helm進行了基本介紹以及如何建立一個自己的helm chart,如何結合私有倉庫chartmuseum在K8s中釋出應用。

希望小作文對你有些許幫助,如果內容有誤請指正。通過部落格閱讀:iqsing.github.io

相關文章