十分鐘,建立一個Helm chart

在DevOps團隊的平常工做中,總會涉及到建立、修改和部署Helm chart,以用其管理應用程序的部署。Helm是Kubernetes的程序包管理器,它能夠協調應用的下載、安裝和部署。Helm chart能夠將應用程序定義爲相關Kubernetes資源的集合。node


Helm經過模板化的方式讓Kubernetes內部的應用部署管理變得更加簡單。全部的Helm chart都遵循相同的結構,同時又十分靈活,能夠表明你在Kubernetes上運行的任何類型的應用。由於部署需求會隨着時間的推移而改變,Helm還支持版本化。或者使用多個配置文件,將它們手動應用到你的Kubernetes集羣中,把一個應用程序帶起來。若是說咱們能從基礎設施即代碼(IaC)中學到什麼,那就是手動會不可避免地出現錯誤。Helm chart的出現極大程度避免了手動操做,也減小了錯誤發生的機率。nginx


Rancher的應用商店是一個Helm chart的集合,能夠幫助你方便地重複部署應用程序。git


在本例中,咱們將經過使用Helm和minikube,一個Kubernetes的單節點測試環境來進行。咱們將製做一個小型的Nginx Web Server應用。在本例中,我在Linux筆記本電腦上安裝了minikube 1.9.2和Helm 3.0。要開始本次教程,你須要進行如下操做:github


  • 根據文檔下載和配置minikube:web

    https://kubernetes.io/docs/tasks/tools/install-minikube/json


  • 使用如下連接列出的軟件包管理器或手動從release下載和配置Helm:api

    https://github.com/helm/helm#install瀏覽器


圖片

建立一個Helm chart安全


首先確認咱們已經完成了前期準備:網絡


$ which helm ## this can be in any folder as long as it returns in the path/usr/local/bin/helm$ minikube status ## if it shows Stopped, run `minikube start`host: Runningkubelet: Runningapiserver: Runningkubeconfig: Configured


啓動一個新的Helm chart須要一個簡單的命令:


$ helm create mychartname


出於本次教程的目的,將chart命名爲buildachart:


$ helm create buildachartCreating buildachart$ ls buildachart/Chart.yaml   charts/      templates/   values.yaml


圖片

檢查chart的架構


既然你已經建立了chart,那麼如今查看其架構並看看裏面有什麼。首先你須要看2個文件——Chart.yaml和values.yaml,這兩個文件定義了chart是什麼以及在部署中它的values是什麼。


查看Chart.yaml,而且你能夠看到Helm chart的架構輪廓:


apiVersion: v2name: buildachartdescription: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.## Application charts are a collection of templates that can be packaged into versioned archives# to be deployed.## Library charts provide useful utilities or functions for the chart developer. They're included as# a dependency of application charts to inject those utilities and functions into the rendering# pipeline. Library charts do not define any templates and therefore cannot be deployed.type: application
# This is the chart version. This version number should be incremented each time you make changes# to the chart and its templates, including the app version.version: 0.1.0
# This is the version number of the application being deployed. This version number should be# incremented each time you make changes to the application.appVersion: 1.16.0


第一部分包括chart所使用的API版本(這是必須的)、chart的名稱以及chart的描述。接下來的部分描述了chart類型(默認狀況下是一個應用程序)、你將部署的chart版本,以及應用程序的版本(在你進行更改時應該遞增)。


chart中最重要的部分是模板目錄。它保存了你的應用程序的全部配置,這些配置將被部署到集羣中。正如你在下面看到的,這個應用程序有一個基本的deployment、ingress、服務賬戶和服務。這個目錄還包括一個測試目錄,其中包括一個鏈接到應用程序的測試。這些應用程序中的每個功能在templates/下都有本身的模板文件。


$ ls templates/NOTES.txt            _helpers.tpl         deployment.yaml      ingress.yaml         service.yaml         serviceaccount.yaml  tests/


還有另外一個目錄,叫作charts,它是空的。它容許你添加部署應用程序所需的依賴性chart。一些應用的Helm chart有多達四個額外的chart,須要與主要的應用程序一塊兒部署。當這種狀況發生時,value文件將用每一個chart的value進行更新,這樣應用程序將會同時配置和部署。這是更高級的配置(我不會在這篇文章中介紹),因此將 charts/文件夾留空。


理解並編輯values


模板文件的設置格式能夠從values.yaml文件中收集部署信息。所以,要自定義Helm chart,須要編輯values文件。默認狀況下,values.yaml以下所示:


# Default values for buildachart.# This is a YAML-formatted file.# Declare variables to be passed into your templates.
replicaCount: 1
image:  repository: nginx  pullPolicy: IfNotPresent
imagePullSecrets: []nameOverride: ""fullnameOverride: ""
serviceAccount: # Specifies whether a service account should be created  create: true  # Annotations to add to the service account  annotations: {}  # The name of the service account to use.  # If not set and create is true, a name is generated using the fullname template  name:
podSecurityContext: {}  # fsGroup: 2000
securityContext: {}  # capabilities:  #   drop:  #   - ALL  # readOnlyRootFilesystem: true  # runAsNonRoot: true  # runAsUser: 1000
service:  type: ClusterIP  port: 80
ingress:  enabled: false  annotations: {}    # kubernetes.io/ingress.class: nginx    # kubernetes.io/tls-acme: "true"  hosts:    - host: chart-example.local      paths: []  tls: []  #  - secretName: chart-example-tls  #    hosts:  #      - chart-example.local
resources: {}  # We usually recommend not to specify default resources and to leave this as a conscious  # choice for the user. This also increases chances charts run on environments with little  # resources, such as Minikube. If you do want to specify resources, uncomment the following  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.  # limits:  #   cpu: 100m  #   memory: 128Mi  # requests:  #   cpu: 100m  #   memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}


基本配置


從頭開始,你能夠看到replicaCount被自動設置爲1,這意味着只有一個pod會出現。在這個例子中,你只須要一個Pod,但你能夠看到Kubernetes運行多個pod以實現冗餘是多麼容易。


鏡像部分有兩點須要注意:你要拉取鏡像的鏡像倉庫和pullPolicy。pullPolicy設置爲IfNotPresent,這意味着若是集羣中不存在新版本鏡像,那麼鏡像將下載一個新版本的鏡像。還有另外兩個選項:Always,這意味着它將在每次部署或重啓時拉取鏡像(建議在鏡像失敗的狀況下這樣作);Latest,它將始終拉取可用的最新版本的鏡像。若是你認爲你的鏡像倉庫與你的部署環境兼容,最新版本可能會頗有用,但狀況並不是老是如此。


將該值改成Always。


此前:


image:  repository: nginx  pullPolicy: IfNotPresent


以後:


image:  repository: nginx  pullPolicy: Always


命名Secrets


接下來,看一下chart中的覆蓋項。第一個覆蓋是imagePullSecrets,這是一個拉取secret的設置,好比密碼或你生成的API密鑰做爲私有鏡像倉庫的憑證。而後是nameOverride。從你運行helm create的那一刻起,它的名字(buildachart)就被添加到了一些配置文件中——從上面的YAML文件到templates/helper.tpl文件。若是你在建立chart以後須要重命名它,那麼在本部分進行重命名是最好的,這樣你就不會錯過任何配置文件。


使用覆蓋程序更改chart名稱:


以前:


imagePullSecrets: []nameOverride: ""fullnameOverride: ""


更改後:


imagePullSecrets: []nameOverride: "cherry-awesome-app"fullnameOverride: "cherry-chart"


Accounts


Service accounts提供了一個用戶身份,以便在集羣內部的 pod 中運行。若是保留爲空白,則將使用helpers.tpl文件根據全名生成名稱。我建議始終設置一個service account,以便應用程序將直接與chart中控制的用戶相關聯。


做爲一個管理員,若是你使用默認的service account,你的權限要麼太少,要麼太多,因此須要進行更改。


以前:


serviceAccount: # Specifies whether a service account should be created  create: true  # Annotations to add to the service account  annotations: {}  # The name of the service account to use.  # If not set and create is true, a name is generated using the fullname template  Name:


以後:


serviceAccount: # Specifies whether a service account should be created  create: true  # Annotations to add to the service account  annotations: {}  # The name of the service account to use.  # If not set and create is true, a name is generated using the fullname template  Name: cherrybomb


安全


你能夠配置pod安全,以設置限制使用什麼類型的文件系統組或哪一個用戶可使用。理解這些選項對於保障Kubernetes pod的安全很是重要,但在這個例子中,我將不考慮這個問題。


podSecurityContext: {}  # fsGroup: 2000
securityContext: {}  # capabilities:  #   drop:  #   - ALL  # readOnlyRootFilesystem: true  # runAsNonRoot: true  # runAsUser: 1000


網絡


在這個chart中,有兩種不一樣類型的網絡選擇。一種是使用帶有ClusterIP地址的本地服務網絡,它將服務暴露在集羣內部IP上。選擇這個值會使與你的應用程序相關聯的服務只能從集羣內部到達(而且經過ingress,默認設置爲false)。另外一個網絡選項是NodePort,它將服務暴露在每一個Kubernetes節點的IP地址上的靜態分配端口上。這個選項推薦用於運行minikube,因此在本教程中使用它。


以前:


service:  type: ClusterIP  port: 80
ingress:  enabled: false


修改後:


service:  type: NodePort  port: 80
ingress:  enabled: false


資源


Helm容許你顯式分配硬件資源。你能夠配置Helm chart能夠請求的最大資源量和它能夠接收的最高限制。因爲我在筆記本電腦上使用Minikube,我將經過刪除大括號和哈希值(將註釋轉換爲命令)來設置一些限制。


以前:


resources: {}  # We usually recommend not to specify default resources and to leave this as a conscious  # choice for the user. This also increases chances charts run on environments with little  # resources, such as Minikube. If you do want to specify resources, uncomment the following  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.  # limits:  #   cpu: 100m  #   memory: 128Mi  # requests:  #   cpu: 100m  #   memory: 128Mi


以後:


resources: # We usually recommend not to specify default resources and to leave this as a conscious  # choice for the user. This also increases chances charts run on environments with little  # resources, such as Minikube. If you do want to specify resources, uncomment the following  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.   limits:     cpu: 100m     memory: 128Mi   requests:     cpu: 100m     memory: 128Mi


容忍、節點選擇器(node selectors)和親和性


最後這三個值是基於節點配置的。雖然我不能在個人本地配置中使用它們中的任何一個,但我仍然會解釋它們的目的。


nodeSelector在你想將部分應用分配給Kubernetes集羣中的特定節點時很方便。若是你有特定的基礎設施應用,你能夠設置節點選擇器的名稱,並在Helm chart中匹配該名稱。而後,當應用程序被部署時,它將與匹配選擇器的節點相關聯。


容忍、污點和親和性一塊兒工做,以確保pod運行在不一樣的節點上。節點親和性是pod的一個屬性,它將pod吸引到一組節點上(能夠是偏好或硬性要求)。污點是相反的——它們容許一個節點排斥一組pod。


在實踐中,若是一個節點被污染,意味着它不能正常工做,或者可能沒有足夠的資源來保持應用部署。容忍度被設置爲scheduler監控的鍵/值對,以確認一個節點將與部署一塊兒工做。


節點親和性在概念上與nodeSelector相似:它容許你根據節點上的標籤來限制pod能夠調度哪些節點。然而,標籤之因此不一樣,是由於它們與適用於調度的規則相匹配。


nodeSelector: {}
tolerations: []
affinity: {}


圖片

部署完成!


如今你已經對建立Helm chart進行了必要的修改,你可使用Helm命令部署它,爲chart添加一個名稱點,添加一個值文件,並將其發送到一個命名空間:


$ helm install my-cherry-chart buildachart/ --values buildachart/values.yamlRelease 「my-cherry-chart」 has been upgraded. Happy Helming!


該命令的輸出將爲你提供鏈接到應用程序的下一個步驟,包括設置端口轉發,這樣你就能夠從你的本地主機到達應用程序。按照這些說明,鏈接到Nginx負載均衡器。


$ export POD_NAME=$(kubectl get pods -l "app.kubernetes.io/name=buildachart,app.kubernetes.io/instance=my-cherry-chart" -o jsonpath="{.items[0].metadata.name}")$ echo "Visit http://127.0.0.1:8080 to use your application"Visit http://127.0.0.1:8080 to use your application$ kubectl port-forward $POD_NAME 8080:80Forwarding from 127.0.0.1:8080 -> 80Forwarding from [::1]:8080 -> 80


圖片

查看已經部署的應用程序


你須要打開瀏覽器纔可以查看應用程序:


圖片


Congratulations!你已經經過Helm chart部署了一個Nginx web server!


當你探索Helm chart還有許多細節須要瞭解,若是你想double check你的工做,歡迎訪問個人Github repo:

https://github.com/Alynder/build_a_chart

相關文章
相關標籤/搜索