kubernetes软件包管理器Helm

Posted 水木,年華

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes软件包管理器Helm相关的知识,希望对你有一定的参考价值。

为什么需要Helm

常规K8s部署应用方式:将需要的资源编写YAML文件,然后apply部署;

由于Kubernetes缺少对发布的应用版本管理和控制,使得部署的应
用维护和更新等面临诸多的挑战,主要面临以下问题:
•如何将这些服务作为一个整体管理?
•这些资源文件如何高效复用?
•不支持应用级别的版本管理

Helm介绍

Helm是一个Kubernetes的包管理工具,就像Linux下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上。

Helm有3个重要概念:
• helm:一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理。
• Chart:应用描述,一系列用于描述 k8s 资源相关文件的集合。
• Release:基于Chart的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个 release;将在k8s中创建出真实运行的资源对象。

Helm目前有两个大版本:v2和v3
2019年11月Helm团队发布v3版本,相比v2版本最
大变化是将Tiller删除,并大部分代码重构。

Helm客户端

使用helm很简单,你只需要下载一个二进制客户端包即可,会通过kubeconfig配置(通常$HOME/.kube/config)来连接Kubernetes。

项目地址:https://github.com/helm/helm

下载Helm客户端:

wget https://get.helm.sh/helm-v3.6.0-linux-amd64.tar.gz
[root@k8s-master1 ~]# tar zxf  helm-v3.6.0-linux-amd64.tar.gz  [root@k8s-master1 ~]# cd linux-amd64/
[root@k8s-master1 linux-amd64]# ls
helm  LICENSE  README.md
[root@k8s-master1 linux-amd64]# mv helm /usr/bin/

Helm命令

Helm基本使用

Helm管理应用生命周期:
• helm create 创建Chart示例
• helm install 部署
• helm upgrade 更新
• helm rollback 回滚
• helm uninstall 卸载

Helm基本使用:创建Chart示例

创建chart:

helm create mychart

打包chart:

helm package mychart

• charts:目录里存放这个chart依赖的所有子chart。
• Chart.yaml:用于描述这个 Chart的基本信息,包括名字、描述信息以及版本等。
• values.yaml :用于存储 templates 目录中模板文件中用到变量的值。
• Templates: 目录里面存放所有yaml模板文件。
• NOTES.txt :用于介绍Chart帮助信息, helm install 部署后展示给用户。例如:如何使用这个 Chart、列出缺省的设置等。
• _helpers.tpl:放置模板的地方,可以在整个 chart 中重复使用。

简单理解:

自定义chart

[root@k8s-master1 ~]# mkdir -p demo/templates 
[root@k8s-master1 demo]# touch values.yaml  
[root@k8s-master1 demo]# vim Chart.ymal 
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
[root@k8s-master1 demo]# cd templates/ 
[root@k8s-master1 templates]# ls
[root@k8s-master1 templates]# touch NOTES.txt  _helpers.tpl
[root@k8s-master1 templates]# echo "这是一个测试chart" > NOTES.txt  
[root@k8s-master1 templates]# kubectl create deployment web --image=nginx --dry-run=client -o yaml > deployment.yaml 
[root@k8s-master1 templates]# kubectl expose deployment web --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml > service.yaml 

Helm基本使用:部署

部署Chart:

helm install web mychart

查看Release:

helm list -n default

查看部署的Pod:

kubectl get pods,svc

动态引用变量

[root@k8s-master1 mychart]# cat values.yaml 
image:
  repository: nginx
  tag: "1.15"

[root@k8s-master1 templates]# cat deployment.yaml  
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name:  .Release.Name  #根据命令行输入的名字动态设置
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - image:  .Values.image.repository : .Values.image.tag 
        name: nginx
        resources: 

[root@k8s-master1 templates]# cat server.yaml  
apiVersion: v1
kind: Service 
metadata:
  labels:
    app: web
  name:  .Release.Name   
spec:
  ports: 
  - port: 80 
    protocol: TCP
    targetPort: 80 
  selector:
    app: web 

[root@k8s-master1 templates]# helm install web4  /root/mychart/  -n default # -n 可指定名称空间
[root@k8s-master1 mychart]# kubectl get pods 


helm install 来源

helm install安装来源:

1. chart仓库: helm install mymaria example/mariadb
2. 一个tar包: helm install mynginx ./nginx-1.2.3.tgz
3. 一个目录:  helm install mynginx ./nginx
4. 绝对的URL: helm install mynginx https://example.com/charts/nginx-1.2.3.tgz
5. repo URL: helm install --repo https://example.com/charts/ mynginx nginx

Helm基本使用:升级

使用Chart升级应用有两种方法:
• --values,-f:指定YAML文件覆盖值
• --set:在命令行上指定覆盖值
注:如果一起使用,–set优先级高
例如将nginx服务升级到1.17版本:
第一种方式:

[root@k8s-master1 ~]# cat update.yaml  
image:
  tag: "1.19"```
```bash
 [root@k8s-master1 ~]# helm upgrade web-16 /root/mychart -f  /root/update.yaml  ```

第二种方式:
```bash
[root@k8s-master1 mychart]# helm upgrade web-16 /root/mychart --set image.tag="1.18"  

用法对比

Helm基本使用:回滚、卸载
查看历史版本

[root@k8s-master1 ~]# helm history web-16 -n default 

回滚到上一个版本:

[root@k8s-master1 ~]# helm rollback web-16 


回滚到指定版本:

[root@k8s-master1 ~]# helm rollback web-16 1 -n default 


卸载应用:

[root@k8s-master1 ~]# helm  uninstall web-16 

Helm基本使用:工作流程

Chart模板

Helm核心是模板,即模板化K8s YAML文件。
通过模板实现Chart高效复用,当部署多个应用时,可以将差异化的字段进行模板化,在部署时使用-f或 者–set动态覆盖默认值,从而适配多个应用。

Chart模板:内置对象

在上面示例中,模板文件中.Release、.Values是Helm内置对象,顶级开头写。

Values对象:为Chart模板提供值,这个对象的值有3个来源:
• chart包中的values.yaml文件
• helm install或者helm upgrade的-f或者–values参数传入的自定义yaml文件
• --set参数传入值
Chart对象:可以通过Chart对象访问Chart.yaml文件的内容,例如: .Chart.AppVersion

Chart模板:调试

使用helm install提供了–dry-run和–debug调试参数,帮助你验证模板正确性,并把渲染后的模板打印出来,而
不会真正的去部署。

# helm install --dry-run web mychart

Chart模板:函数与管道

常用函数:
• quote:将值转换为字符串,即加双引号
• default:设置默认值,如果获取的值为空则为默认值
• indent和nindent:缩进字符串
• toYaml:引用一块YAML内容
• 其他函数:upper(字段变成大写)、title(首字母变成大写)等

quote:将值转换为字符串,即加双引号
示例:nodeSelector标签的值用了true正常使用会报错,这是因为它是关键字,需要加引号才可以。

# values.yaml
nodeSelector: 
gpu: true 
# templates/deployment.yaml

nodeSelector:
disktype:  quote .Values.nodeSelector.gpu 

default:设置默认值,如果获取的值为空则为默认值
示例:以防止忘记定义而导致模板文件缺少字段无法创建资源,这时可以为字段定义一个默认值。

image: " .Values.image.repository : .Values.image.tag | default .Chart.AppVersion 

这里用到了管道符“|”,前面的值传递后函数验证是否为空。

indent和nindent函数都是缩进字符串,主要区别在于nindent会在缩进前多添加一个换行符。
示例:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app:  .Release.Name | indent 6 
app:  .Release.Name | nindent 6 
...

toYaml:引用一块YAML内容
示例:在values.yaml里写结构化数据,引用内容块

# values.yaml
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# templates/deployment.yaml
...
resources:
 toYaml .Values.resources | nindent 10 

Chart模板:流程控制

Helm模板语言提供以下流程控制语句:
• if/else:条件判断
• range:循环
• with:指定变量作用域

Chart模板:流程控制之if/else

条件判断:根据不同的条件做不同的行为
语法:

 if <表达式> 
# 做某事
 else if <表达式> 
# 做某事
 else 
# 默认
 end 


示例:部署一个应用,在没明确启用ingress时,默认情况下不启用


如果值为以下几种情况则为false: • 一个布尔类型 false
• 一个数字 0
• 一个空的字符串
• 一个 nil(空或 null)
• 一个空的集合( map、 slice、 tuple、 dict、 array)

条件表达式也支持操作符:
• eq 等于
• ne 不等于
• lt 小于
• gt 大于
• and 逻辑与
• or 逻辑或

示例:如果是一个空的集合则不启用资源配额

# cat values.yaml 
resources: 
# templates/ingress.yaml
...
    if .Values.resources 
   resources:
       toYaml .Values.resources | indent 10 
    end 

验证渲染结果:

helm install test --dry-run mychart

渲染结果会发现有多余的空行,这是因为模板渲染时会将指令删除,所以原有的位置就空白了。可以使用横杠 “-” 消除空行。
示例:

...
- if .Values.resources 
    resources:
         toYaml .Values.resources | indent 10 
- end 

Chart模板:流程控制之range

循环:一般用于遍历序列结构的数据。例如序列、键值。
语法:

 range <> 
# 引用内容
 end 


示例:遍历数据

# cat values.yaml 
test:
- 1
- 2
- 3
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
 name:  .Release.Name 
data:
 test: |
 - range .Values.test 
   .  # 引用当前元素
 - end 

Chart模板:流程控制之with

with:指定变量作用域
语法:

 with <> 
# 限制范围
 end 

with语句可以允许将当前范围 . 设置为特定的对象,比如我们前面一直使用
的 .Values.nodeSelecotr,我们可以使用 with来将 . 范围指向.Values.nodeSelecotr:
示例:

# cat values.yaml 
...
nodeSelector:
 team: a
 gpu: yes
# cat templates/deployment.yaml 
...
- with .Values.nodeSelector 
nodeSelector:
team:  .team 
gpu:  .gpu 
- end 

with块限制了变量作用域,也就是无法直接引用模板对象,例如.Values、.Release,
如果还想使用,可以定义变量来解决该问题。
示例:

- $releaseName := .Release.Name -
  - with .Values.nodeSelector 
    team:  .team 
    gpu:  .gpu 
    test:  $releaseName 
  - end 

Chart模板:变量

变量是实际应用中不多,但有时候结合with、range能更好处理数据。
示例:k8s变量是键值,可以range遍历生成

# values.yaml
env:
 NAME: "gateway"
 JAVA_OPTS: "-Xmx1G"
# cat templates/deployment.yaml 
...
   env:
   - range $k, $v := .Values.env 
     - name:  $k 
       value:  $v | quote 
   - end 

Chart模板:命名模板

命名模板类似于开发语言中的函数。指一段可以直接被另一段程序或代码引用的程序或代码。
在编写chart时,可以将一些重复使用的内容写在命名模板文件中供公共使用,这样可减少重复编写程序段和简化代码结构。

命名模块使用define定义,template或include引入,在templates目录中默认下划线开头的文件为公共模板(helpers.tpl)。

示例:资源名称生成指令放到公共模板文件,作为所有资源名称

# cat templates/_helpers.tpl
- define "fullname" -
- .Chart.Name -- .Release.Name 
- end -
# cat templates/deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
 name:  template "fullname" . 
..

template指令是将一个模板包含在另一个模板中的方法。但是,template函
数不能用于Go模板管道。为了解决该问题,引入include指令。
示例:

# cat _helpers.tpl
- define "labels" -
app:  template "fullname" . 
chart: " .Chart.Name - .Chart.Version "
release: " .Release.Name "
- end -
# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
name:  include "fullname" . 
labels:
  - include "labels" . | nindent 4 
...

写一个通用的Chart

1. 先创建模板示例 helm create demo
2. 修改Chart.yaml,Values.yaml,参考示例预留变动的字段值
3. 在templates目录下准备部署应用所需的yaml文件,并添加指令引用
Values.yaml字段
4. 将重复使用的内容作为命名模板
5. 使用Chart结合参数部署多个同类服务

使用Harbor作为Chart仓库

Harbor是一个主流的镜像仓库系统,在 v1.6 版本以后的 harbor 中新增加了 helm charts 的管理功能,可以存储Chart文件。
使用步骤:

1、启用Harbor的Chart仓库服务
# ./install.sh --with-chartmuseum
启用后,默认创建的项目就带有helm charts功能了。
2、安装push插件
helm plugin install https://github.com/chartmuseum/helm-push
3、添加repo
helm repo add --username admin --password Harbor12345 myrepo 
http://192.168.31.70/chartrepo/library
helm repo update
4、推送
# helm push demo-0.1.0.tgz --username=admin --password=Harbor12345 
http://192.168.31.70/chartrepo/library
5、部署
# helm install web --version 0.1.0 myrepo/demo

公共Chart仓库

官方维护一个公共仓库,可直接使用它们制作好的包。
官方仓库:https://artifacthub.io

例如使用Chart部署Dashboard:https://artifacthub.io/packages/helm/k8s-dashboard/kubernetes-dashboard

以上是关于kubernetes软件包管理器Helm的主要内容,如果未能解决你的问题,请参考以下文章

kubernetes软件包管理器Helm

kubernetes软件包管理器Helm

kubernetes软件包管理器Helm

轻松学Kubernetes 的包管理器-Helm

使用 Helm 3 包管理器在 Kubernetes 集群上安装软件

使用 Helm 3 包管理器在 Kubernetes 集群上安装软件