Kubernetes部署应用利器Helm详解

Kubernetes部署应用利器Helm详解Kubernetes 部署应用利器 Helm 详解 helm 安装使用 chart 模版 函数使用 harbor 仓库管理 chart helm


一、helm概述&安装

1.为什么需要Helm

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

2.Helm介绍

  • 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. +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目录下

[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. +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.Name release名称(helm install xxx 名称就是这个xxx)
Release.Time release的时间
Release.Namespace release的命名空间
Release.Service release服务的名称
Release.Revision release的修订版本号,从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对象进行实现

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

[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的值才可以启用

  • 一个布尔类型 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仓库

例如使用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/_/


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

今天的文章 Kubernetes部署应用利器Helm详解分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-15 16:33
下一篇 2024-12-15 16:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/87026.html