zoukankan      html  css  js  c++  java
  • Kubernetes之(二十)Helm程序包管理器

    Kubernetes之(二十)Helm程序包管理器

    概念

    每个成功的软件平台都有一个优秀的打包系统,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。
    Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。
    举个例子,我们需要部署一个MySQL服务,Kubernetes则需要部署以下对象:
    ① 为了能够让外界访问到MySQL,需要部署一个mysql的service;
    ②需要进行定义MySQL的密码,则需要部署一个Secret;
    ③Mysql的运行需要持久化的数据存储,此时还需要部署PVC;
    ④保证后端mysql的运行,还需要部署一个Deployment,以支持以上的对象。
    针对以上对象,我们可以使用YAML文件进行定义并部署,但是仅仅对于单个的服务支持,如果应用需要由一个甚至几十个这样的服务组成,并且还需要考虑各种服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。

    Helm的核心术语:

    • Chart:一个helm程序包,是创建一个应用的信息集合,包含各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。可以将Chart比喻为yum中的软件安装包;
    • Repository:Charts仓库,用于集中存储和分发Charts;
    • Config:应用程序实例化安装运行时所需要的配置信息;
    • Release:特定的Chart部署于目标集群上的一个实例,代表这一个正在运行的应用。当chart被安装到Kubernetes集群,就会生成一个release,chart可以多次安装到同一个集群,每次安装都是一个release。

    Helm的程序架构:
    Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,如下图:

    • helm:客户端,GO语言编写,实现管理本地的Chart仓库,可管理Chart,与Tiller服务进行交互,用于发送Chart,实例安装、查询、卸载等操作。

    Tiller:服务端,通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg,合并生成release,完成部署。

    简单的说:Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。

    部署Helm

    下载helm

    Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装

    [root@master manifests]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz
    [root@master manifests]# tar xf helm-v2.9.1-linux-amd64.tar.gz
    [root@master manifests]# cd linux-amd64 
    [root@master linux-amd64]# ls
    helm  LICENSE  README.md
    [root@master linux-amd64]# cp helm /usr/bin/
    
    [root@master linux-amd64]# helm version
    Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
    

    部署Tiller

    helm第一次init时,需要链接api-server并进行认证,所以在运行helm时,会去读取kube-config文件,所以必须确认当前用户存在kube-config文件。

    Tiller运行在K8s集群之上,也必须拥有集群的管理权限,也就是需要一个serviceaccount,进行一个clusterrolebinding到cluster-admin。
    Tiller的RBAC配置示例链接:

    https://github.com/helm/helm/blob/master/docs/rbac.md

    [root@master linux-amd64]# cd ..
    [root@master manifests]# mkdir helm
    [root@master manifests]# cd helm
    [root@master helm]# vim tiller-rbac.yaml
    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
    	
    
    [root@master helm]# kubectl apply -f tiller-rbac.yaml 
    serviceaccount/tiller created
    clusterrolebinding.rbac.authorization.k8s.io/tiller created
    [root@master helm]# kubectl get sa -n kube-system|grep tiller
    tiller                               1         14s
    
    [root@master helm]# helm init 
    Creating /root/.helm 
    Creating /root/.helm/repository 
    Creating /root/.helm/repository/cache 
    Creating /root/.helm/repository/local 
    Creating /root/.helm/plugins 
    Creating /root/.helm/starters 
    Creating /root/.helm/cache/archive 
    Creating /root/.helm/repository/repositories.yaml 
    Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com 
    Adding local repo with URL: http://127.0.0.1:8879/charts 
    $HELM_HOME has been configured at /root/.helm.
    
    Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
    
    Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
    For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
    Happy Helming!
    
    #helm init命令进行初始化时,会用到gcr.io/kubernetes-helm中的景象,需要提前下载,镜像标签和Helm同版本号
    [root@master helm]# docker pull xiaobai20201/tiller:v2.9.1
    
    [root@master pki]#  docker tag xiaobai20201/tiller:v2.9.1 gcr.io/kubernetes-helm/tiller:v2.9.1
    
    
    [root@master helm]# kubectl get pods -n kube-system 
    NAME                                     READY   STATUS    RESTARTS   AGE
    canal-nbspn                              3/3     Running   0          30h
    canal-pj6rx                              3/3     Running   0          30h
    canal-rgsnp                              3/3     Running   0          30h
    coredns-78d4cf999f-6cb69                 1/1     Running   3          14d
    coredns-78d4cf999f-tflpn                 1/1     Running   2          14d
    etcd-master                              1/1     Running   0          14d
    kube-apiserver-master                    1/1     Running   0          14d
    kube-controller-manager-master           1/1     Running   0          14d
    kube-flannel-ds-amd64-5zrk7              1/1     Running   0          31h
    kube-flannel-ds-amd64-pql5n              1/1     Running   0          31h
    kube-flannel-ds-amd64-ssd29              1/1     Running   0          31h
    kube-proxy-ch4vp                         1/1     Running   0          14d
    kube-proxy-cz2rf                         1/1     Running   1          14d
    kube-proxy-kdp7d                         1/1     Running   0          14d
    kube-scheduler-master                    1/1     Running   0          14d
    kubernetes-dashboard-6f9998798-klf4t     1/1     Running   0          2d2h
    metrics-server-v0.3.1-65bd5d59b9-xvmns   2/2     Running   0          5h31m
    tiller-deploy-c4f47c598-gl6rp            1/1     Running   0          11m
    
    #安装完成后,执行helm version可以看到客户端和服务端的版本号,两个都显示表示正常安装。
    [root@master helm]# helm version
    Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
    Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
    

    如果希望在安装时自定义一些参数,可以参考一下的一些参数:

    • --canary-image:安装canary分支,即项目的Master分支
    • --tiller-image:安装指定版本的镜像,默认和helm同版本
    • --kube-context:安装到指定的Kubernetes集群
    • --tiller-namespace:安装到指定的名称空间,默认为kube-system
      Tiller将数据存储在ConfigMap资源当中,卸载或重装不会导致数据丢失,卸载Tiller的方法有以下两种:
    (1)kubectl delete deployment tiller-deploy -n kube-system
    (2)helm reset
    

    helm的使用

    官方可用的Chart列表:

    https://hub.kubeapps.com

    [root@master helm]# helm -h
    The Kubernetes package manager
    
    To begin working with Helm, run the 'helm init' command:
    
            $ helm init
    
    This will install Tiller to your running Kubernetes cluster.
    It will also set up any necessary local configuration.
    
    Common actions from this point include:
    
    - helm search:    search for charts  #搜索charts
    - helm fetch:     download a chart to your local directory to view #下载charts到本地
    - helm install:   upload the chart to Kubernetes #安装charts
    - helm list:      list releases of charts #列出charts的版本
    
    Environment:
      $HELM_HOME          set an alternative location for Helm files. By default, these are stored in ~/.helm
      $HELM_HOST          set an alternative Tiller host. The format is host:port
      $HELM_NO_PLUGINS    disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
      $TILLER_NAMESPACE   set an alternative Tiller namespace (default "kube-system")
      $KUBECONFIG         set an alternative Kubernetes configuration file (default "~/.kube/config")
    
    Usage:
      helm [command]
    
    Available Commands:
      completion  Generate autocompletions script for the specified shell (bash or zsh) #为指定的shell生成自动补全脚本(bash或zsh)
      create      create a new chart with the given name #创建一个新的charts
      delete      given a release name, delete the release from Kubernetes #删除指定版本的release
      dependency  manage a chart's dependencies # 管理charts的依赖
      fetch       download a chart from a repository and (optionally) unpack it in local directory #  下载charts并解压到本地目录
      get         download a named release# 下载一个release
      history     fetch release history #release历史信息
      home        displays the location of HELM_HOME #显示helm的家目录
      init        initialize Helm on both client and server #在客户端和服务端初始化helm
      inspect     inspect a chart #查看charts的详细信息
      install     install a chart archive #安装charts
      lint        examines a chart for possible issues #检测包的存在问题
      list        list releases #列出release
      package     package a chart directory into a chart archive # 将chart目录进行打包
      plugin      add, list, or remove Helm plugins #add(增加), list(列出), or remove(移除) Helm 插件
      repo        add, list, remove, update, and index chart repositories #add(增加), list(列出), remove(移除), update(更新), and index(索引) chart仓库
      reset       uninstalls Tiller from a cluster #卸载tiller
      rollback    roll back a release to a previous revision #release版本回滚
      search      search for a keyword in charts#  关键字搜索chart
      serve       start a local http web server # 启动一个本地的http server
      status      displays the status of the named release #查看release状态信息
      template    locally render templates #本地模板
      test        test a release # release测试
      upgrade     upgrade a release #release更新
      verify      verify that a chart at the given path has been signed and is valid  #验证chart的签名和有效期
      version     print the client/server version information #打印客户端和服务端的版本信息
    

    Charts是Helm的程序包,它们都存在在Charts仓库当中。Kubernetes官方的仓库保存了一系列的Charts,仓库默认的名称为stable。安装Charts到集群时,Helm首先会到官方仓库获取相关的Charts,并创建release。可执行 helm search 查看当前可安装的 chart 。
    Helm 可以像 yum 管理软件包一样管理 chart。 yum 的软件包存放在仓库中,同样的,Helm 也有仓库。
    Helm 安装时已经默认配置好了两个仓库:stable 和 local。stable 是官方仓库,local 是用户存放自己开发的chart的本地仓库。可以通过helm repo list进行查看。由于网络原因,国内可能无法更新仓库源(网络不稳定偶尔出问题),这里可以更改为阿里云的仓库源,。

    [root@master helm]# helm repo remove stable
    "stable" has been removed from your repositories
    [root@master helm]# 
    [root@master helm]# helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
    "stable" has been added to your repositories
    [root@master helm]# 
    [root@master helm]# helm repo update
    Hang tight while we grab the latest from your chart repositories...
    ...Skip local chart repository
    ...Successfully got an update from the "stable" chart repository
    Update Complete. ⎈ Happy Helming!⎈ 
    [root@master helm]# helm repo list
    NAME    URL                                                   
    local   http://127.0.0.1:8879/charts                          
    stable  https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
    

    与 yum 一样,helm 也支持关键字搜索:

    [root@master helm]# helm search stable/mysql
    NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                       
    stable/mysql            0.15.0          5.7.14          Fast, reliable, scalable, and easy to use open-...
    stable/mysqldump        2.4.0           2.4.0           A Helm chart to help backup MySQL databases usi..
    

    使用helm inspect也可以查看详细信息

    [root@master helm]# helm inspect stable/mysql
    

    包括 DESCRIPTION 在内的所有信息,只要跟关键字匹配,都会显示在结果列表中。
    安装 chart 也很简单,执行如下命令可以安装 MySQL。

    [root@master helm]# helm install stable/mysql
    Error: no available release name found
    #出现此类报错主要是tiller权限的问题
    [root@master helm]# kubectl create serviceaccount --namespace kube-system tiller
    Error from server (AlreadyExists): serviceaccounts "tiller" already exists
    [root@master helm]# kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
    clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
    [root@master helm]# kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
    deployment.extensions/tiller-deploy patched (no change)
    
    #再次安装
    [root@master helm]# helm install stable/mysql
    NAME:   callous-zorse  #第一部分
    LAST DEPLOYED: Thu Apr 11 09:31:41 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    
    RESOURCES:   #第二部分
    ==> v1/Secret
    NAME                 TYPE    DATA  AGE
    callous-zorse-mysql  Opaque  2     0s
    
    ==> v1/ConfigMap
    NAME                      DATA  AGE
    callous-zorse-mysql-test  1     0s
    
    ==> v1/PersistentVolumeClaim
    NAME                 STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
    callous-zorse-mysql  Pending  0s
    
    ==> v1/Service
    NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)   AGE
    callous-zorse-mysql  ClusterIP  10.109.125.202  <none>       3306/TCP  0s
    
    ==> v1beta1/Deployment
    NAME                 DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    callous-zorse-mysql  1        1        1           0          0s
    
    ==> v1/Pod(related)
    NAME                                 READY  STATUS   RESTARTS  AGE
    callous-zorse-mysql-f5c97689b-ch5cf  0/1    Pending  0         0s
    
    
    NOTES:  #第三部分
    MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
    callous-zorse-mysql.default.svc.cluster.local
    
    To get your root password run:
    
        MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default callous-zorse-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)
    
    To connect to your database:
    
    1. Run an Ubuntu pod that you can use as a client:
    
        kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
    
    2. Install the mysql client:
    
        $ apt-get update && apt-get install mysql-client -y
    
    3. Connect using the mysql cli, then provide your password:
        $ mysql -h callous-zorse-mysql -p
    
    To connect to your database directly from outside the K8s cluster:
        MYSQL_HOST=127.0.0.1
        MYSQL_PORT=3306
    
        # Execute the following command to route the connection:
        kubectl port-forward svc/callous-zorse-mysql 3306
    
        mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
    
    

    输出分为三部分:

    1. chart 本次部署的描述信息:
      NAMErelease 的名字,因为我们没用 -n 参数指定,Helm 随机生成了一个,这里是 callous-zorse
      NAMESPACErelease 部署的 namespace,默认是 default,也可以通过 --namespace 指定。
      STATUSDEPLOYED,表示已经将 chart 部署到集群。
    2. 当前 release 包含的资源:ServiceDeploymentSecretPersistentVolumeClaim,其名字都是 callous-zorse-mysql,命名的格式为 ReleasName-ChartName
    3. NOTES 部分显示的是 release 的使用方法。比如如何访问 Service,如何获取数据库密码,以及如何连接数据库等。
      通过 kubectl get 可以查看组成 release 的各个对象:
    [root@master helm]# kubectl get deploy,svc,pvc,secret callous-zorse-mysql
    NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.extensions/callous-zorse-mysql   0/1     1            0           10m
    
    NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    service/callous-zorse-mysql   ClusterIP   10.109.125.202   <none>        3306/TCP   10m
    
    NAME                                        STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    persistentvolumeclaim/callous-zorse-mysql   Pending                                                     10m
    
    NAME                         TYPE     DATA   AGE
    secret/callous-zorse-mysql   Opaque   2      10m
    

    由于我们还没有准备 PersistentVolume,当前 release 还不可用。

    helm list 显示已经部署的 releasehelm delete 可以删除 release

    [root@master helm]# helm list
    NAME            REVISION        UPDATED                         STATUS          CHART           NAMESPACE
    callous-zorse   1               Thu Apr 11 09:31:41 2019        DEPLOYED        mysql-0.15.0    default  
    [root@master helm]# helm delete callous-zorse
    release "callous-zorse" deleted
    

    chart 目录结构

    chart 是 Helm 的应用打包格式。chart 由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源,比如 Service、Deployment、PersistentVolumeClaim、Secret、ConfigMap 等。

    单个的 chart 可以非常简单,只用于部署一个服务,比如 Memcached;chart 也可以很复杂,部署整个应用,比如包含 HTTP Servers、 Database、消息中间件、cache 等。

    chart 将这些文件放置在预定义的目录结构中,通常整个 chart 被打成 tar 包,而且标注上版本信息,便于 Helm 部署。

    以前面 MySQL chart为例。一旦安装了某个 chart,我们就可以在 ~/.helm/cache/archive 中找到 chart 的 tar 包。

    [root@master ~]# cd .helm/cache/archive/   
    [root@master archive]# ls
    mysql-0.15.0.tgz
    
    [root@master archive]# tar xf mysql-0.15.0.tgz  
    tar: mysql/Chart.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/values.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/NOTES.txt:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/_helpers.tpl:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/configurationFiles-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/deployment.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/initializationFiles-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/pvc.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/secrets.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/svc.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/tests/test-configmap.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/templates/tests/test.yaml:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/.helmignore:不可信的旧时间戳 1970-01-01 08:00:00
    tar: mysql/README.md:不可信的旧时间戳 1970-01-01 08:00:00
    
    [root@master archive]# tree
    .
    ├── mysql
    │   ├── Chart.yaml
    │   ├── README.md
    │   ├── templates
    │   │   ├── configurationFiles-configmap.yaml
    │   │   ├── deployment.yaml
    │   │   ├── _helpers.tpl
    │   │   ├── initializationFiles-configmap.yaml
    │   │   ├── NOTES.txt
    │   │   ├── pvc.yaml
    │   │   ├── secrets.yaml
    │   │   ├── svc.yaml
    │   │   └── tests
    │   │       ├── test-configmap.yaml
    │   │       └── test.yaml
    │   └── values.yaml
    └── mysql-0.15.0.tgz
    
    3 directories, 14 files
    
    • Chart.yaml:YAML 文件,描述 chart 的概要信息。
    • README.md:Markdown 格式的 README 文件,相当于 chart 的使用文档,此文件为可选。
    • LICENSE:文本文件,描述 chart 的许可信息,此文件为可选。
    • requirements.yaml :chart 可能依赖其他的 chart,这些依赖关系可通过 requirements.yaml 指定。
    • values.yaml:chart 支持在安装的时根据参数进行定制化配置,而 values.yaml 则提供了这些配置参数的默认值。
    • templates目录:各类 Kubernetes 资源的配置模板都放置在这里。Helm 会将 values.yaml 中的参数值注入到模板中生成标准的 YAML 配置文件。
    • templates/NOTES.txt:chart 的简易使用文档,chart 安装成功后会显示此文档内容。 与模板一样,可以在 NOTE.txt 中插入配置参数,Helm 会动态注入参数值。

    chart模板

    Helm 通过模板创建 Kubernetes 能够理解的 YAML 格式的资源配置文件,我们将通过例子来学习如何使用模板。
    以 templates/secrets.yaml 为例:

    {{- if not .Values.existingSecret }}
    apiVersion: v1
    kind: Secret
    metadata:
      name: {{ template "mysql.fullname" . }}
      labels:
        app: {{ template "mysql.fullname" . }}
        chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
        release: "{{ .Release.Name }}"
        heritage: "{{ .Release.Service }}"
    type: Opaque
    data:
      {{ if .Values.mysqlRootPassword }}
      mysql-root-password:  {{ .Values.mysqlRootPassword | b64enc | quote }}
      {{ else }}
      mysql-root-password: {{ randAlphaNum 10 | b64enc | quote }}
      {{ end }}
      {{ if .Values.mysqlPassword }}
      mysql-password:  {{ .Values.mysqlPassword | b64enc | quote }}
      {{ else }}
      mysql-password: {{ randAlphaNum 10 | b64enc | quote }}
      {{ end }}
    {{- if .Values.ssl.enabled }}
    {{ if .Values.ssl.certificates }}
    {{- range .Values.ssl.certificates }}
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: {{ .name }}
      labels:
        app: {{ template "mysql.fullname" $ }}
        chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
        release: "{{ $.Release.Name }}"
        heritage: "{{ $.Release.Service }}"
    type: Opaque
    data:
      ca.pem: {{ .ca | b64enc }}
      server-cert.pem: {{ .cert | b64enc }}
      server-key.pem: {{ .key | b64enc }}
    {{- end }}
    {{- end }}
    {{- end }}
    {{- end }}
    

    从结构上看,文件的内容和我们在定义Secret的配置上大致相似,只是大部分的属性值变成了{{ xxx }}。这些{{ xx }}实际上是模板的语法。Helm采用了Go语言的模板来编写chart。

    • {{ template "mysql.fullname" . }} 定义 Secret 的 name
      关键字 template 的作用是引用一个子模板 mysql.fullname。这个子模板是在 templates/_helpers.tpl 文件中定义的。
    [root@master templates]# vim _helpers.tpl
    ......
    If release name contains chart name it will be used as a full name.
    */}}
    {{- define "mysql.fullname" -}}
    {{- if .Values.fullnameOverride -}}
    {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
    {{- else -}}
    {{- $name := default .Chart.Name .Values.nameOverride -}}
    {{- if contains $name .Release.Name -}}
    {{- printf .Release.Name | trunc 63 | trimSuffix "-" -}}
    {{- else -}}
    {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
    {{- end -}}
    {{- end -}}
    {{- end -}}
    ......
    

    这个定义还是很复杂的,因为它用到了模板语言中的对象、函数、流控制等概念。现在看不懂没关系,这里我们学习的重点是:如果存在一些信息多个模板都会用到,则可在 templates/_helpers.tpl 中将其定义为子模板,然后通过 templates 函数引用。
    这里 mysql.fullname 是由 release 与 chart 二者名字拼接组成。
    根据 chart 的最佳实践,所有资源的名称都应该保持一致,对于我们这个 chart,无论 Secret 还是 Deployment、PersistentVolumeClaim、Service,它们的名字都是子模板 mysql.fullname 的值。

    • ChartRelease 是 Helm 预定义的对象,每个对象都有自己的属性,可以在模板中使用。如果使用下面命令安装 chart:
    [root@master templates]# helm search stable/mysql
    NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                       
    stable/mysql            0.15.0          5.7.14          Fast, reliable, scalable, and easy to use open-...
    stable/mysqldump        2.4.0           2.4.0           A Helm chart to help backup MySQL databases usi...
    [root@master templates]# helm install stable/mysql -n my
    


    {{ .Chart.Name }} 的值为 mysql
    {{ .Chart.Version }} 的值为 0.15.0
    {{ .Release.Name }}的值为 my
    {{ .Release.Service }} 始终取值为 Tiller.
    {{ template "mysql.fullname" . }} 计算结果为 my-mysql。

    • 这里指定 mysql-root-password 的值,不过使用了 if-else 的流控制,其逻辑为:
      如果 .Values.mysqlRootPassword 有值,则对其进行 base64 编码;否则随机生成一个 10 位的字符串并编码。

    Values 也是预定义的对象,代表的是 values.yaml 文件。而 .Values.mysqlRootPassword 则是values.yaml中定义的 mysqlRootPassword 参数:

    [root@master mysql]# vim values.yaml 
    ## mysql image version
    ## ref: https://hub.docker.com/r/library/mysql/tags/
    ##
    image: "mysql"
    imageTag: "5.7.14"
    
    busybox:
      image: "busybox"
      tag: "1.29.3"
    
    testFramework:
      image: "dduportal/bats"
      tag: "0.4.0"
    
    ## Specify password for root user
    ##
    ## Default: random 10 character string
    # mysqlRootPassword: testing
    
    ## Create a database user
    ##
    # mysqlUser:
    ## Default: random 10 character string
    # mysqlPassword:
    

    因为 mysqlRootPassword 被注释掉了,没有赋值,所以逻辑判断会走 else,即随机生成密码。

    randAlphaNumb64encquote 都是 Go 模板语言支持的函数,函数之间可以通过管道 | 连接。
    {{ randAlphaNum 10 | b64enc | quote }} 的作用是首先随机产生一个长度为 10 的字符串,然后将其 base64 编码,最后两边加上双引号。
    templates/secrets.yaml 这个例子展示了 chart 模板主要的功能,我们最大的收获应该是:模板将 chart 参数化了,通过 values.yaml 可以灵活定制应用。

    无论多复杂的应用,用户都可以用 Go 模板语言编写出 chart。无非是使用到更多的函数、对象和流控制

    定制安装 MySQL chart

    chart安装准备

    作为准备工作,安装之前需要先清楚 chart 的使用方法。这些信息通常记录在 values.yaml 和 README.md 中。除了下载源文件查看,执行 helm inspect values 可能是更方便的方法。

    [root@master helm]# helm inspect values stable/mysql       
    ## mysql image version
    ## ref: https://hub.docker.com/r/library/mysql/tags/
    ##
    image: "mysql"
    imageTag: "5.7.14"
    
    busybox:
      image: "busybox"
      tag: "1.29.3"
    
    testFramework:
      image: "dduportal/bats"
      tag: "0.4.0"
    
    ## Specify password for root user
    ##
    ## Default: random 10 character string
    # mysqlRootPassword: testing
    
    ## Create a database user
    ##
    # mysqlUser:
    ## Default: random 10 character string
    # mysqlPassword:
    
    ## Allow unauthenticated access, uncomment to enable
    ##
    # mysqlAllowEmptyPassword: true
    
    ## Create a database
    ##
    # mysqlDatabase:
    
    ## Specify an imagePullPolicy (Required)
    ## It's recommended to change this to 'Always' if the image tag is 'latest'
    ## ref: http://kubernetes.io/docs/user-guide/images/#updating-images
    ##
    imagePullPolicy: IfNotPresent
    
    extraVolumes: |
      # - name: extras
      #   emptyDir: {}
    
    extraVolumeMounts: |
      # - name: extras
      #   mountPath: /usr/share/extras
      #   readOnly: true
    
    extraInitContainers: |
      # - name: do-something
      #   image: busybox
      #   command: ['do', 'something']
    
    # Optionally specify an array of imagePullSecrets.
    # Secrets must be manually created in the namespace.
    # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
    # imagePullSecrets:
      # - name: myRegistryKeySecretName
    
    ## Node selector
    ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
    nodeSelector: {}
    
    ## Tolerations for pod assignment
    ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
    ##
    tolerations: []
    
    livenessProbe:
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 3
    
    readinessProbe:
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 3
    
    ## Persist data to a persistent volume
    persistence:
      enabled: true
      ## database data Persistent Volume Storage Class
      ## If defined, storageClassName: <storageClass>
      ## If set to "-", storageClassName: "", which disables dynamic provisioning
      ## If undefined (the default) or set to null, no storageClassName spec is
      ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
      ##   GKE, AWS & OpenStack)
      ##
      # storageClass: "-"
      accessMode: ReadWriteOnce
      size: 8Gi
      annotations: {}
    
    ## Configure resource requests and limits
    ## ref: http://kubernetes.io/docs/user-guide/compute-resources/
    ##
    resources:
      requests:
        memory: 256Mi
        cpu: 100m
    
    # Custom mysql configuration files used to override default mysql settings
    configurationFiles: {}
    #  mysql.cnf: |-
    #    [mysqld]
    #    skip-name-resolve
    #    ssl-ca=/ssl/ca.pem
    #    ssl-cert=/ssl/server-cert.pem
    #    ssl-key=/ssl/server-key.pem
    
    # Custom mysql init SQL files used to initialize the database
    initializationFiles: {}
    #  first-db.sql: |-
    #    CREATE DATABASE IF NOT EXISTS first DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    #  second-db.sql: |-
    #    CREATE DATABASE IF NOT EXISTS second DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
    
    metrics:
      enabled: false
      image: prom/mysqld-exporter
      imageTag: v0.10.0
      imagePullPolicy: IfNotPresent
      resources: {}
      annotations: {}
        # prometheus.io/scrape: "true"
        # prometheus.io/port: "9104"
      livenessProbe:
        initialDelaySeconds: 15
        timeoutSeconds: 5
      readinessProbe:
        initialDelaySeconds: 5
        timeoutSeconds: 1
    
    ## Configure the service
    ## ref: http://kubernetes.io/docs/user-guide/services/
    service:
      annotations: {}
      ## Specify a service type
      ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
      type: ClusterIP
      port: 3306
      # nodePort: 32000
    
    ssl:
      enabled: false
      secret: mysql-ssl-certs
      certificates:
    #  - name: mysql-ssl-certs
    #    ca: |-
    #      -----BEGIN CERTIFICATE-----
    #      ...
    #      -----END CERTIFICATE-----
    #    cert: |-
    #      -----BEGIN CERTIFICATE-----
    #      ...
    #      -----END CERTIFICATE-----
    #    key: |-
    #      -----BEGIN RSA PRIVATE KEY-----
    #      ...
    #      -----END RSA PRIVATE KEY-----
    
    ## Populates the 'TZ' system timezone environment variable
    ## ref: https://dev.mysql.com/doc/refman/5.7/en/time-zone-support.html
    ##
    ## Default: nil (mysql will use image's default timezone, normally UTC)
    ## Example: 'Australia/Sydney'
    # timezone:
    
    # To be added to the database server pod(s)
    podAnnotations: {}
    
    podLabels: {}
    
    ## Set pod priorityClassName
    # priorityClassName: {}
    

    输出的实际上是 values.yaml 的内容。阅读注释就可以知道 MySQL chart 支持哪些参数,安装之前需要做哪些准备。其中有一部分是关于存储的:

    ## Persist data to a persistent volume
    persistence:
      enabled: true
      ## database data Persistent Volume Storage Class
      ## If defined, storageClassName: <storageClass>
      ## If set to "-", storageClassName: "", which disables dynamic provisioning
      ## If undefined (the default) or set to null, no storageClassName spec is
      ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
      ##   GKE, AWS & OpenStack)
      ##
      # storageClass: "-"
      accessMode: ReadWriteOnce
      size: 8Gi
      annotations: {}
    

    chart 定义了一个 PersistentVolumeClaim,申请 8G 的 PersistentVolume。由于我们的实验环境不支持动态供给,所以得预先创建好相应的 PV,其配置文件 mysql-pv.yml 内容为:

    
    [root@master helm]# cd ../volume/
    [root@master volume]# vim mysql-pv.yaml
    
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: mysql-pv2
    spec:
      accessModes:
        - ReadWriteOnce
      capacity:
        storage: 8Gi
      persistentVolumeReclaimPolicy: Retain
      nfs:
        path: /data/volume/db
        server: nfs
    	
    [root@master volume]# kubectl apply -f mysql-pv.yaml 
    persistentvolume/mysql-pv2 created
    [root@master volume]# kubectl get pv   
    NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS   REASON   AGE
    mysql-pv2   8Gi        RWO            Retain           Bound       default/my-mysql                                    30s
    

    定制化安装 chart

    除了接受 values.yaml 的默认值,我们还可以定制化 chart,比如设置 mysqlRootPassword
    Helm有两种方式传递配置参数:

    • 指定自己的values文件,通常是先通过helm inspect values mysql > myvalues.yaml生成values,然后设置mysqlRootPassword之后执行 helm install --values=myvalues.yaml mysql
    • 通过 --set 直接传入参数值,比如:
    [root@master helm]# helm install stable/mysql --set mysqlRootPassword=abc123 -n my-2
    NAME:   my-2
    LAST DEPLOYED: Thu Apr 11 11:26:33 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    RESOURCES:
    ==> v1/Service
    NAME        TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)   AGE
    my-2-mysql  ClusterIP  10.97.198.107  <none>       3306/TCP  1s
    
    ==> v1beta1/Deployment
    NAME        DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    my-2-mysql  1        1        1           0          1s
    
    ==> v1/Pod(related)
    NAME                         READY  STATUS   RESTARTS  AGE
    my-2-mysql-5dc69d7d66-rmt2z  0/1    Pending  0         1s
    
    ==> v1/Secret
    NAME        TYPE    DATA  AGE
    my-2-mysql  Opaque  2     1s
    
    ==> v1/ConfigMap
    NAME             DATA  AGE
    my-2-mysql-test  1     1s
    
    ==> v1/PersistentVolumeClaim
    NAME        STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
    my-2-mysql  Pending  1s
    ......
    

    mysqlRootPassword 设置为 abc123。另外,-n 设置elease 为 my-2,各类资源的名称即为my-2-mysql

    通过 helm list helm status 可以查看 chart 的最新状态。

    升级和回滚release

    release 发布后可以执行 helm upgrade 对其升级,通过 --values 或 --set应用新的配置。比如将当前的 MySQL 版本升级到 5.7.15:

    [root@master helm]# helm upgrade --set imageTag=5.7.15 my stable/mysql
    

    helm history 可以查看 release 所有的版本。通过 helm rollback 可以回滚到任何版本。

    [root@master helm]# helm history my-2 
    REVISION        UPDATED                         STATUS          CHART           DESCRIPTION     
    1               Thu Apr 11 11:26:33 2019        SUPERSEDED      mysql-0.15.0    Install complete
    2               Thu Apr 11 11:29:41 2019        DEPLOYED        mysql-0.15.0    Upgrade complete
    
    [root@master helm]# helm rollback my-2 1
    Rollback was a success! Happy Helming!
    
    [root@master helm]# helm history my-2
    REVISION        UPDATED                         STATUS          CHART           DESCRIPTION     
    1               Thu Apr 11 11:26:33 2019        SUPERSEDED      mysql-0.15.0    Install complete
    2               Thu Apr 11 11:29:41 2019        SUPERSEDED      mysql-0.15.0    Upgrade complete
    3               Thu Apr 11 11:30:21 2019        DEPLOYED        mysql-0.15.0    Rollback to 1 
    

    自定义chart

    Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart。

    创建chart

    执行 helm create mychart 的命令创建 chart mychart

    [root@master helm]# cd mychart/
    [root@master mychart]# tree
    .
    ├── charts
    ├── Chart.yaml
    ├── templates
    │   ├── deployment.yaml
    │   ├── _helpers.tpl
    │   ├── ingress.yaml
    │   ├── NOTES.txt
    │   └── service.yaml
    └── values.yaml
    
    2 directories, 7 files
    

    Helm 会帮我们创建目录 mychart,并生成了各类 chart 文件。这样我们就可以在此基础上开发自己的 chart 了。

    调试chart

    elm 提供了 debug 的工具:helm linthelm install --dry-run --debug
    helm lint 会检测 chart 的语法,报告错误以及给出建议。 故意修改mychart中的value.yaml,进行检测:
    helm lint mychart 会指出这个语法错误。

    [root@master helm]# helm lint mychart
    ==> Linting mychart
    [INFO] Chart.yaml: icon is recommended
    [ERROR] values.yaml: unable to parse YAML
            error converting YAML to JSON: yaml: line 12: could not find expected ':'
    
    Error: 1 chart(s) linted, 1 chart(s) failed
    
    1 chart(s) linted, no failures
    [root@master helm]# helm lint mychart
    ==> Linting mychart
    [INFO] Chart.yaml: icon is recommended
    
    1 chart(s) linted, no failures
    

    helm install --dry-run --debug 会模拟安装 chart,并输出每个模板生成的 YAML 内容。

    [root@master helm]# helm install --dry-run mychart --debug
    [debug] Created tunnel using local port: '28515'
    
    [debug] SERVER: "127.0.0.1:28515"
    
    [debug] Original chart version: ""
    [debug] CHART PATH: /root/manifests/helm/mychart
    
    NAME:   early-marsupial
    REVISION: 1
    RELEASED: Thu Apr 11 11:40:39 2019
    CHART: mychart-0.1.0
    USER-SUPPLIED VALUES:
    {}
    
    COMPUTED VALUES:
    affinity: {}
    image:
      pullPolicy: IfNotPresent
      repository: nginx
      tag: stable
    ingress:
      annotations: {}
      enabled: false
      hosts:
      - chart-example.local
      path: /
      tls: []
    nodeSelector: {}
    replicaCount: 1
    resources: {}
    service:
      port: 80
      type: ClusterIP
    tolerations: []
    
    HOOKS:
    MANIFEST:
    
    ---
    # Source: mychart/templates/service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: early-marsupial-mychart
      labels:
        app: mychart
        chart: mychart-0.1.0
        release: early-marsupial
        heritage: Tiller
    spec:
      type: ClusterIP
      ports:
        - port: 80
          targetPort: http
          protocol: TCP
          name: http
      selector:
        app: mychart
        release: early-marsupial
    ---
    # Source: mychart/templates/deployment.yaml
    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
      name: early-marsupial-mychart
      labels:
        app: mychart
        chart: mychart-0.1.0
        release: early-marsupial
        heritage: Tiller
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mychart
          release: early-marsupial
      template:
        metadata:
          labels:
            app: mychart
            release: early-marsupial
        spec:
          containers:
            - name: mychart
              image: "nginx:stable"
              imagePullPolicy: IfNotPresent
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /
                  port: http
              readinessProbe:
                httpGet:
                  path: /
                  port: http
              resources:
                {}
    

    我们可以检视这些输出,判断是否与预期相符。

    安装chart

    Helm自持四种方法安装chart:

    • 安装仓库中的 chart,例如:helm install stable/nginx
    • 通过 tar 包安装,例如:helm install ./nginx-1.2.3.tgz
    • 通过 chart 本地目录安装,例如:helm install ./nginx
    • 通过 URL 安装,例如:helm install https://example.com/charts/nginx-1.2.3.tgz

    本次使用本地目录安装

    [root@master helm]# helm install ./mychart/ 
    NAME:   soft-worm
    LAST DEPLOYED: Thu Apr 11 13:43:18 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    
    RESOURCES:
    ==> v1beta2/Deployment
    NAME               DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    soft-worm-mychart  1        1        1           0          0s
    
    ==> v1/Pod(related)
    NAME                               READY  STATUS   RESTARTS  AGE
    soft-worm-mychart-78ccf58c6-t6jp5  0/1    Pending  0         0s
    
    ==> v1/Service
    NAME               TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
    soft-worm-mychart  ClusterIP  10.103.92.36  <none>       80/TCP   0s
    
    
    NOTES:
    1. Get the application URL by running these commands:
      export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=soft-worm" -o jsonpath="{.items[0].metadata.name}")
      echo "Visit http://127.0.0.1:8080 to use your application"
      kubectl port-forward $POD_NAME 8080:80
    

    当 chart 部署到 Kubernetes 集群,便可以对其进行更为全面的测试。

    将chart添加到仓库

    chart 通过测试后可以将其添加到仓库,团队其他成员就能够使用。任何 HTTP Server 都可以用作 chart 仓库,下面演示在 nfs 10.0.0.14 上搭建仓库。

    在nfs上启动nginx(容器也可以)并创建一个server标签(由于实验用nfs已经有nginx服务,新建个server标签监听8080端口)

    ......
        server {
            listen       8080;
            location / {
            root         /data/;
            }
            # Load configuration files for the default server block.
            include /etc/nginx/default.d/*.conf;
    
            }
    .....
    [root@nfs ~]# mkdir /data/charts/ -p
    [root@nfs ~]#  nginx -s reload
    

    通过 helm package 将 mychart 打包。

    [root@master helm]# helm package ./mychart/
    Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz
    #执行 helm repo index 生成仓库的 index 文件
    [root@master helm]# helm package ./mychart/
    Successfully packaged chart and saved it to: /root/manifests/helm/mychart-0.1.0.tgz
    [root@master helm]# mkdir myrepo
    [root@master helm]# mv /root/manifests/helm/mychart-0.1.0.tgz ./myrepo/
    [root@master helm]# helm repo index ./myrepo/ --url http://10.0.0.14:8080/charts
    [root@master helm]# ls myrepo/
    index.yaml  mychart-0.1.0.tgz
    

    Helm 会扫描 myrepo 目录中的所有 tgz 包并生成 index.yaml。--url指定的是新仓库的访问路径。新生成的 index.yaml 记录了当前仓库中所有 chart 的信息:
    当前只有 mychart 这一个 chart。

    [root@master helm]# cat myrepo/index.yaml 
    apiVersion: v1
    entries:
      mychart:
      - apiVersion: v1
        appVersion: "1.0"
        created: 2019-04-11T14:18:48.494631141+08:00
        description: A Helm chart for Kubernetes
        digest: 08abeb3542e8a9ab90df776d3a646199da8be0ebfc5198ef032190938d49e30a
        name: mychart
        urls:
        - http://10.0.0.14:8080/charts/mychart-0.1.0.tgz
        version: 0.1.0
    generated: 2019-04-11T14:18:48.494210001+08:00
    

    将 mychart-0.1.0.tgz 和 index.yaml 上传到 k8s-node1 的 /var/www/charts 目录。

    [root@master helm]# scp ./myrepo/* nfs:/data/charts/
    index.yaml                                                              100%  394   407.6KB/s   00:00    
    mychart-0.1.0.tgz                                                       100% 2556     2.8MB/s   00:00  
    

    通过 helm repo add 将新仓库添加到 Helm。

    [root@master helm]# helm repo add nfs_repo http://10.0.0.14:8080/charts
    "nfs_repo" has been added to your repositories
    [root@master helm]# helm repo list 
    NAME            URL                                             
    stable          https://kubernetes-charts.storage.googleapis.com
    local           http://127.0.0.1:8879/charts                    
    nfs_repo        http://10.0.0.14:8080/charts  
    

    现在已经可以 repo search 到 mychart 了。

    [root@master helm]# helm search mychart  
    NAME                    CHART VERSION   APP VERSION     DESCRIPTION                
    local/mychart           0.1.0           1.0             A Helm chart for Kubernetes
    nfs_repo/mychart        0.1.0           1.0             A Helm chart for Kubernetes
    

    除了 newrepo/mychart,这里还有一个 local/mychart。这是因为在执行打包操作的同时,mychart 也被同步到了 local 的仓库。

    已经可以直接从新仓库安装 mychart 了。

    [root@master helm]# helm install --name my-3 nfs_repo/mychart
    NAME:   my-3
    LAST DEPLOYED: Thu Apr 11 14:26:53 2019
    NAMESPACE: default
    STATUS: DEPLOYED
    
    RESOURCES:
    ==> v1/Pod(related)
    NAME                           READY  STATUS             RESTARTS  AGE
    my-3-mychart-69cdddc4fb-cljmt  0/1    ContainerCreating  0         0s
    
    ==> v1/Service
    NAME          TYPE       CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
    my-3-mychart  ClusterIP  10.97.149.58  <none>       80/TCP   0s
    
    ==> v1beta2/Deployment
    NAME          DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    my-3-mychart  1        1        1           0          0s
    
    
    NOTES:
    1. Get the application URL by running these commands:
      export POD_NAME=$(kubectl get pods --namespace default -l "app=mychart,release=my-3" -o jsonpath="{.items[0].metadata.name}")
      echo "Visit http://127.0.0.1:8080 to use your application"
      kubectl port-forward $POD_NAME 8080:80
    
    

    如果以后仓库添加了新的 chart,需要用 helm repo update 更新本地的 index。类似于yum update /apt-get update

    [root@master helm]# helm repo update
    Hang tight while we grab the latest from your chart repositories...
    ...Skip local chart repository
    ...Successfully got an update from the "nfs_repo" chart repository
    ...Unable to get an update from the "stable" chart repository (https://kubernetes-charts.storage.googleapis.com):
            Get https://kubernetes-charts.storage.googleapis.com/index.yaml: dial tcp 172.217.161.176:443: connect: connection timed out
    Update Complete. ⎈ Happy Helming!⎈ 
    

    总结

    • Helm是Kubernetes的包管理器,Helm 让我们能够像 yum 管理 rpm 包那样安装、部署、升级和删除容器化应用。
    • Helm 由客户端和 Tiller 服务器组成。客户端负责管理 chart,服务器负责管理 release。
    • chart 是 Helm 的应用打包格式,它由一组文件和目录构成。其中最重要的是模板,模板中定义了 Kubernetes 各类资源的配置信息,Helm 在部署时通过 values.yaml 实例化模板。
    • Helm 允许用户开发自己的 chart,并为用户提供了调试工具。用户可以搭建自己的 chart 仓库,在团队中共享 chart。
    参考资料

    https://www.cnblogs.com/linuxk

  • 相关阅读:
    160-三个用户同时登录,是怎么实现多线程的?
    159-如何解决缓存穿透?
    158-为什么会引发缓存穿透?
    存储emoji表情,修改字符集为utf8mb4
    java相差小时数
    pom.xml解释
    前端 跨域
    java 获取的是本地的IP地址
    是否超时
    发送验证码
  • 原文地址:https://www.cnblogs.com/wlbl/p/10694393.html
Copyright © 2011-2022 走看看