Kubernetes部署应用利器Helm详解

文章目录

  • 一、helm概述&安装
    • 1.为什么需要Helm
    • 2.Helm介绍
    • 3.Helm架构
    • 4.部署Helm客户端
    • 5.Helm基本使用
      • 5.1 创建Chart示例
  • 二、Helm 应用部署、升级
    • 1.创建项目(chat所需目录、文件)
    • 2.创建/拷贝项目的yaml文件到templates目录下
    • 3.使用Helm进行部署项目
    • 4.Helm升级/更新项目
    • 5.Helm回滚/卸载项目
      • 5.1回滚到上一个版本
      • 5.2回滚到指定版本
      • 5.3卸载项目
    • 6.Helm工作流程
  • 三、Chart模板
    • 1.内置对象
    • 2.调试
    • 3.函数与管道
    • 4.动态读取文件内容
    • 5.流程控制-if/else判断
    • 6.流程控制-range循环
    • 7.流程控制-with变量作用域
    • 8.变量
    • 9.命名模板
  • 四、使用Harbor私有仓库集中管理Chart
    • 1.启用Harbor的Chart仓库服务
    • 2.安装push插件
    • 3.添加repo仓库
    • 4.推送
    • 5.部署chart
  • 五、公共Chart仓库
    • 1.本地添加dashborad的库
    • 2.直接部署dashboard
    • 3.将dashboard的chart下载到本地进行修改
  • 六、一步步编写Chart模版


一、helm概述&安装

1.为什么需要Helm

(为了更高效的部署管理我们的应用)
由于kubernetes缺少对发布的应用版本控制和管理,使得部署的应用维护和更新等方面面临诸多的挑战,主要面临以下问题;

  • 目前YAML资源文件分散,如何将这些YAML作为一个整体进行管理?
  • 这些YAML资源文件如何高效的复用?
  • 不支持应用级别的版本管理!例如回滚,目前只支持单个Depolyment

2.Helm介绍

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

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

3.Helm架构

Helm目前有两个大版本:V2和V3
2019年11月Heml团队发布V3版本,相比于V2版本最大的变化是将Tiller删除,并大部分代码重构
在这里插入图片描述
V2工作流程:
helm客户端通过yaml将chart部署到k8s里面,会经过一个组件Tiller,这个组件起到了一个承上启下的作用,它负责接收客户端的请求,再调用K8s的api完成部署;

V3工作流程
helm客户端通过kubeconfig去连接k8s集群去完成应用的部署,跟kubectl一样;

4.部署Helm客户端

使用Helm很简单,只需要下载一个二进制的客户端包即可,它会通过kubeconfig配置(默认是在$HOME/.kube/config)来链接kubernetes。
项目地址:
下载Helm客户端:https://github.com/helm/helm
Helm官网:https://helm.sh/

在这里插入图片描述

[root@k8s-master ~]# wget -c https://get.helm.sh/helm-v3.13.3-linux-amd64.tar.gz
[root@k8s-master ~]# tar -zxf helm-v3.13.3-linux-amd64.tar.gz
#解压完之后直接将二进制文件helm丢到 二进制目录下即可执行helm命令
[root@k8s-master ~]# mv linux-amd64/helm /usr/bin/
[root@k8s-master ~]# helm --help

5.Helm基本使用

Helm管理应用生命周期:

  • helm create 创建Chart示例
  • helm install 部署
  • helm upgrade 更新
  • helm rollback 回滚
  • helm uninstall 卸载

5.1 创建Chart示例

创建chart:
helm create mychart #示例中默认是部署一个nginx服务
打包chart:
helm package mychart

[root@k8s-master ~]# helm create mychart 
Creating mychart
[root@k8s-master ~]# cd mychart/
[root@k8s-master mychart]# ll 
总用量 8
drwxr-xr-x 2 root root    6 45 22:21 charts
-rw-r--r-- 1 root root 1143 45 22:21 Chart.yaml
drwxr-xr-x 3 root root  162 45 22:21 templates
-rw-r--r-- 1 root root 2252 45 22:21 values.yaml
  • charts:目录里存放这个chart依赖的所有子chart;
  • Chart.yaml:用于描述这个Chart的基本信息,包括名字、描述信息及版本等;
  • values.yaml:用于存储templates目录中模板文件中用到的 变量 的值;
  • templates:目录里面存放所有的yaml模板文件,例如deployment,service,ingress等;
    • NOTES.txt:用于介绍Chart的帮助信息,helm install部署后展示给用户,例如:如何使用这个Chart、列出缺省的设置等;
    • _helpers.tpl:放置模板的地方,可以在整个chart中重复使用;
[root@k8s-master mychart]# helm install demo /root/mychart/
#部署信息
NAME: demo
LAST DEPLOYED: Fri Apr  5 22:33:10 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
#部署提示(NOTES.txt中的内容)
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=demo" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT

#列出之前的部署情况
[root@k8s-master mychart]# helm list 
NAME	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART        	APP VERSION
demo	default  	1       	2024-04-05 22:33:10.226678647 +0800 CST	deployed	mychart-0.1.0	1.16.0  

#然后使用kubectl就可以看到使用chart部署的这个pod示例了
[root@k8s-master mychart]# kubectl get pods,svc
NAME                                          READY   STATUS              RESTARTS   AGE
pod/demo-mychart-6fd7f6cd64-fjnwc             0/1     ContainerCreating   0          2s


NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/demo-mychart   ClusterIP   10.97.197.171   <none>        80/TCP    2s

#卸载chart
[root@k8s-master mychart]# helm uninstall demo
release "demo" uninstalled


二、Helm 应用部署、升级

命令描述
completion命令补全,source <(helm completion bash)
create创建一个chart并指定名字
dependency管理chart依赖
get下载一个release。可用子命令:all、hooks、manifest、notes、values
help命令的帮助文档
history获取release历史
install安装一个chart
list列出一个release
package将chart目录打包到chart存档文件中
pull从远程仓库中下载chart并解压到本地 #helm pull stable/mysql --untar
repo添加、列出、移除、更新和索引chart仓库。可用子命令:add、index、list、remove、update
rollback从之前的版本回滚
search根据关键字搜索chart。可用子命令:hub、repo
show查看chart详细信息。可用子命令:all、chart、readme、values
status显示已命名版本的状态
template本地呈现渲染模版
uninstall卸载一个release
upgrade更新一个release
version查看helm客户端版本

接下来我们先使用helm自定义创建部署一个chant应用

1.创建项目(chat所需目录、文件)

[root@k8s-master ~]# mkdir chart-prod
[root@k8s-master ~]# cd chart-prod/
[root@k8s-master chart-prod]# touch Chart.yaml

#这里需要编辑Chart.yaml文件里的内容,否则在使用helm部署项目时候会报错(可以直接复制helm create xxx 生成的Chart.yaml模板内容进行修改)
[root@k8s-master chart-prod]# vim Chart.yaml
apiVersion: v2
#chart的名称
name: chart-prod
#chart的描述
description: This is chart-prod
#类型默认
type: application
#chart的版本随便写
version: 0.1.0
#应用的版本随便写即可
appVersion: "1.16.0"

[root@k8s-master chart-prod]# touch values.yaml
[root@k8s-master chart-prod]# mkdir templates
[root@k8s-master chart-prod]# touch templates/_helpers.tpl
[root@k8s-master chart-prod]# touch templates/NOTES.txt

#最终目录结构如下
[root@k8s-master ~]# tree chart-prod/
chart-prod/
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

1 directory, 6 files

2.创建/拷贝项目的yaml文件到templates目录下

这里就是将我们项目的deployment/service/ingress的yaml文件拷贝或创建到我们的templates目录下
Ps:我这里直接创建一个nginx的deployment/service

[root@k8s-master ~]# kubectl create deployment web --image=nginx:1.16 --dry-run=client -o yaml > deployment.yaml
[root@k8s-master ~]# kubectl create service nodeport web --tcp=80:80 --dry-run=client -o yaml > service.yaml
[root@k8s-master ~]# mv deployment.yaml chart-prod/templates/
[root@k8s-master ~]# mv service.yaml chart-prod/templates/

#以上的操作只是将原本就可以部署的yaml文件移动到templates目录下,并不能发挥到helm的能力,解决我们的痛点(痛点是第一步,为什么使用helm)

#接下来才是真正的使用helm 修改 deployment的值 使用 valumes.yaml文件中的变量(这样可以方便后期一个yaml部署多个项目)

[root@k8s-master chart-prod]# vim templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  #使用内置变量.Release.Name 动态的来生成资源名称 这个名称使用的是 "heml install xxx" 时的 xxx 
  #如果不修改为这个内置变量的话在使用同一套chart创建多个项目的时候会报已经有这个deployemnt资源的错,因为k8s的资源名称必须是唯一的!  
  name: {{ .Release.Name }}
spec:
  #使用在values.yaml文件中自定义的变量replicas的值
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      #使用在values.yaml文件中自定义的变量image的值
      - image: {{ .Values.image }}
        name: nginx
        
#service也是同理
[root@k8s-master chart-prod]# vim templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: {{ .Release.Name  }}
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort
  
#在values.yaml中添加要在templates目录下yaml文件中要修改的值  
[root@k8s-master chart-prod]# vim values.yaml 
replicas: 3
image : nginx:1.16


#现目录结构如下
[root@k8s-master chart-prod]# tree templates/
templates/
├── deployment.yaml
├── _helpers.tpl
├── NOTES.txt
└── service.yaml

0 directories, 4 files

3.使用Helm进行部署项目

使用helm部署/更新等操作时候,可以用 -n 来指定命名空间

[root@k8s-master ~]# helm install web /root/chart-prod/ -n default 
NAME: web
LAST DEPLOYED: Sat Apr  6 00:28:41 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

[root@k8s-master ~]# helm list 
NAME	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART           	APP VERSION
web 	default  	1       	2024-04-06 00:28:41.408736547 +0800 CST	deployed	chart-prod-0.1.0	1.16.0   

[root@k8s-master ~]# kubectl get pods,svc 
NAME                                          READY   STATUS              RESTARTS   AGE
pod/web-96d5df5c8-hw5cj                       1/1     Running             0          80s
pod/web-96d5df5c8-spqvn                       1/1     Running             0          80s
pod/web-96d5df5c8-w7lzm                       1/1     Running             0          80s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        86d
service/web            NodePort    10.104.133.20   <none>        80:30451/TCP   81s

[root@k8s-master ~]# curl -I 10.104.133.20
HTTP/1.1 200 OK
Server: nginx/1.16.1
...

4.Helm升级/更新项目

使用Chart升级应用有两种方法:

  • –values,-f:指定YAML对原有的templates目录下的yaml中的值进行覆盖以达到升级效果
  • –set:在命令行上直接指定覆盖值进行升级

示例:将上面部署的 nginx1.16.1版本 升级为 nginx1.17版本,副本数从3修改为1

第一种方式(指定yaml文件进行覆盖):

[root@k8s-master ~]# vim abc.yaml #在任意路径都行
replicas: 1
image : nginx:1.17

[root@k8s-master ~]# helm upgrade web /root/chart-prod/ -f abc.yaml 
Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Sat Apr  6 01:04:43 2024
NAMESPACE: default
STATUS: deployed
#可以发现这里版本已经变成升级为2了
REVISION: 2
TEST SUITE: None

#此时去验证nginx是否升级为1.17
[root@k8s-master ~]# kubectl get pods,svc 
NAME                                          READY   STATUS    RESTARTS   AGE                       1/1     Running   1          10d
pod/web-5899d78c9-wff2z                       1/1     Running   0          79s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        86d
service/web            NodePort    10.99.157.130   <none>        80:30457/TCP   9m45s

[root@k8s-master ~]# curl -I 10.99.157.130
HTTP/1.1 200 OK
Server: nginx/1.17.10

第二种方式(在命令行使用–set进行覆盖):

[root@k8s-master ~]# helm upgrade web /root/chart-prod/ --set image=nginx:1.17 --set replicas=1
Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Sat Apr  6 01:11:06 2024
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None

5.Helm回滚/卸载项目

heml查看历史版本

[root@k8s-master ~]# helm history web
REVISION	UPDATED                 	STATUS    	CHART           	APP VERSION	DESCRIPTION     
1       	Sat Apr  6 01:11:58 2024	superseded	chart-prod-0.1.0	1.16.0     	Install complete
2       	Sat Apr  6 01:12:05 2024	deployed  	chart-prod-0.1.0	1.16.0     	Upgrade complete

5.1回滚到上一个版本

#现在版本nginx1.17 副本数为1,回滚到nginx1.16 副本数为3

[root@k8s-master ~]# helm rollback web 
Rollback was a success! Happy Helming!

[root@k8s-master ~]# kubectl get pods,svc 
NAME                                          READY   STATUS    RESTARTS   AGE
pod/web-6bc4dfc596-dgrck                      1/1     Running   0          16s
pod/web-6bc4dfc596-njf9d                      1/1     Running   0          18s
pod/web-6bc4dfc596-prtl9                      1/1     Running   0          14s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        86d
service/web            NodePort    10.103.75.187   <none>        80:31867/TCP   4m37s

[root@k8s-master ~]# curl -I 10.103.75.187 
HTTP/1.1 200 OK
Server: nginx/1.16.1
...

5.2回滚到指定版本

回滚到指定版本的话需要指定 历史版本的版本号
在这里插入图片描述

[root@k8s-master ~]# helm rollback web 1
Rollback was a success! Happy Helming!

Ps:
我们可以在每次部署/升级的时候使用 –description 来添加描述,例如:当前的版本是多少,这样可以方便我们后期回滚时查看到我们的版本记录

[root@k8s-master ~]# helm install web /root/chart-prod/ --description v1.17
[root@k8s-master ~]# helm upgrade web /root/chart-prod/ --set image=nginx:1.18 --set replicas=1 --description v1.18

在这里插入图片描述

5.3卸载项目

[root@k8s-master ~]# helm uninstall web

6.Helm工作流程

在这里插入图片描述

  1. 从镜像仓库拉取chart,这个chart里会包含我们项目所需的各个yaml模板,例如deployment、service、ingress等;
  2. helm将values对象(chart保重values.yaml文件/helm install、helm upgrade的-f参数传入的自定义yaml文件/–set参数传入的值)合并渲染到我们的yaml模板中形成完整的yaml清单;
  3. helm再将应用发布到k8s里;



三、Chart模板

Helm核心是模板,即模板化k8s YAML文件。
通过模板实现Chart高效复用,当部署多个应用时,可以将差异化的字段进行模板化,在部署时使用-f或者–set动态覆盖默认值,从而适配多个应用
Helm模板由Go  Template编写,指令由于{​{ }}包裹

1.内置对象

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

Release对象:获取发布记录信息

内置描述
Release.Namerelease名称(helm install xxx 名称就是这个xxx)
Release.Timerelease的时间
Release.Namespacerelease的命名空间
Release.Servicerelease服务的名称
Release.Revisionrelease的修订版本号,从1开始累加

Values对象:为Chart模板提供值,这个对象的值有3个来源:

  • chat包中的values.yaml文件
  • helm install或者helm upgrade的-f或者–values参数传入的自定义yaml文件
  • –set参数传入值

Chart对象:可以通过Chart对象访问Chart.yaml文件的内容,例如:{{ .Chart.AppVersion }}

2.调试

作用:当使用从网上下载的chart时,想知道它都使用了那些资源,资源的配置是什么,这个时候就能用–dry-run 或者 --template来列出来查看;

本地呈现渲染结果(查看下载后默认渲染的资源文件)

#helm template mychart

在这里插入图片描述
还可以在helm install 时使用 –dry-run和**–debug**进行调试参数,帮助验证模版的正确性,并把渲染后的模版打印出来,而不去真正的去部署;
如下:
在这里插入图片描述

–dry-run和–template的区别在于前者会经过k8s校验,使用时可以加-f或者–set参数,后者不会经过校验也不能使用参数 只能查看下载后默认的资源配置;

3.函数与管道

常用函数:

  • quote:将值转换为字符串,也就是加上双引号
  • default:设置默认值,如果获取的值为空则使用默认值
  • indentnindent:缩进字符串
  • toYaml:引用一块YAML内容
  • 其他函数:upper、title等

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

#values.yaml
nodeSelector:
  gpu: true

#templates/deployment.yaml
...
      nodeSelector:
        gpu: {{ quote .Values.nodeSelector.gpu }}

可以用–dry-run调试命令查看会发现true 加上了双引号
[root@k8s-master templates]# helm upgrade web /root/chart-prod/ --dry-run
在这里插入图片描述

default:设置默认值,如果获取的值为空则使用默认值
示例:以防止忘记定义而导致模版文件缺少字段无法创建资源,这时可以为字段定义一个默认值;
image: {{ .Values.image }}:{{ .Values.tag | default “1.19” }}
这里会用到管道符"|",前面的值传递后函数验证是否为空;

#values.yaml
image : nginx
tag: ""

#templates/deployment.yaml
...
      containers:
      - image: {{ .Values.image }}:{{ .Values.tag | default "1.19" }}
      或者使用Chart的版本号作为默认值
      - image: {{ .Values.image }}:{{ .Values.tag | default .Chart.AppVersion }}

如果不设置默认值的话,在install / upgrade时会报如下错误
在这里插入图片描述

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

#templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    #indent 6 代表缩进6个空格
    #nindent 6 代表换行并缩进6个空格
    app: {{ .Release.Name | indent 6 }}
    app: {{ .Release.Name | nindent 6 }}

效果为:
在这里插入图片描述
indent和nindent的使用场景:
经常会在引用一个块Yaml的时候使用,例如下面要看的toYaml

toYaml:引用一块YAML内容
普遍{{ .Values.xxx.xxx }}这种key value格式适合不变化的字段,而toYaml可以适用于经常变化的字段,不管选中的块yaml里有没有变化的字段,都可以直接按一个整体传入到模版里

示例

#values.yaml
...
resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

#templates/deployment
...
      containers:
      #使用在values.yaml文件中自定义的变量image的值
      - image: {{ .Values.image }}:{{ .Values.tag | default .Chart.AppVersion  }}
        name: nginx
        resources: {{ toYaml .Values.resources | nindent 10}}
        #也可以使用indent
        #resources: 
#{{ toYaml .Values.resources | indent 10}}

在这里插入图片描述

其他函数:upper、title等
upper:将引用的值大写
title:将引用的值首字母大写

例如
upper

#values.yaml
nodeSelector:
  gpu: true
  
#templates/deployment.yaml
...
metadata:
  labels:
    app: {{ upper .Release.Name }}
...
    spec:
      nodeSelector:
        gpu: {{ quote .Values.nodeSelector.gpu | upper}}

在这里插入图片描述
在这里插入图片描述

例如:
title

#values.yaml
nodeSelector:
  gpu: true
  
#templates/deployment.yaml
...
metadata:
  labels:
    app: {{ title .Release.Name }}
...
    spec:
      nodeSelector:
        gpu: {{ quote .Values.nodeSelector.gpu | title}}

在这里插入图片描述
在这里插入图片描述

4.动态读取文件内容

有时想从文件中(例如a.txt)导入内容,可以通过.Files对象进行实现

.Files.Get可以获取文件的内容传到configmap里
.Files.Glob方法返回所有匹配的文件路径列表,当做个文件时,可以更灵活的提取某些文件(多个)

示例:configmap动态读取文件内容
普遍的configmap如下
在这里插入图片描述

.Files.Get可以获取文件的内容传到configmap里
例如单独创建一个redis的配置文件

[root@k8s-master chart-prod]# pwd 
/root/chart-prod
[root@k8s-master chart-prod]# mkdir files
[root@k8s-master chart-prod]# vim files/config.yaml
name: fandaoshuai
host: 192.168.1.1
port: 6379


[root@k8s-master chart-prod]# vim templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  config.yaml: |
#"files/config.yaml为文件所在的绝对目录"
{{ .Files.Get "files/config.yaml" | indent 4}}

#若有多个文件且文件名称固定的话,可以用这种方式继续往下写
  #config.yaml: |
#{{ .Files.Get "files/config2.yaml" | indent 4}}

然后保存调试一下
在这里插入图片描述

上面是将单个文件的内容传到configmap中,其实也可以同时将多个文件都传入configmap中;

.Files.Glob方法返回所有匹配的文件路径列表,当做个文件时,可以更灵活的提取某些文件

#files/config.yaml 
name: fandaoshuai
host: 192.168.1.1
port: 6379

#files/config2.yaml
name: zt
javajdbc: http://192.168.1.2:3306

#templates/configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  {{- $root := . }}
  {{- range $path, $bytes := .Files.Glob "files/*.yaml" }}
  {{ base $path }}: | 
{{ $root.Files.Get $path | indent 4 }}
  {{- end  }}

配置完成后进行–dry-run调试
在这里插入图片描述

5.流程控制-if/else判断

Helm模版语言提供一下流程控制语句

  • if/else:条件判断
  • range:循环
  • with:指定变量作用域

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

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

在这里插入图片描述
示例:部署一个应用,在没明确启用ingress时,默认情况下不启用

#values.yaml
ingress:
  enabled: false

#templates/ingress.yaml
{{ if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Release.Name }}
  #annotations:
    #nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: "web.study.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: {{ .Release.Name }}
            port:
              number: 80
{{ end  }}

这样是默认不启用的,除非在部署更新调试时将enabled的值改为true,–set ingress.enabled=true 或者 直接修改values.yaml文件里enabled的值才可以启用

ps:
如果值为以下几种情况则为false(按照上面这个例子,是不会启用ingress的):

  • 一个布尔类型 false
  • 一个数字 0
  • 一个空的字符串
  • 一个nil(空或null)
  • 一个空的集合(map、slice、tuple、dict、array)

条件表达式也支持操作符:

  • eq 等于
  • ne 不等于
  • lt 小于
  • gt 大于
  • and 逻辑与
  • or 逻辑或

例如 标签的值eq等于456话,输出123,否则输出456

#values.yaml
label:
  test: "123"

#templates/deployment.yaml
...
  labels:
    {{ if eq .Values.label.test "456" }}
    test: "123"
    {{ else }}
    test: "456"
    {{ end }}

现在调试的话输出的值为456
在这里插入图片描述
修改values.yaml的值为456的话在此调试这个test标签的值会变为123

在我们配置完进行调试/渲染的时候,会发现有多余的空行,这是因为模版渲染时会将指令删除,所以原有的位置就空白了。可以使用横杠"-"消除空行;
例如:

#templates/deployment.yaml
...
    {{- if eq .Values.label.test "456" }}
    test: "123"
    {{- else }}
    test: "456"
    {{- end }}

在这里插入图片描述

6.流程控制-range循环

循环:一般用于遍历序列结构的数据。例如序列、键值等
语法:
{{ range <值> }}
#引用内容
{{ end }}
在这里插入图片描述
示例:将values里的内容遍历出来

#values.yaml
test:
- 1
- 2
- 3

#templates/config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  test: |
  {{- range.Values.test }}
    {{ . }} #引用当前内容
  {{- end }}

然后进行调试
在这里插入图片描述

7.流程控制-with变量作用域

指的是指定变量的生效范围(简化代码)

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

示例:指定nodeSelector为作用域

#values.yaml
nodeSelector:
  gpu: "true"
  disktype: ssd

#templates/deployment.yaml
...
    spec:
      {{- with .Values.nodeSelector }}
      nodeSelector:
        #gpu: {{ .Values.nodeSelector.gpu }}
        #在正常不使用作用域的情况下需要这样进行引用values.yaml中的值,当把values.yaml中的nodeSelector做成作用域的话即可直接引用相应的值,如下:
        #调试时,需要把这几行的注释给删掉,要不然会报错
        gpu: {{ .gpu }}
        disktype: {{ .disktype }}
      {{- end }}
      containers:                                                                

这样看with块是限制了变量作用域,也就是无法直接引用模版对象,例如.Values、.Release,如果还想使用这种方式的话,可以定义变量来解决这个问题

示例:在with作用域中引用模版对象

#values.yaml
nodeSelector:
  gpu: true
  disktype: ssd

#templates/deployment.yaml
...
    spec:
      #定义变量$disktype来引用.Values.nodeSelector.disktype
      {{- $disktype := .Values.nodeSelector.disktype }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        gpu: {{ .gpu }}
        #这里来使用变量即可
        disktype: {{ $disktype }}
      {{- end }}
      containers:

8.变量

变量在实际应用中不多,但有时候结合with、range能够更好的处理数据;

示例:在k8s中变量是键值 ,可以range遍历生成并引用

#values.yaml
env:
  SERVER_NAME: protal
  PORT: 80 
  HOST: 127.0.0.1

#templates/deployment.yaml
...
        resources: {{ toYaml .Values.resources | nindent 10}}
        env:
       {{- range $k,$v := .Values.env }}
        - name: {{ $k }}
          value: {{ quote $v }}
       {{- end }}

调试查看yaml效果
在这里插入图片描述

9.命名模板

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

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

示例:我们可以在template目录下的所有yaml资源中找到共同使用的字段配置,这里用"name"和"labels"字段来举例,把它加入模板 供我们引用;
ps:#只有使用命名模板的时候会在右边产生空行,所以也需要在开头右边加上"-"

#templates/_helpers.tpl
#name
{{- define "fullname" -}}
{{ .Chart.Name }}-{{ .Release.Name }}
{{- end -}}

#templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  #使用template 进行引用模板中的键获取值
  name: {{ template"fullname" . }}
...

dry-run调试结果如下
helm install web /root/chart-prod/ --dry-run
在这里插入图片描述

template指令是将一个模板包含在另一个模板中的方法(yaml资源可以引用模板中的键获取值),但是template函数不能用于Go模板通道。为了解决这个问题,引入include指令,如下lables:

#labels
#values.yaml
label:
  project: www
  app: nginx

#templates/_helpers.tpl
#labels
{{- define "labels" -}}
project: {{ .Values.label.project }}
app: {{ .Values.label.app }}
chartname: {{ .Chart.Name }}
{{- end -}}

#templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels: {{ include "labels" . | nindent 4 }}
  name: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels: {{ include "labels" . | nindent 6 }}

#templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ include "fullname" .}}
spec:
...
  selector: {{ include "labels" . | nindent 4}}

dry-run调试结果如下
helm install web /root/chart-prod/ --dry-run
在这里插入图片描述
在这里插入图片描述



四、使用Harbor私有仓库集中管理Chart

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

前置条件:

#给编写好的helm进行打包
[root@k8s-master ~]# helm package chart-dev
[root@k8s-master ~]# ll
drwxr-xr-x 5 root root     4096 Apr 16 16:04 chart-dev
-rw-r--r-- 1 root root     3982 Apr 16 17:18 chart-dev-0.1.0.tgz

1.启用Harbor的Chart仓库服务

[root@iZbp1j85tynrpi0u439x2cZ harbor]# pwd 
/hqtbj/hqtwww/harbor_workspace/harbor
[root@iZbp1j85tynrpi0u439x2cZ harbor]# ./install.sh --with-chartmuseum

在这里插入图片描述
启用后,默认创建的项目就带有helm charts功能了
在这里插入图片描述

2.安装push插件

[root@k8s-master ~]# helm plugin install https://github.com/chartmuseum/helm-push

也可以直接将二进制包下载下来解压然后把解压过后的 bin目录以及/plugin.yaml放在helm的plugin目录下即可

[root@k8s-master ~]# tar -zxf helm-push_0.10.4_linux_amd64.tar.gz
[root@k8s-master ~]# ls 
bin plugin.yaml
[root@k8s-master ~]# ls bin/
helm-cm-push

[root@k8s-master helm]# cd $HOME/.cache/helm
[root@k8s-master helm]# mkdir plugins/cm-push
[root@k8s-master helm]# mv /root/plugin.yaml /root/bin plugins/cm-push/

3.添加repo仓库

在这里插入图片描述

[root@k8s-master ~]# helm repo add --username admin --password xxxxxx myrepo https://dev-registry.hqxxx.net/chartrepo/library
"myrepo" has been added to your repositories
[root@k8s-master ~]# helm repo update 
[root@k8s-master ~]# helm repo list 
NAME    URL                                              
myrepo  https://dev-registry.hqxxx.net/chartrepo/library

4.推送

[root@k8s-master ~]# helm cm-push chart-dev-0.1.0.tgz --username admin --password xxxx https://dev-registry.hqxxx.net/chartrepo/library
Pushing chart-dev-0.1.0.tgz to https://dev-registry.hqtong.net/chartrepo/library...
Done.

在这里插入图片描述
在这里插入图片描述

5.部署chart

当我们把打包好的chart上传至harbor仓库后,后续进行部署时就可以直接在仓库里拉取进行部署,类似于镜像一样

[root@k8s-master ~]# helm repo list 
NAME    URL                                              
myrepo  https://dev-registry.hqtong.net/chartrepo/library

[root@k8s-master ~]# helm install energy-order-api --version 0.1.0 myrepo/chart-dev

–version:这里的version是chart的版本号,在打包时可以修改chart目录里的Chart.yaml文件进而改变上传到harbor的版本

# chart-dev/Chart.yaml 
version: 0.1.0

在这里插入图片描述



五、公共Chart仓库

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

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

1.本地添加dashborad的库

[root@k8s-master ~]# helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
[root@k8s-master ~]# helm repo list 
NAME                    URL                                    
kubernetes-dashboard    https://kubernetes.github.io/dashboard
[root@k8s-master ~]# helm repo update 

2.直接部署dashboard

#因为我的集群版本是v1.20.11 最新的dashboard不支持这个版本,所以我直接指定的老版本进行的部署
在这里插入图片描述

[root@k8s-master ~]# helm install kubernetes-dashboard --version 6.0.8 kubernetes-dashboard/kubernetes-dashboard

#使用edit修改svc的类型为NodePort来访问试下
[root@k8s-master ~]# kubectl edit service/kubernetes-dashboard 
...
  type: NodePort
[root@k8s-master ~]# kubectl get pod,svc
NAME                                         READY   STATUS    RESTARTS   AGE                         1/1     Running   0          251d
pod/kubernetes-dashboard-7bfccf4c5b-gglnq    1/1     Running   0          5m52s

NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes              ClusterIP   10.96.0.1        <none>        443/TCP          296d
kubernetes-dashboard    NodePort    10.97.23.85      <none>        443:31502/TCP    15m

在这里插入图片描述
后续获取个token就可以了,这里略过 可以参考:https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

3.将dashboard的chart下载到本地进行修改

上面我们是直接对公共仓库里的chart进行部署的,我们可以将它的chart下载下来查看都使用了哪些资源并可以自己修改;

[root@k8s-master ~]# helm pull kubernetes-dashboard/kubernetes-dashboard --version 6.0.8
[root@k8s-master ~]# ll 
total 27972
-rw-r--r-- 1 root root      18717 Apr 17 11:18 kubernetes-dashboard-6.0.8.tgz

[root@k8s-master ~]# tar -zxf kubernetes-dashboard-6.0.8.tgz
[root@k8s-master kubernetes-dashboard]# ll 
total 36
-rw-r--r-- 1 root root   247 May 19  2023 Chart.lock
drwxr-xr-x 3 root root  4096 Apr 17 11:22 charts
-rw-r--r-- 1 root root   602 May 19  2023 Chart.yaml
-rw-r--r-- 1 root root  7068 May 19  2023 README.md
drwxr-xr-x 2 root root  4096 Apr 17 11:22 templates
-rw-r--r-- 1 root root 11605 May 19  2023 values.yaml

#可以使用dry-run查看渲染后使用的资源
[root@k8s-master ~]# helm install kubernetes-dashboard /root/kubernetes-dashboard  --dry-run

#修改service的类型为Nodeport类型
[root@k8s-master ~]# vim kubernetes-dashboard/values.yaml
...
service:
  直接将ClusterIP改为需要的Nodeport类型即可
  #type: ClusterIP
  type: NodePort
  # Dashboard service port
  externalPort: 443

六、一步步编写Chart模版

详情可见:https://download.csdn.net/download/qq_44930876/89155278


总结:以上就是关于helm的学习与总结,到这里我们就可以一步步的编写我们服务所用到的chart了,健康检查、资源限制、数据持久化、污点亲和性等等;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/552373.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十五届蓝桥杯复盘python大学A组——试题B 召唤数学精灵

按照正常思路解决&#xff0c;由于累乘消耗大量时间&#xff0c;因此这不是一个明智的解决方案。 这段代码执行速度非常慢的原因在于它试图计算非常大的数的阶乘&#xff08;累乘&#xff09;&#xff0c;并且对于每一个i的值都执行这个计算。阶乘的增长是极其迅速的&#xff…

49.HarmonyOS鸿蒙系统 App(ArkUI)Tab导航组件的使用

HarmonyOS鸿蒙系统 App(ArkUI)Tab导航组件的使用 图片显示 Row() {Image($r(app.media.leaf)).height(100).width(100)Image($r(app.media.icon)).height(100).width(100) } 左侧导航 import prompt from ohos.prompt; import promptAction from ohos.promptAction; Entry C…

vue2知识点1 ———— (vue指令,vue的响应式基础)

vue2的知识点&#xff0c;更多前端知识在主页&#xff0c;还有其他知识会持续更新 Vue 指令 Vue指令是Vue.js中的一个重要概念&#xff0c;用于向DOM元素添加特定行为或功能。Vue指令以v-开头&#xff0c;例如v-bind、v-if、v-for等。 v-bind 动态绑定属性 用法&#xff1a…

windows ubuntu 子系统:肿瘤全外篇,2. fq 数据质控,比对。

首先我们先下载一组全外显子测序数据。nabi sra库&#xff0c;随机找了一个。 来自受试者“16177_CCPM_1300019”(SRR28391647, SRR28398576)的样本“16177_CCPM_1300019_BB5”的基因组DNA配对端文库“0369547849_Illumina_P5-Popal_P7-Hefel”的Illumina随机外显子测序 下载下…

SGI_STL空间配置器源码剖析(一)总览

SGI 全称为 Silicon Graphics [Computer System] Inc. 硅图[计算机系统] 公司&#xff0c;SGI_STL是SGI实现的C的标准模板库。 SGI STL的空间配置器包括一级和二级两种。 一级空间配置器allocator采用malloc和free来管理内存&#xff0c;这与C标准库中提供的allocator是相似的…

VS集成vcpkg

VS集成vcpkg 下载vcpkg 下载vcpkg git clone https://github.com/Microsoft/vcpkg.git安装vcpgk&#xff0c;文件目录 .\bootstrap-vcpkg.bat集成到vs2022中 # 集成到项目 vcpkg integrate project vcpkg integrate installPS C:\Users\Administrator> vcpkg integrate…

大模型开发轻松入门——(1)从搭建自己的环境开始

pip install openai import openai import osfrom dotenv import load_dotenv, find_dotenv _ load_dotenv(find_dotenv())openai.api_key os.getenv(OPENAI_API_KEY)

如何选择投资交易策略?很简单,只需回答fpmarkets6个问题

刚迈出交易的第一步的投资新手们&#xff0c;是不是还没有选择策略&#xff1f;外汇市场上的交易策略是一种算法&#xff0c;可以让投资者以最低的风险尽快实现目标。目标通常是获得一定比例的利润。 那么如何选择投资交易策略&#xff1f;很简单&#xff0c;只需回答fpmarkets…

计算机网络 2.2数据传输方式

第二节 数据传输方式 一、数据通信系统模型 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 1.数据终端设备&#xff08;DTE&#xff09; 作用&#xff1a;用于处理用户数据的设备&#xff0c;是数据通信系统的信源和信宿。 设备&#xff1a;便携计算机…

酒店餐厅装水离子雾化壁炉前和装后对比

酒店餐厅装水离子雾化壁炉前和装后的对比可以体现出餐厅氛围和客户体验的显著改变&#xff1a; 装前&#xff1a; 普通的氛围&#xff1a;餐厅可能显得比较普通&#xff0c;缺乏特色或独特的装饰元素。 视觉上缺乏焦点&#xff1a;餐厅空间可能显得相对平淡&#xff0c;缺乏…

如何在MacOS上使用OpenHarmony SDK交叉编译?

本文以cJSON三方库为例介绍如何通过OpenHarmony的SDK在Mac平台进行交叉编译。 环境准备 SDK准备 我们可以通过 openHarmony SDK 官方发布渠道下载对应mac版本的SDK&#xff0c;当前OpenHarmony MAC版本的SDK有2种&#xff0c;一种是x86架构&#xff0c;另一种是arm64&#x…

【小白学机器学习13】一文理解假设检验的反证法,H0如何设计的,什么时候用左侧检验和右侧检验,等各种关于假设检验的基础知识

目录 前言&#xff1a; 目标 1 什么叫 假设检验 1.1 假设检验的定义 1.1.1 来自百度百科 1.1.2 维基百科 1.2 假设检验的最底层逻辑&#xff1a;是反证法思想 1.3 假设检验的底层构造&#xff1a;小概率反证法思想 2 什么叫反证法 2.1 反证法的概念 2.1.1 来自百度…

HarmonyOS开发实例:【任务延时调度】

介绍 本示例使用[ohos.WorkSchedulerExtensionAbility] 、[ohos.net.http]、[ohos.notification] 、[ohos.bundle]、[ohos.fileio] 等接口&#xff0c;实现了设置后台任务、下载更新包 、保存更新包、发送通知 、安装更新包实现升级的功能。 效果预览 使用说明 安装本应用之…

基于Python的机器学习的文本分类系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

PyTorch深度学习入门-2

PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】_哔哩哔哩_bilibili 一、神经网络的基本骨架 --nn.Module Neutral network torch.nn — PyTorch 2.2 documentation * import torch from torch import nnclass xiaofan(nn.Module):…

探索未来:人工智能—图像分类的发展与核心技术

引言 在当今数字化时代&#xff0c;图像已经成为我们生活中不可或缺的一部分&#xff0c;而人工智能技术的发展为图像处理和分析提供了巨大的机遇和挑战。其中&#xff0c;图像分类作为人工智能领域的一个重要应用&#xff0c;在诸多领域中发挥着关键作用。 人工智能在图像分类…

Pascal VOC(VOC 2012、VOC 2007) 数据集的简介

一、数据集介绍 PascalVOC(2005~2012)数据集是PASCAL VOC挑战官方使用的数据集。该数据集包含20类的物体。每张图片都有标注&#xff0c;标注的物体包括人、动物&#xff08;如猫、狗、岛等&#xff09;、交通工具&#xff08;如车、船飞机等&#xff09;、家具&#xff08;如椅…

多线程意义

直接上代码 我们来看两个程序 由一个线程和两个线程运行的区别&#xff1a; 单线程&#xff08;main&#xff09;&#xff1a; public static void test(){long a 0;long b 0;for(long i 0; i < 10000000000l; i){a;}for(long i 0; i < 10000000000l; i){b;}} 多…

MySQL Prepared语句(Prepared Statements)

在数据库应用中&#xff0c;很多SQL语句都会重复执行很多次&#xff0c;每次执行可能只是where条件中的变量值不同&#xff0c;但MySQL依然会解析SQL语法并生成执行计划。对于这类情况&#xff0c;可以利用prepared语句来避免重复解析SQL的开销。 文章目录 一、prepared语句优…

蓝桥杯(基础题)

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…