上一篇文章 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日,字节跳动-胡贤彬《自动化测试,如何做到「攻防兼备」?》