在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