在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