关于kubernetes:Kubernetes上应用部署利器之Helm-IDCF

48次阅读

共计 8082 个字符,预计需要花费 21 分钟才能阅读完成。

上一篇文章 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: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - 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 tiller
deployment.extensions/tiller-deploy   1         1         1            1      115d
pod/tiller-deploy-6f6fd74b68-tzhcv    1/1       Running
   0          2d21h

执行 helm version

$ helm version
Client: &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 devops
devops/
├── 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.yaml
apiVersion: v1
kind: Service
metadata:
  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.yaml
replicaCount: 1

env:
  running_env: dev
  name: devops
  client: helm
  server: tiller
  version: v1

image:
  repository: dllhb/go_test
  tag: v1.3
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
  path: /
  hosts:
    - devops.test.com
  tls:
    - secretName: devops-tls
      hosts:
        - devops.test.com

resources:
   limits:
    cpu: 100m
    memory: 128Mi
   requests:
    cpu: 100m
    memory: 128Mi

deployment.yaml 文件的内容如下

$ cat templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  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.yaml
apiVersion: v1
kind: Service
metadata:
  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/v1beta1
kind: Ingress
metadata:
  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.yaml
NAME:   devops
LAST DEPLOYED: Sun Aug  4 16:21:03 2019
NAMESPACE: devops
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME    AGE
devops  4s

==> v1beta2/Deployment
devops  4s

==> v1beta1/Ingress
devops  4s

==> v1/Pod(related)

NAME                     READY  STATUS   RESTARTS  AGE
devops-5f499c48b4-rzldr  1/1    Running  0         4s


NOTES:
1. Get the application URL by running these commands:
  https://devops.test.com/

查看 pod,service,ingress 资源

$ kubectl -n devops get pods,svc,ing
NAME                                READY     STATUS    RESTARTS   AGE
pod/hello-devops-78dd67d9cc-jpx2z   1/1       Running   0          2d22h

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP  
PORT(S)    AGE
service/hello-devops-svc   ClusterIP   172.21.246.13   <none>        8888/TCP   14d

NAME                                      
 HOSTS                                                                  
                           ADDRESS   
   PORTS     AGE
ingress.extensions/hello-devops-ingress   devops.test.com   10.208.70.22   80, 443   14d

而后就能够用 https://devops.test.com 来拜访应用程序了

$ curl -k -s https://devops.test.com
Hello DevOps, pod name is hello-devops-78dd67d9cc-jpx2z

此外,能够用 helm ls 查看曾经部署了的 Release

$ helm ls | grep devops
devops         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 日,字节跳动 - 胡贤彬《自动化测试,如何做到「攻防兼备」?》

正文完
 0