一、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 4月 5 22:21 charts -rw-r--r-- 1 root root 1143 4月 5 22:21 Chart.yaml drwxr-xr-x 3 root root 162 4月 5 22:21 templates -rw-r--r-- 1 root root 2252 4月 5 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工作流程
- 从镜像仓库拉取chart,这个chart里会包含我们项目所需的各个yaml模板,例如deployment、service、ingress等;
- helm将values对象(chart保重values.yaml文件/helm install、helm upgrade的-f参数传入的自定义yaml文件/–set参数传入的值)合并渲染到我们的yaml模板中形成完整的yaml清单;
- helm再将应用发布到k8s里;
三、Chart模板
Helm核心是模板,即模板化k8s YAML文件。
通过模板实现Chart高效复用,当部署多个应用时,可以将差异化的字段进行模板化,在部署时使用-f或者–set动态覆盖默认值,从而适配多个应用
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:设置默认值,如果获取的值为空则使用默认值
- indent和nindent:缩进字符串
- 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时会报如下错误
indent和nindent:都是缩进字符串,主要区别在于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详解分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/87026.html