ASP.NET Core on K8S深入學習(10)K8S包管理器Helm


本篇已加入《.NET Core on K8S學習實踐系列文章索引》,可以點擊查看更多容器化技術相關系列文章。

一、關於Helm

1.1 為何需要Helm?

  雖然K8S能夠很好地組織和編排容器,但是缺少一個更高層次的應用打包工具,而Helm就是專門干這個事的。

  通過Helm能夠幫助開發者定義、安裝和升級Kubernetes中的容器雲應用。同時,也可以通過Helm進行容器雲應用的分享。

1.2 Helm的架構

  Helm的整體架構如下圖(圖片來源-Kubernetes中文社區)所示:

  

  Helm架構由Helm客戶端、Tiller服務器端和Chart倉庫所組成;

兩個重要概念:

(1)Chart是創建一個應用的信息集合,包括各種K8S對象的配置模板、參數定義等,可以理解為是apt、yum中的軟件安裝包;

(2)Release是Chart的運行實例,代表了一個正在運行的應用。

  Tiller部署在Kubernetes中,Helm客戶端從Chart倉庫中獲取Chart安裝包,並通過與Tiller服務器的交互將其安裝部署到Kubernetes集群中。

  簡單說來,Helm客戶端負責管理Chart,而 Tiller服務器則負責管理Release。 

二、Helm的安裝和使用

2.1 Helm客戶端的安裝

  執行以下命令將Helm客戶端安裝在能夠執行kubectl命令的節點上,這里假設我們安裝在k8s-master節點上進行示例演示:

curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash

  也可以通過下面的方式安裝:

wget https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz
tar -zxvf helm-v2.11.0-linux-amd64.tar.gz
cd linux-amd64/
cp helm /usr/local/bin/

  驗證:查看helm版本

helm version

  

  補充:為了提高使用命令行的效率,建議安裝helm命令補全腳本,命令如下:

cd ~ && helm completion bash > .helmrc echo "source .helmrc" >> .bashrc

  重新登錄后,就可以方便地通過tab鍵來補全helm子命令和參數了,如下圖所示,當我們輸入helm install --之后按下Tab鍵,就會給我們參數提示了:

  

2.2 Tiller服務器的安裝

  Tiller服務器本身也是作為容器化的一個應用運行在K8S集群中,這里我們簡單執行下面的命令即可安裝Tiller服務:

helm init

  執行以上命令,會如下圖所示:

  

   看到上圖中的提示信息,代表Helm服務端已經安裝成功。

   這時,我們可以看看Tiller的Service、Deployment和Pod有沒有啟動起來:

  (1)Service & Deployment

  

   (2)Pod

  

  如果看到其Status不是Running,那么很有可能是鏡像沒有拉取下來,可以曲線救國:即下載可訪問的鏡像然后修改Tag!

docker pull fishead/gcr.io.kubernetes-helm.tiller:v2.11.0
docker tag fishead/gcr.io.kubernetes-helm.tiller:v2.11.0 gcr.io/kubernetes-helm/tiller:v2.11.0

   這時再次通過helm version命令驗證一下:

  

   可以看到,我們已經可以成功看到客戶端和服務端的版本信息了,證明客戶端和服務端(Pod)都已經安裝成功了!

2.3 Helm的使用准備

  Helm安裝好后,我們可以通過以下helm search來查看當前可安裝的Chart:

  

Note:Helm安裝時會為我們配置好兩個倉庫,一個是stable官方倉庫,另一個是local本地倉庫,上圖中顯示的都是stable官方倉庫中的Chart。  

   為了能夠執行install安裝,我們還需要事先為Tiller服務器添加集群權限,防止因Tiller服務器的權限不足而無法install。

# 創建serviceaccount資源tiller,屬於kube-system命名空間
kubectl create serviceaccount -n kube-system tiller
# 創建 clusterrolebinding資源tiller-cluster-rule,集群角色為cluster-admin,用戶為kube-system:tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
# 修改deployment tiller-deploy的配置,增加字段spec.template.spec.serviceAccount
kubectl patch deploy -n kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

  

   至此,使用Helm的准備工作就到此結束,后面我們就可以開始實踐安裝Chart了!

三、MySQL Chart實踐

3.1 初步安裝MySQL Chart

  這里我們通過以下命令來通過官方倉庫安裝mysql:

helm install stable/mysql -n=edc-mysql --namespace=edc-charts

  其中,-n 代表 release的名字,--namespace 指定了其所在namespace。

  執行成功之后,會顯示一屏幕的提示信息,其中Notes部分包含了release的使用方法,可以重點關注一下。

  這里我們通過以下命令來看看已經部署的release:

helm list

  

   可以看到,該release的狀態已經是DEPLOYED,也可以看到其版本號是5.7.27。

  下面再看看service、deployment、pod以及pvc的情況:

  

  

   從上圖可以看到,由於還沒有位mysql准備PV(PersistentVolume,不了解此概念的童鞋可以參考這一篇《K8S數據管理》),導致當前release不可用,處於Pending狀態。接下來我們就要先解決PV的問題,讓release能夠正常運行起來!在此之前,為了后續方便演示,這里現將此chart刪除:

helm delete edc-mysql

3.2 為MySQL Chart准備PV

  首先,按照約定准備一個edc-mysql-pv.yml,如下所示:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: edc-mysql-pv
spec:
  capacity:
    storage: 8Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  #storageClassName: nfs
  nfs:
    path: /edc/k8s/nfsdata/edc-mysql-pv
    server: k8s-master

  這里申請了一個8G的PV,用於適配mysql chart的默認配置要求,當然我們也可以通過修改自定義values.yaml來修改。

3.3 定制化安裝MySQL Chart

  Helm有兩種方式傳遞配置參數實現定制化安裝,一種是指定自定義的values文件,另一種是通過--set直接傳入參數值。這里我們演示通過第二種,這里我們重新安裝mysql chart:

helm install stable/mysql -namespace=edc-charts --set mysqlRootPassword=edc123456 -n edison

  驗證結果如下圖所示:

  

3.4 升級和回滾Release

  這里假設我安裝的版本是5.7.14,這里我將其先升級為5.7.26來演示:

helm upgrade --set imageTag=5.7.26 edison stable/mysql

  通過查看可以看到image已經換為了5.7.26:

  

   通過helm history可以查看release的所有歷史版本:

  

   Note:這里Revision 1是5.7.14版本,Revision 2是5.7.26版本,Revision 3是5.7.27版本。

   這里我們通過helm rollback回退到Revision 1版本(即5.7.14版本),可以看到已經成功回退到了5.7.14版本:

   

四、自定義Chart實踐

4.1 創建Chart

  首先,通過以下命令創建一個chart命名為mychart:

helm create mychart

  Helm會幫我們創建目錄mychart,並生成各種chart文件。

  

  這里我們需要關注的是values.yaml,修改其中的內容為我們之前演示的ASP.NET Core WebAPI應用鏡像:

# Default values for mychart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: edisonsaonian/k8s-demo
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: NodePort
  port: 80
  nodePort: 31000

ingress:
  enabled: false

resources:
  limits:
    cpu: 1
    memory: 228Mi
  requests:
    cpu: 100m
    memory: 128Mi

  這里我們選擇NodePort的方式讓外部可以通過31000端口訪問到API,也設置了資源限制。

  此外,我們再修改一下Templates目錄下的deployment和service兩個模板文件:

  (1)deployment模板:重點關注兩個探針的配置

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    helm.sh/chart: {{ include "mychart.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "mychart.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "mychart.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          # 探針 檢測項目是否存活
          livenessProbe:
            httpGet:
              path: /api/values
              port: http
          # 探針 檢測項目是否啟動成功
          readinessProbe:
            httpGet:
              path: /api/values
              port: http
            initialDelaySeconds: 30 periodSeconds: 60
          resources:
{{ toYaml .Values.resources | indent 12 }}
    {{- with .Values.nodeSelector }}
      nodeSelector:
{{ toYaml . | indent 8 }}
    {{- end }}
    {{- with .Values.affinity }}
      affinity:
{{ toYaml . | indent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
{{ toYaml . | indent 8 }}
    {{- end }}

  (2)service模板:重點關注NodePort的配置

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    helm.sh/chart: {{ include "mychart.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      # 添加nodePort
      nodePort: {{ .Values.service.nodePort }}
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}

   編寫完成后,通過 helm lint 可以幫助我們快速驗證是否有語法錯誤:

  

4.2 安裝Chart

  沒有語法錯誤檢測之后,便可以開始安裝Chart了,正式安裝之前我們可以通過以下命令來模擬安裝,它會輸出每個模板生成的yaml內容,幫助你檢查生成的yaml內容是否是你想要的或者正確的。

helm install --dry-run --debug

  然后,這里我們選擇本地安裝Chart:

helm install mychart -n edc-api-release --namespace=aspnetcore

  只需要簡單的一句話,就可以將chart部署到K8S集群中了,下面我們通過在外部訪問NodePort 31000端口來驗證一下是否部署成功:

  (1)Node 1

  

  (2)Node 2

   

   兩個Node節點都可以訪問到,證明部署成功!

4.3 添加Chart到倉庫

  通過測試之后,我們的Chart就可以發布到倉庫中供團隊成員使用了,像阿里雲、騰訊雲等雲服務商都已經提供了完善的Helm遠程倉庫,我們也可以自己搭建一個倉庫,任何的Web Server其實都可以作為一個chart倉庫。

  下面我們在k8s-master上啟動給一個httpd容器,讓它來作為我們的本地chart倉庫。

docker run -d -p 8080:80 -v /var/www:/usr/local/apache2/htdocs/ httpd

  然后,我們將mychart進行打包,helm會將其打包為一個tgz包:

helm package mychart

  然后,我們為mychart包生成倉庫的index文件,並將其推送到本地chart倉庫中:

mkdir myrepo
mv mychart-0.1.0.tgz myrepo/
helm repo index myrepo/ --url http://192.168.2.100:8080/charts

  這里我們將httpd容器中的charts目錄作為chart倉庫,因此需要提前創建charts目錄,並將打好的包和index.yaml文件也上傳到該目錄中:

  

  最后,我們將新倉庫添加到helm:

helm repo add edc-repo http://192.168.2.100:8080/charts
helm repo list

  

   可以看到,edc-repo已經添加到了helm中,代表可以從新的本地倉庫中下載和安裝mychart了!

4.4 使用自定義Chart

  現在我們來從本地的新倉庫中下載和安裝mychart:

helm install edc-repo/mychart -n mychart-release --namespace=aspnetcore

  安裝完成后再次驗證:

  (1)Node 1

  

  (2)Node 2

   

  如果以后倉庫添加了新的chart,需要使用以下命令來更新本地的index文件:

helm repo update

五、小結

   本文介紹了K8S的包管理器Helm的基本概念與安裝和使用,Helm能夠幫助我們像使用apt或yum那樣管理安裝、部署、升級和刪除容器化應用,最后演示了如何為我們的ASP.NET Core API應用開發自己的chart,並在團隊中共享chart。當然,關於Helm,筆者也是初學,還有很多地方沒有研究,希望此文能給初學者一點幫助,謝謝!

參考資料

(1)CloudMan,《每天5分鍾玩轉Kubernetes

(2)李振良,《一天入門Kubernets教程

(3)馬哥(馬永亮),《Kubernetes快速入門

(4)潘猛,《Kubernetes筆記之Helm

(5)雪雁(心萊科技),《利用Helm簡化Kubernetes應用部署(二)

(6)周國通,《Kubernetes實戰篇之Helm填坑與基本命令

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM