1 helm相关概念
1.1 Helm 介绍
Helm就是Kubernetes的应用程序包管理器,类似于Linux系统之上的yum或apt-get等,可用于实现帮助用户查找、分享及使用Kubernetes应用程序。它的核心打包功能组件称为chart,可以帮助用户创建、安装及升级复杂应用。Helm将Kubernetes的资源(如Deployments、Services或ConfigMap等)打包到一个Charts中,制作并测试完成的各个Charts将保存到Charts仓库进行存储和分发。另外,Helm实现了可配置的发布,它支持应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除和更新等操作。
Helm有两个重要概念:
helm:一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理。
Chart:应用描述,一系列用于描述 k8s 资源相关文件的集合。
Release:基于Chart的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个 release;将在k8s中创建出真实运行的资源对象。
1.2 Helm v3 变化
a.最明显的变化是 Tiller的删除
b.Release名称可以在不同命名空间重用
c.支持将 Chart 推送至 Docker 镜像仓库中
d.使用JSONSchema验证chart values
①为了更好地协调其他包管理者的措辞 Helm CLI个别更名
helm delete更名为helm uninstall
helm inspect更名为helm show
helm fetch更名为helm pull
但以上旧的命令当前仍能使用。
②移除了用于本地临时搭建 Chart Repository的 helm serve 命令。
③自动创建名称空间
在不存在的命名空间中创建发行版时,Helm 2创建了命名空间。Helm 3遵循其他Kubernetes对象的行为,如果命名空间不存在则返回错误。
④不再需要requirements.yaml, 依赖关系是直接在chart.yaml中定义。
1.3 helm架构
2 Helm部署使用
2.1 Helm客户端部署
Helm客户端下载地址:https://github.com/helm/helm/releases
解压移动到/usr/bin/目录即可。
wget https://get.helm.sh/helm-vv3.2.1-linux-amd64.tar.gz
tar zxvf helm-v3.2.1-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
helm 常见的命令
命令 描述
create 创建一个chart并指定名字
dependency 管理chart依赖
get 下载一个release。可用子命令:all、hooks、manifest、notes、values
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客户端版本
2.2 配置国内chart仓库
微软仓库(http://mirror.azure.cn/kubernetes/charts/)这个仓库推荐,基本上官网有的chart这里都有。
阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts )
官方仓库(https://hub.kubeapps.com/charts/incubator)官方chart仓库,国内有点不好使。
添加存储库
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update
查看配置的存储库
helm repo list
helm search repo stable
删除存储库:
helm repo remove aliyun
3 Helm基本使用
3.1.1 使用chart部署一个应用
#查找chart
[root@k8s-master01 helm3]# helm search repo mysql
NAME CHART VERSION APP VERSION DESCRIPTION
aliyun/mysql 0.3.5 Fast, reliable, scalable, and easy to use open-...
azure/mysql 1.6.9 5.7.30 DEPRECATED - Fast, reliable, scalable, and easy...
azure/mysqldump 2.6.2 2.4.1 DEPRECATED! - A Helm chart to help backup MySQL...
azure/prometheus-mysql-exporter 0.7.1 v0.11.0 DEPRECATED A Helm chart for prometheus mysql ex...
bitnami/mysql 8.8.7 8.0.26 Chart to create a Highly available MySQL cluster
prometheus-community/prometheus-mysql-exporter 1.2.2 v0.12.1 A Helm chart for prometheus mysql exporter with...
stable/mysql 0.3.5 Fast, reliable, scalable, and easy to use open-...
#查看chrt信息
[root@k8s-master01 helm3]# helm show values aliyun/mysql
## mysql image version
## ref: https://hub.docker.com/r/library/mysql/tags/
##
image: "mysql"
imageTag: "5.7.14"
## Specify password for root user
##
## Default: random 10 character string
# mysqlRootPassword: testing
#安装包
>一个 chart 包是可以多次安装到同一个集群中的,每次安装都会产生一个release, 每个release都可以独立管理和升级。
[root@k8s-master01 mysql]# helm repo add stable http://mirror.azure.cn/kubernetes/charts/
helm install db stable/mysql
WARNING: This chart is deprecated
NAME: db
LAST DEPLOYED: Wed Oct 20 21:13:10 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
db-mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=(kubectl get secret --namespace default db-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 db-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/db-mysql 3306
mysql -h{MYSQL_HOST} -P{MYSQL_PORT} -u root -p{MYSQL_ROOT_PASSWORD}
#查看发布状态
[root@k8s-master01 mysql]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
db default 1 2021-10-20 21:13:10.417392635 +0800 CST deployed mysql-1.6.9 5.7.30
helm status db
因为mysql需要指定使用存储才能起来 所以要用如下命令
[root@k8s-master01 mysql]# helm install db --set persistence.storageClass="managed-nfs-storage" stable/mysql
[root@k8s-master01 mysql]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
db-mysql Bound pvc-41064e58-6ea7-461a-aff3-86f3f729cd05 8Gi RWO managed-nfs-storage 60s
[root@k8s-master01 storageclass]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-9d7dfbc65-bpdd5 1/1 Running 1 5m46s
卸载一个charts
[root@k8s-master01 storageclass]# helm uninstall mysql
3.1.2 安装前自定义chart配置选项
自定义chart配置选项,安装过程中有两种方法可以传递配置数据:
--values(或-f):指定带有覆盖的YAML文件。这可以多次指定,最右边的文件优先
--set:在命令行上指定替代。如果两者都用,--set优先级高
[root@k8s-master01 helm3]# cat config.yaml
persistence:
enabled: true
storageClass: "managed-nfs-storage"
accessMode: ReadWriteOnce
size: 6Gi
mysqlUser: "k8s"
mysqlPassword: "123456"
mysqlDatabase: "k8s"
helm install mysql azure/mysql -f config.yaml
WARNING: This chart is deprecated
NAME: mysql
LAST DEPLOYED: Thu Oct 21 13:58:23 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql.default.svc.cluster.local
To get your root password run:
MYSQL_ROOT_PASSWORD=(kubectl get secret --namespace default 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 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/mysql 3306
mysql -h{MYSQL_HOST} -P{MYSQL_PORT} -u root -p{MYSQL_ROOT_PASSWORD}
验证
[root@k8s-master01 helm3]# kubectl exec -it mysql-6d755f68cb-v5qcv -- bash
root@mysql-6d755f68cb-v5qcv:/# mysql -h mysql -uk8s -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 5.7.30 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| k8s |
+--------------------+
2 rows in set (0.00 sec)
4 Helm Chart自定义模板
4.1 Charts文件组织结构
一个Charts就是按特定格式组织的目录结构,目录名即为Charts名,目录名称本身不包含版本信息。目录结构中除了charts/和templates/是目录之外,其他的都是文件。它们的基本功用如下。
[root@k8s-master01 helm3]# helm create mychart
Creating mychart
[root@k8s-master01 helm3]# tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
# Chart.yaml:用于描述这个 Chart的基本信息,包括名字、描述信息以及版本等。
# values.yaml :用于存储 templates 目录中模板文件中用到变量的值。
# Templates: 目录里面存放所有yaml模板文件。
# charts:目录里存放这个chart依赖的所有子chart。
# NOTES.txt :用于介绍Chart帮助信息, helm install 部署后展示给用户。例如:如何使用这个 Chart、列出缺省的设置等。
# _helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用
打包推送的charts仓库
[root@k8s-master01 helm3]# helm package mychart/
Successfully packaged chart and saved it to: /root/k8s-ceshi/helm3/mychart-0.1.0.tgz
升级、回滚和删除
发布新版本的chart时,或者当您要更改发布的配置时,可以使用该helm upgrade 命令。
# helm upgrade --set imageTag=1.17 web mychart
# helm upgrade -f values.yaml web mychart
4.2 Chart模板配置
Helm最核心的就是模板,即模板化的K8S manifests文件。 它本质上就是一个Go的template模板。Helm在Go template模板的基础上,还会增加很多东西。如一些自定义的元数据信息、扩展的库以及一些类似于编程形式的工作流,例如条件语句、管道等等。这些东西都会使得我们的模板变得更加丰富。
4.2.1 helm chart values的引用
helm create nginx
[root@k8s-master01 nginx]# kubectl create deploy nginx --image=nginx:1.16 --dry-run=client -o yaml > deployment.yml
[root@k8s-master01 templates]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: helm-nginx
name: helm-nginx
spec:
replicas: 1
selector:
matchLabels:
app: helm-nginx
template:
metadata:
labels:
app: helm-nginx
spec:
containers:
- image: nginx:1.16
name: helm-nginx
kubectl create deploy nginx --image=nginx:1.16
[root@k8s-master01 templates]# kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort nginx --dry-run=client -o yaml > service.yaml
cat service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: helm-nginx
name: helm-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: helm-nginx
type: NodePort
创建Chart后,接下来就是将其部署:
[root@k8s-master01 helm3]# helm install web nginx -n nginx
NAME: web
LAST DEPLOYED: Fri Oct 22 17:01:52 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@k8s-master01 helm3]# helm list -n nginx
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web nginx 1 2021-10-22 17:01:52.681448993 +0800 CST deployed helm-nginx-0.1.0 1.16.0
访问验证
[root@k8s-master01 helm3]# curl 10.104.245.231 -I
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Fri, 22 Oct 2021 09:03:23 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 10:05:00 GMT
Connection: keep-alive
ETag: "5d528b4c-264"
Accept-Ranges: bytes
然后更新nginx版本,这里我们引用value的使用
[root@k8s-master01 nginx]# vim values.yaml
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.17"
[root@k8s-master01 templates]# cat deployment.yml
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: helm-nginx
版本升级
[root@k8s-master01 helm3]# helm upgrade web nginx -n nginx
Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Fri Oct 22 17:08:58 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 2
TEST SUITE: None
[root@k8s-master01 helm3]# helm history web -n nginx #查看历史
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Fri Oct 22 17:01:52 2021 superseded helm-nginx-0.1.0 1.16.0 Install complete
2 Fri Oct 22 17:08:58 2021 deployed helm-nginx-0.1.0 1.16.0 Upgrade complete
[root@k8s-master01 helm3]# kubectl get pod,svc -n nginx
NAME READY STATUS RESTARTS AGE
pod/helm-nginx-79b54d4bdb-qpjxd 1/1 Running 0 81s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/helm-nginx NodePort 10.104.245.231 <none> 80:31604/TCP 8m26s
[root@k8s-master01 helm3]# curl 10.104.245.231 -I
HTTP/1.1 200 OK
Server: nginx/1.17.10
Date: Fri, 22 Oct 2021 09:10:25 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
Connection: keep-alive
ETag: "5e95c66e-264"
Accept-Ranges: bytes
如下 nginx版本已经更新到了nginx1.17
回滚到1版本
[root@k8s-master01 helm3]# helm rollback web 1 -n nginx
Rollback was a success! Happy Helming!
[root@k8s-master01 helm3]# curl 10.104.245.231 -I
HTTP/1.1 200 OK
Server: nginx/1.16.1
已回滚到版本1
4.2.2 构建自己的chart模板
Helm最核心的就是模板,即模板化的K8S manifests文件。 使用如下命令可以看到实际的模板被渲染过后的资源文件:
# 查看manifest
# helm get manifest web
一个deployment.yaml 部署多个应用,有哪些字段需要修改: 镜像 标签 副本数 资源限制 环境变量 端口 资源名称
- helm内置变量
内置对象 | Release就是Helm的内置对象 |
---|---|
Release.Name | release 名称 |
Release.Time | release 的时间 |
Release.Namespace | release 的 namespace(如果清单未覆盖 |
Release.Service | release 服务的名称 |
Release.Revision | 此 release 的修订版本号,从1开始累加 |
Release.IsUpgrade | 如果当前操作是升级或回滚,则将其设置为 true。 |
Release.IsInstall | 如果当前操作是安装,则设置为 true。 |
- Values Values对象是为Chart模板提供值,这个对象的值有4个来源: ● chart 包中的 values.yaml 文件 ● 父 chart 包的 values.yaml 文件 ● 通过 helm install 或者 helm upgrade 的 -f或者 --values参数传入的自定义的 yaml 文件 ● 通过 --set 参数传入的值 chart 的 values.yaml 提供的值可以被用户提供的 values 文件覆盖,而该文件同样可以被 --set提供的参数所覆盖。
通过charts模板部署nginx
cat nginx/values.yaml
# Default values for nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.17"
name: nginx
labels:
project: www
app: helm-nginx
service:
type: NodePort
port: 80
targetport: 80
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
cat nginx/templates/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Values.labels.app }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.labels.app }}
template:
metadata:
labels:
app: {{ .Values.labels.app }}
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: {{ .Values.image.name }}
cat nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Values.labels.app }}
name: {{ .Values.labels.app }}
spec:
ports:
- port: {{ .Values.service.port }}
protocol: TCP
targetPort: {{ .Values.targetport }}
selector:
app: {{ .Values.labels.app }}
type: {{ .Values.service.type }}
helm install web nginx --dry-run #测试执行,检查有无语法错误
[root@k8s-master01 helm3]# helm install web nginx -n nginx #直接安装,即可使用
NAME: web
LAST DEPLOYED: Wed Oct 27 21:26:02 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None helm show values nginx -nginx #查看values
[root@k8s-master01 helm3]# helm list -n nginx
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web nginx 1 2021-10-27 21:26:02.174975039 +0800 CST deployed helm-nginx-0.1.0 1.17.0
调试使用–dry-run 如上面nginx的实例deployment使用charts部署应用需要修改如下字段 镜像 标签 副本数 资源限制 环境变量 端口 资源名称
4.3 管道与函数
从.Values中读取的值变成字符串,可以使用quote函数实现.
# vi templates/deployment.yaml
app: {{ quote .Values.label.app }}
# helm install --dry-run web ../mychart/
project: ms
app: "nginx"
quote .Values.label.app 将后面的值作为参数传递给quote函数。
另外还会经常使用一个default函数,该函数允许在模板中指定默认值,以防止该值被忽略掉。
例如忘记定义,执行helm install 会因为缺少字段无法创建资源,这时就可以定义一个默认值。
# cat values.yaml
replicas: 2
# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
- name: {{ .Values.name | default "nginx" }}
其他函数:
缩进:{{ .Values.resources | indent 12 }}
大写:{{ upper .Values.resources }}
首字母大写:{{ title .Values.resources }}
4.4 流程控制
流程控制是为模板提供了一种能力,满足更复杂的数据逻辑处理。 Helm模板语言提供以下流程控制语句: if/else 条件块 with 指定范围 range 循环块
4.4.1 if
if/else块是用于在模板中有条件地包含文本块的方法,条件块的基本结构如下:
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
例子:
cat nginx/templates/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.labels.app }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.labels.app }}
template:
metadata:
labels:
app: {{ .Values.labels.app }}
{{- if eq .Values.test "123" }} ##{{- 用来消除此行执行后产生的空格
ttt: 123
{{- else }}
ttt: 456
{{- end }}
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: {{ .Values.image.name }}
[root@k8s-master01 helm3]# cat nginx/values.yaml
test: "123"
通过模板引擎来渲染一下
[root@k8s-master01 helm3]# helm install web nginx --dry-run
spec:
replicas: 1
selector:
matchLabels:
app: helm-nginx
template:
metadata:
labels:
app: helm-nginx
ttt: 123
条件判断就是判断条件是否为真,如果值为以下几种情况则为false:
● 一个布尔类型的 假
● 一个数字 零
● 一个 空的字符串
● 一个 nil(空或 null)
● 一个空的集合( map、 slice、 tuple、 dict、 array)
通过判断变量的值的真假可以开启对应的参数,如下面例子
cat nginx/values.yaml
resources:
limits:
cpu: 100m
memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
[root@k8s-master01 helm3]# helm install web nginx --dry-run
# Source: helm-nginx/templates/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helm-nginx
spec:
replicas: 1
selector:
matchLabels:
app: helm-nginx
template:
metadata:
labels:
app: helm-nginx
ttt: 123
spec:
containers:
- image: nginx:1.17
name: nginx
resources:
limits:
cpu: 100m
memory: 128Mi
经调试,当values里注释resources: {}时,则无资源限制,当values有值时,可以引用资源限制
也可以通过增加控件开关的方式控制是否引用变量
[root@k8s-master01 helm3]# cat nginx/values.yaml
resources:
enabled: false
limits:
cpu: 100m
memory: 128Mi
cat nginx/templates/deployment.yml
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: {{ .Values.image.name }}
{{- if .Values.resources.enabled }}
resources:
limits:
cpu: {{ .Values.resources.limits.cpu }}
memory: {{ .Values.resources.limits.memory }}
{{- else }}
resources: {}
{{- end }}
当我们设置resources.enabled为false时,不启用资源限制
[root@k8s-master01 helm3]# helm install web nginx --dry-run
# Source: helm-nginx/templates/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helm-nginx
spec:
replicas: 1
selector:
matchLabels:
app: helm-nginx
template:
metadata:
labels:
app: helm-nginx
ttt: 123
spec:
containers:
- image: nginx:1.17
name: nginx
resources: {}
通过value中增加类似 enabled: false,可以控制是否创建某些资源对象.如ingress
{{- if .Values.ingress.enabled }}
ingress资源对象内容
{{- end }}
思考:
也可以通过value 设置不同的nodeSelector 的选择不同的node服务器资源.
4.4.2 with
with :控制变量作用域。 其语法和一个简单的 if语句比较类似: {{ with PIPELINE }} #restricted scope {{ end }} with语句可以允许将当前范围 .设置为特定的对象,比如我们前面一直使用的 .Values.label,我们可以使用 with来将 .范围指向 .Values.label:
[root@k8s-master01 helm3]# cat nginx/values.yaml
nodeSelector:
team: a
gpu: yes
[root@k8s-master01 helm3]# cat nginx/templates/deployment.yml
spec:
{{- with .Values.nodeSelector }}
nodeSelector:
team: {{ .team }}
gpu: {{ .gpu }}
{{- end }}
containers:
[root@k8s-master01 helm3]# helm install web nginx --dry-run
spec:
nodeSelector:
team: a
gpu: true
containers:
- image: nginx:1.17
name: nginx
resources: {}
另一种简单的写法
spec:
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
with是一个循环构造。使用.Values.nodeSelector中的值:将其转换为Yaml。
toYaml之后的点是循环中.Values.nodeSelector的当前值
4.4.3 range
在Helm模板语言中,使用range关键字来进行循环操作。
$ vim mychart/values.yaml
test:
- 1
- 2
- 3
$ vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}
data:
test: |
{{- range .Values.test }}
{{ . }}
{{- end }}
$ helm install web1 mychart --dry-run
# Source: helm-nginx/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: web
data:
test: |
1
2
3
循环内部我们使用的是一个 .,这是因为当前的作用域就在当前循环内,这个 .引用的当前读取的元素。
4.4.4 变量
变量,在模板中,使用变量的场合不多,但我们将看到如何使用它来简化代码,并更好地利用with和range。
5 开发自己的chart
开发Chart大致流程: 先创建模板 helm create demo 修改Chart.yaml,Values.yaml,添加常用的变量 在templates目录下创建部署镜像所需要的yaml文件,并变量引用yaml里经常变动的字段
5.1 创建模板
helm create demo
[root@k8s-master01 helm3]# tree demo
demo
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
5.2 修改Chart.yaml,Values.yaml
[root@k8s-master01 helm3]# cat demo/Chart.yaml
apiVersion: v2
name: demo
description: A Helm chart for demo
type: application
version: 0.1.0
appVersion: 1.16.0
cat demo/values.yaml
replicas: 2
image:
repository: lizhenliang/java-demo
pullPolicy: IfNotPresent
tag: "latest"
service:
type: ClusterIP
port: 80
targetport: 8080
ingress:
enabled: true
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: demo.devopstack.cn
paths: /
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
nodeSelector: {}
5.3 修改_helpers.tpl(通用模板)
cat demo/templates/_helpers.tpl
{{/*
资源名称
*/}}
{{- define "demo.fullname" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
公共标签选择器
*/}}
{{- define "demo.labels" -}}
app: {{ template "demo.fullname" . }}
release: {{ .Release.Name }}
chart: {{ .Chart.Name }}
{{- end }}
{{/*
标签选择器
*/}}
{{- define "demo.selectorLabels" -}}
app: {{ template "demo.fullname" . }}
release: {{ .Release.Name }}
{{- end }}
5.4 生成deployment.yaml,service.yaml, ingress等文件
cat demo/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "demo.fullname" . }}
labels:
{{- include "demo.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "demo.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "demo.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- else }}
resources: {}
{{- end }}
cat demo/templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
{{- fullName := include "demo.fullname" . -}}
{{-svcPort := .Values.service.port -}}
{{- paths := .Values.ingress.paths -}}
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: {{fullName }}
labels:
{{- include "demo.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
- path: {{ .paths }}
backend:
serviceName: {{ fullName }}
servicePort: {{svcPort }}
{{- end }}
{{- end }}
cat demo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "demo.fullname" . }}
labels:
{{- include "demo.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetport }}
protocol: TCP
name: http
selector:
{{- include "demo.selectorLabels" . | nindent 4 }}
5.5 NOTES.txt 提示信息
cat demo/templates/NOTES.txt
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
http{{ if .Values.ingress.tls }}s{{ end }}://{{- range .Values.ingress.hosts }}{{ .host }}{{.paths}}{{end}}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "demo.fullname" . }})
export NODE_IP=(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://NODE_IP:NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "demo.fullname" . }}'
export SERVICE_IP=(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "demo.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "demo.fullname" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
{{- end }}
5.6 演示我们的chart
#试运行chart
helm install web1 demo --dry-run
NAME: web1
LAST DEPLOYED: Sun Nov 14 17:32:01 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: demo/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: demo
labels:
app: demo
release: web1
chart: demo
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: demo
release: web1
---
# Source: demo/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
labels:
app: demo
release: web1
chart: demo
spec:
replicas:
selector:
matchLabels:
app: demo
release: web1
template:
metadata:
labels:
app: demo
release: web1
spec:
containers:
- name: demo
image: "lizhenliang/java-demo:latest"
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
---
# Source: demo/templates/ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: demo
labels:
app: demo
release: web1
chart: demo
spec:
rules:
- host: "demo.devopstack.cn"
http:
paths:
- path: /
backend:
serviceName: demo
servicePort: 80
NOTES:
1. Get the application URL by running these commands:
http://demo.devopstack.cn/
安装chart
helm install web1 demo -n nginx
NAME: web1
LAST DEPLOYED: Sun Nov 14 17:32:46 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
http://demo.devopstack.cn/
#验证我们的chart
[root@k8s-master01 helm3]# helm list -n nginx
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web1 nginx 1 2021-11-14 17:32:46.567894938 +0800 CST deployed demo-0.1.0 1.16.0
[root@k8s-master01 helm3]# kubectl get pods -n nginx
NAME READY STATUS RESTARTS AGE
demo-6bc44cbc7b-q592l 1/1 Running 0 36s
[root@k8s-master01 helm3]# kubectl get pods -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-6bc44cbc7b-q592l 1/1 Running 0 41s 10.244.4.40 k8s-node04 <none> <none>
[root@k8s-master01 helm3]# kubectl get ingress -n nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
demo <none> demo.devopstack.cn 80 2m15s
[root@k8s-master01 helm3]# kubectl get svc -n nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo ClusterIP 10.100.151.147 <none> 80/TCP 2m30s
访问浏览器验证demo java运行情况
6 使用Harbor作为Chart仓库
6.1 启用Harbor的Chart仓库服务
./install.sh --with-chartmuseum
启用后,默认创建的项目就带有helm charts功能了。
6.2 安装push插件
https://github.com/chartmuseum/helm-push
helm plugin install https://github.com/chartmuseum/helm-push
或者
wget https://github.com/chartmuseum/helm-push/releases/download/v0.10.1/helm-push_0.10.1_linux_amd64.tar.gz
tar zxvf helm-push_0.10.1_linux_amd64.tar.gz mkdir -p /root/.local/share/helm/plugins/helm-push
chmod +x bin/* mv bin plugin.yaml /root/.local/share/helm/plugins/helm-push
[root@k8s-master01 ~]# helm plugin list
NAME VERSION DESCRIPTION
cm-push 0.10.1 Push chart package to ChartMuseum
6.3 添加repo
helm repo add --ca-file harbor.devopstack.cn.cert --cert-file harbor.devopstack.cn.crt --key-file harbor.devopstack.cn.key --username admin --password Harbor12345 myrepo https://192.168.10.20:443/chartrepo/chart/
helm repo list #查询已添加 仓库地址
[root@k8s-master01 ~]# helm repo list
NAME URL
stable http://mirror.azure.cn/kubernetes/charts/
myrepo https://192.168.10.20:443/chartrepo/chart/
helm repo update #跟新本地仓库缓存
备注
需要你创一个项目 eg: mychart 不然添加不进去
仓库地址格式为: http(s)//{harbor 域名或iP:端口(如果默认443 或80 可不加)}/chartrepo/{mychart}
确认你启动仓库harbor 配置的是https 还是 http 如果是http 上面的命令可以执行成功,如果是https 还需带上 ca 证书,启动harbor 用的服务器证书和密钥 如下
6.4 配置好harbor到k8s集群insecure-registry
如果想用私有chart仓库像开源的chart仓库一样,就需要把harbor的公钥私钥放到docker下
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"insecure-registries": ["harbor.devopstack.cn"]
} cd /etc/docker/ && mkdir cert.d/hub.devopstack.cn -pv
# 将 hubor私有仓库的私钥拷贝到/etc/docker/cert.d/hub.devopstack.cn/ 下即可
$ systemctl restart docker
6.4 推送与安装Chart
推送到harbor仓库
helm cm-push ./demo myrepo --ca-file ~/harbor.devopstack.cn.cert --cert-file ~/harbor.devopstack.cn.crt --key-file ~/harbor.devopstack.cn.key --username admin --password Harbor12345
Pushing demo-0.1.0.tgz to myrepo...
Done.
如图查看已经推送到harbor仓库了
查找chart
[root@k8s-master01 helm3]# helm search repo myrepo/demo
NAME CHART VERSION APP VERSION DESCRIPTION
myrepo/demo 0.1.0 1.16.0 A Helm chart for demo
下载demo包
[root@k8s-master01 ~]# helm pull myrepo/demo
[root@k8s-master01 ~]# ls |grep demo
demo-0.1.0.tgz
如果没配置 harbor到k8s集群insecure-registry
helm pull myrepo/demo --ca-file ~/harbor.devopstack.cn.cert --cert-file ~/harbor.devopstack.cn.crt --key-file ~/harbor.devopstack.cn.key --username admin --password Harbor12345
部署demo
[root@k8s-master01 ~]# helm install myrepo/demo --generate-name -n nginx
NAME: demo-1636977766
LAST DEPLOYED: Mon Nov 15 20:02:46 2021
NAMESPACE: nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
http://demo.devopstack.cn/
如果没配置 harbor到k8s集群insecure-registry
helm install myrepo/demo --generate-name -n nginx --ca-file ~/harbor.devopstack.cn.cert --cert-file ~/harbor.devopstack.cn.crt --key-file ~/harbor.devopstack.cn.key --username admin --password Harbor12345
[root@k8s-master01 ~]# helm list -n nginx
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
demo-1636977766 nginx 1 2021-11-15 20:02:46.508425704 +0800 CST deployed demo-0.1.0 1.16.0
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫