Helm的打包格式叫做chart,所谓chart就是一系列文件, 它描述了一组相关的 k8s 集群资源
文件结构
k8s采用的是声明式的资源管理,以YAML文件的形式声明资源的期望状态,Chart文件包含了大部分的资源抽象,例如kubernetes deployment,service,ingress,serviceaccount等资源。
$ helm create test
Creating test
$ tree test -L 1
test
├── Chart.yaml
├── charts
├── templates
└── values.yaml
2 directories, 2 files
文件说明
Chart.yaml | Chart 的基本描述信息,包括Chart名称,描述,类型,版本和应用版本 |
---|---|
values.yaml | 设置模板文件的默认值,当 install 或是 upgrade 时这些值也可以被覆盖 |
charts | 依赖的 Chart 文件 |
templates | 目录下存放应用一系列 k8s 资源的 yaml 文件 |
chart.yaml 文件结构
apiVersion: # chart API 版本信息, 通常是 "v1" (必须)
name: # chart 的名称 (必须)
version: # chart 包的版本 (必须)
kubeVersion: # 指定 Kubernetes 版本 (可选)
type: # chart类型 (可选)
description: # 对项目的描述 (可选)
keywords:
- # 有关于项目的一些关键字 (可选)
home: # 项目 HOME 页面的 URL 地址 (可选)
sources:
- # 项目源码的 URL 地址 (可选)
dependencies: # chart 必要条件列表 (可选)
- name: # chart名称 (nginx)
version: # chart版本 ("1.2.3")
repository: # (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name")
condition: # (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )
tags: # (可选)
- # 用于一次启用/禁用 一组chart的tag
import-values: # (可选)
- # ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
alias: # (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用
maintainers: # (可选)维护者信息
- name: # 维护者的名称
email: # 维护者的邮件地址
url: # 维护者的个人主页
engine: gotpl # 模板引擎的名称(可选,默认为 gotpl)
icon: # (可选)指定 chart 图标的 SVG 或 PNG 图像的 URL
appVersion: # 应用程序包含的版本
deprecated: # (可选,使用布尔值)该 chart 是否被废弃
annotations:
example: # 按名称输入的批注列表 (可选).
快速入门
创建一个名称叫mychartde 简单的chart,helm会自动生成一些模板文件
helm create mychart
Creating mychart
查看temple目录底下文件
tree mychart/templates
mychart/templates
├── NOTES.txt
├── _helpers.tpl
├── deployment.yaml
├── hpa.yaml
├── ingress.yaml
├── service.yaml
├── serviceaccount.yaml
└── tests
└── test-connection.yaml
NOTES.txt | 类似于“帮助文档”,在用户运行 helm install 时显示给用户 |
---|---|
_helpers.tpl | 作用类似于“模板助手”,在这里定义需要在 Chart 中反复使用到的模板或是结构 |
service.yaml | 创建k8s的 service相关文件 |
deployment.yaml | 创建k8s的 deployment对象资源清单文件 |
ingress.yaml | 创建ingress对象的资源清单文件 |
删除tenplayes底下的文件
rm -rf mychart/templates/*
创建mychart/templates/configmap.yaml,内容如下
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello Mychart"
本地安装
helm install my-chart ./mychart
NAME: my-chart
LAST DEPLOYED: Sun Jul 11 11:41:20 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
使用helm 命令查看release和实际加载的模板内容
helm get manifest my-chart
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello Mychart"
先删除mychart
helm uninstall mychart
release "mychart" uninstalled
修改配置文件
名称使用硬编码到资源中通常被认为是不好的做法。名称对于一个发布版本来说应该是唯一的。因此,我们可能通过插入变量名来生成名称字段。
提示:由于对DNS系统的限制,name:字段被限制为63个字符。因此,发布名被限制为53个字符。Kubernetes 1.3和更早的版本限制为只有24个字符(因此只有14个字符)。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{.Release.Name}}-congfigmap
data:
myval: 'hello mychart'
执行
helm install test-chart ./mychart
NAME: test-chart
LAST DEPLOYED: Sun Jul 11 14:39:57 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看
helm get manifest test-chart
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-chart-configmap
data:
myvalue: "Hello Mychart"
—dry-run
当你想测试模板的渲染结果,但不实际安装时,你可以使用helm install —debug —dry-run my-chart ./mychart。这将呈现模板。但是不是安装chart,它会返回渲染模板,这样你就可以看到输出:
helm install --debug --dry-run my-chart ./mychart
...
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-chart-configmap
data:
myvalue: "Hello Mychart"
使用——dry-run将使测试chart变得简易,但它不能确保Kubernetes会执行生生成的模板。因此不能认为试运行是可行的。就一定可以在k8s执行成功。
Chart操作
创建
$ helm create mychart
Creating mychart
打包helm package
打包一个 Chart 模板
helm package test
安装
helm install foo ./
NAME: foo
LAST DEPLOYED: Sat Dec 12 22:24:11 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看
helm get manifest foo
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: foo-congfigmap
data:
myval: 'hello mychart'
使用参数 --debug --dry-run
,这样会返回渲染的模板、同时不会立刻执行安装操作:
helm install --debug --dry-run bar ./
....
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: bar-congfigmap
data:
myval: 'hello mychart'
修改配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{.Release.Name}}-congfigmap
data:
myval: {{.Values.myval}}
执行
helm install --debug --dry-run bar ./
...
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: bar-congfigmap
data:
myval: hello world
—set
helm install --debug --dry-run --set myval="hello helm" bar ./
...
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: bar-congfigmap
data:
myval: hello helm
Nginx
创建mynginx
$ helm create mynginx
目录结构
tree -L 2
.
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
└── values.yaml
修改values.yaml
service:
type: NodePort
port: 80
nodePort: 30080
修改sever.yaml
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
nodePort: {{ .Values.service.nodePort }}
只是渲染当前的chart 不按照当前的chart
$ helm template --debug my-nginx mynginx
install.go:172: [debug] Original chart version: ""
install.go:189: [debug] CHART PATH: /Users/baxiang/Documents/k8s/helm/mynginx
---
# Source: mynginx/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-nginx-mynginx
labels:
helm.sh/chart: mynginx-0.1.0
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
---
# Source: mynginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx-mynginx
labels:
helm.sh/chart: mynginx-0.1.0
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
type: NodePort
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
nodePort: 30080
selector:
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
---
# Source: mynginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-mynginx
labels:
helm.sh/chart: mynginx-0.1.0
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
template:
metadata:
labels:
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
spec:
serviceAccountName: my-nginx-mynginx
securityContext:
{}
containers:
- name: mynginx
securityContext:
{}
image: "nginx:1.15"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}
---
# Source: mynginx/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "my-nginx-mynginx-test-connection"
labels:
helm.sh/chart: mynginx-0.1.0
app.kubernetes.io/name: mynginx
app.kubernetes.io/instance: my-nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['my-nginx-mynginx:80']
restartPolicy: Never
上面的命令还可以执行
helm install my-nginx mynginx --dry-run --debug
安装当前的chart
$ helm install my-nginx mynginx
NAME: my-nginx
LAST DEPLOYED: Tue Dec 29 22:36:02 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services my-nginx-mynginx)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
查看当前k8s的service
$kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-mynginx NodePort 10.96.21.211 <none> 80:30080/TCP 2m8s
执行
curl localhost:30080