上一篇文章 Kubernetes上利用部署之三步曲 中提到了一句话 Kubernetes上所有皆资源,咱们通过创立pods(deployment),service,ingress三种资源实现了 HelloDevOps利用的部署,一个简略的利用就有了三个yaml文件,然而实在实际中,利用(微服务利用)必定不止一个,这样下来,就会有十多个,甚至几十个yaml文件,如果每次部署都用 kubectl 来对相应的资源进行增(create),删(delete),改(edit),查(get),那么这种治理形式无疑是复杂多变甚至是劫难的,在这种状况下,Kubernetes提供了Helm来让整个流程变得简略起来。
Helm 介绍
正如官网所说, Helm is the packagemanager for Kubernetes and Helm is the best way to find,share,and use software built for Kubernetes. 顾名思义,Helm 是kubernetes的包管理器,就像apt-get 与之Ubuntu和yum与之Redhat和Centos。
Helm 基本原理
Helm 是C/S模型,总共有两局部组成: Helm客户端(Helm)和服务器端(Tiller,以2.x版本为例,3.x剔除了tiller)。Helm 客户端是一个CLI,而Tiller是以deployment模式部署在Kubernetes平台的kube-system namespace下。
其中Helm承受来自于用户对于Helm Charts 所生成的Release的增(helm install)、删(helm delete)、改(helm upgrade)、查(helm ls);Tiller次要用来与Kubernetes API server进行交互(因为对于Kubernetes来说,所有申请的入口都是API server),从而实现对于Kubernetes资源的增、删、改、查,另外Tiller还能够对于曾经创立好的Release进行存储与治理。
当用户须要用某一个chart来通过install形式生成一个Release的时候,Helm客户端承受这个install申请,并将申请发个Tiller服务端,Tiller服务端会将chart中的相干文件依据values.yaml中定义的值或者来自于--set前面指定的参数来进行渲染,而后将渲染好的文件发给Kubernetes API server生成相应的资源,最终实现一个Release的创立。
Helm 装置
因为Helm有客户端与服务端两局部组成,所以装置分两步走。
第一步:Helm 客户端的装置
Helm客户端有源码和二进制码两种装置形式,本文采纳二进制进行装置(二进制装置比拟不便,所以集体举荐用二进制进行装置)。首先在Helm 客户端Release的github页面中,找到与本人OS想匹配的版本进行下载,将下载文件进行解压并将解压之后的二进制文件helm拷贝至指标门路(比方/usr/local/bin/helm),能够用helm help命令来验证helm 客户端是否装置胜利。
第二步:创立Service Account
因为在Kubernetes中,对于资源的管制权限是通过RBAC(Role-Based Access Control)来实现的, 而Tiller是在kube-system namespace下的,然而由Tiller治理的Release 是在别的namespace上面的,这种状况下须要给Tiller创立一个相应权限的Service Account,这个Service Account和cluster-admin这个ClusterRole进行绑定,这样确保Tiller可能对于整个cluster各个namespace上面的资源进行list,delete,update等操作。
apiVersion: v1kind: ServiceAccountmetadata: name: tiller namespace: kube-system---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: tillerroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-adminsubjects: - kind: ServiceAccount name: tiller namespace: kube-system
创立完service account,能够在kube-system ns上面查看service account的具体信息
$ kubectl -n kube-system get sa | grep tillertiller 1 115d
第三步:Helm 服务端的装置
借助于上一步生成的Service Account(tiller),能够执行 helm init --service-account tiller 命令来实现 Tiller 服务端的装置。这个过程会先对helm本地环境进行有效性验证,而后会与Kubernetes cluster的kubectl进行连贯,如果连贯胜利 ,会在kube-system namespace局势下部署一个与tiller相干的deployment。能够在 kube-system namespace上面进行查看。
$kubectl -n kube-system get deploy,pods | grep tillerdeployment.extensions/tiller-deploy 1 1 1 1 115dpod/tiller-deploy-6f6fd74b68-tzhcv 1/1 Running 0 2d21h
执行 helm version
$ helm versionClient: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}Server: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}
至此,helm 客户端和服务端都装置实现。上面咱们就能够用helm来部署上篇文章中的利用了,部署之前先要讲几个与Helm相干的概念。
Helm的一些基本概念
Chart
部署一个利用所须要的一个包,这个包是由可能形容kubernetes 相干资源(deploy, service, ingress 等等)的一系列文件组成 ,通过这些文件,能够在kubernetes上创立相干资源
Release
由Helm Chart所创立生成的一个实例(个别状况下就是部署了一个微服务利用)
Repoistory
寄存Helm charts的仓库,和Docker Registry Repository一样,用来寄存helm chart包。比方Jfrog Artifactory。
Helm 部署利用
首先,咱们用 helm create devops命令创立一个名为devops的chart,查看一下蕴含的文件有哪些
$ tree devopsdevops/├── Chart.yaml├── charts├── templates│ ├── NOTES.txt│ ├── _helpers.tpl│ ├── deployment.yaml│ ├── ingress.yaml│ └── service.yaml└── values.yaml
先简略的介绍一下下面呈现的一些文件的作用
Chart.yaml
此文件次要用来形容此chart的信息,包含版本号,维护者的信息等。
charts
这是个目录,外面次要寄存此chart所依赖的一些chart包。
templates
这是一个目录,外面蕴含chart的重点内容,能够看到有 deployment.yaml,ingress.yaml,service.yaml
,这三个文件(chart创立进去之后,默认只有这三种资源的定义文件,然而这并不代表只能有这三个文件,如果部署利用的过程中用到了secret,configmap等相干资源,也能够写在这个目录下,这也是就看进去了,文件越来越多的时候 helm 的方便快捷就能体现进去了)形容的就是与pod(deployment),ingress,service 等kubernetes资源相干的信息。
_helpers.tpl
这是个模版文件,用来定义用于一些模版语言。
value.yaml
这是最初也是要着重要介绍的一个文件。在介绍这个文件之前,咱们先看一下,service.yaml文件中的内容有什么,这样能帮咱们更好的了解 values.yaml
文件。
$ cat service.yamlapiVersion: v1kind: Servicemetadata: name: {{ include "devops.fullname" . }} labels: app: {{ .Release.Name }}spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: app: {{ .Release.Name }}
能够看到下面有很多用 "{{}}"括起来的内容,这是Helm Chart中定义的变量。Helm Chart的书写用到了Go Template Language。 Package Template次要实现了一些数据驱动模块,这些数据模块能够用来生成一些文本输入。而对于Template 最直观的了解能够这么了解
这些括弧外面的内容能够了解为 "形参",而"实参"的值就是来自于 values.yaml 文件,其实如果一一关上chart目录下的其余文件,比方 deployment.yaml, ingress.yaml关上之后都会看到与 service.yaml类似的状况。所以 values.yaml文件的重要性就体现进去了,部署进去的deployment,ingress ,service是什么样的,齐全取决于在 values.yaml文件中是怎么样定义的。
而且helm chart的另外一个便当之处就是,一个chart能够部署多个Release,而这多个Release又能够对应多个不同的环境,比方dev环境,svt环境,prod环境,这种变动须要的仅仅是一个 values.yaml 文件,比方将dev环境相干的信息,写在一个 values-dev.yaml的文件中,那么创立进去的Release所对应的环境就是dev环境,svt和prod都能够用同样的形式创立进去。 这些用"{{}}"括起来的变量中,有几个全局的变量,须要关注一下:
.Chart.Name
示意chart的name,比方下面用helm create devops创立了devops 这个chart,则.Chart.Name的值就是devops。
.Release.Name
示意由chart创立的Release的name,比方用上述的devops chart通过install命令生成了一个hello-devops的Release,则.Release.Name的值就是hello-devops。
.Release.Namespace
由chart创立的Release所在的namespace,比方用上述的devops chart在devops namespace上面创立的hello-devops Release,则 .Release.Namespace的值就是devops。 咱们将上一篇文章中deployment,yaml,service.yaml,ingress.yaml文件中的"实参"内容写入到 values.yaml 文件中
$ cat values.yamlreplicaCount: 1env: running_env: dev name: devops client: helm server: tiller version: v1image: repository: dllhb/go_test tag: v1.3 pullPolicy: IfNotPresentservice: type: ClusterIP port: 80ingress: enabled: true annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "true" path: / hosts: - devops.test.com tls: - secretName: devops-tls hosts: - devops.test.comresources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mi
deployment.yaml
文件的内容如下
$ cat templates/deployment.yamlapiVersion: apps/v1beta2kind: Deploymentmetadata: name: {{ .Release.Name }} labels: app: {{ .Release.Name }}spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: {{ .Release.Name }} template: metadata: labels: app: {{ .Release.Name }} version: non-canary spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 9999 protocol: TCP env: {{- include "devops.env" . | nindent 12}}
service.yaml 文件内容如下
$ cat templates/service.yamlapiVersion: v1kind: Servicemetadata: name: {{ include "devops.fullname" . }} labels: app: {{ .Release.Name }}spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: app: {{ .Release.Name }}
ingress.yaml 文件内容如下
$ cat templates/ingress.yaml{{- if .Values.ingress.enabled -}}{{- $fullName := include "devops.fullname" . -}}{{- $ingressPath := .Values.ingress.path -}}apiVersion: extensions/v1beta1kind: Ingressmetadata: name: {{ $fullName }} labels: app.kubernetes.io/instance: {{ .Release.Name }}{{- with .Values.ingress.annotations }} annotations:{{ toYaml . | indent 4 }}{{- end }}spec:{{- if .Values.ingress.tls }} tls: {{- range .Values.ingress.tls }} - hosts: {{- range .hosts }} - {{ . | quote }} {{- end }} secretName: {{ .secretName }} {{- end }}{{- end }} rules: {{- range .Values.ingress.hosts }} - host: {{ . | quote }} http: paths: - path: {{ $ingressPath }} backend: serviceName: {{ $fullName }} servicePort: http {{- end }}{{- end }}
上面就能够进入到devops目录下用 helm install 来进行利用装置,
$ helm install . --name devops --namespace devops -f values.yamlNAME: devopsLAST DEPLOYED: Sun Aug 4 16:21:03 2019NAMESPACE: devopsSTATUS: DEPLOYEDRESOURCES:==> v1/ServiceNAME AGEdevops 4s==> v1beta2/Deploymentdevops 4s==> v1beta1/Ingressdevops 4s==> v1/Pod(related)NAME READY STATUS RESTARTS AGEdevops-5f499c48b4-rzldr 1/1 Running 0 4sNOTES:1. Get the application URL by running these commands: https://devops.test.com/
查看pod,service,ingress资源
$ kubectl -n devops get pods,svc,ingNAME READY STATUS RESTARTS AGEpod/hello-devops-78dd67d9cc-jpx2z 1/1 Running 0 2d22hNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/hello-devops-svc ClusterIP 172.21.246.13 <none> 8888/TCP 14dNAME HOSTS ADDRESS PORTS AGEingress.extensions/hello-devops-ingress devops.test.com 10.208.70.22 80, 443 14d
而后就能够用 https://devops.test.com 来拜访应用程序了
$ curl -k -s https://devops.test.comHello DevOps, pod name is hello-devops-78dd67d9cc-jpx2z
此外,能够用 helm ls 查看曾经部署了的Release
$ helm ls | grep devopsdevops 1 Thu Jun 6 10:13:02 2019 DEPLOYED devops-0.1.0 1.0 devops
如果要删除曾经装置了的Release,能够执行 helmdeletedevops--purge
$ helm delete devops --purgerelease "devops" deleted
起源:DevSecOps SIG
作者:小马哥
申明:文章取得作者受权在IDCF社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。
7月每周四晚8点,【冬哥有话说】研发效力工具专场,公众号留言“研发效力”可获取地址
- 7月8日,前微软-周文洋《微软DevOps工具链的 "爱恨情仇"(Azure DevOps)》
- 7月15日,阿里云-陈逊《复杂型研发合作模式下的效力晋升实际》
- 7月22日,极狐(GitLab)-张扬《基础设施即代码的⾃动化测试摸索》
- 7月29日,字节跳动-胡贤彬《自动化测试,如何做到「攻防兼备」?》