在helm的体系中,有helm,tiller server,以及chart。tiller作为服务端一般运行在k8s集群之上,helm能够通过tiller server在k8s之上部署应用程序,这些应用程序来在helm能够访问到的仓库当中的chart。此前我们自定义了一些简单的值文件,实现实例化chart可安装的,可运行的release。也可以通过chart生成release,其中配置文件config来自chart中的values.yaml文件。
对于chart来讲,事实上内部没有太复杂的地方,只是将此前我们所使用的编写的配置清单,改写为可复用的格式。
此前我们的配置清单的都是为了完成某一个特定的功能而开发,一旦编辑完成,如果需要配置变更就需要重新修改配置清单文件,或者重新更新配置文件。而helm chart引用了一种机制,能够把此前配置清单中特定的内容,尤其是属性值,配置为模板内容。这类似于ansibel当中的playbook模板。只不过其中调用的变量值来自于不同的位置,或是helm内建的,或者是来自部署的release,也有一些属性值是由用户通过值文件(config)提供。
chart组成
我们先获取一个chart
[root@linuxea helm]# helm fetch stable/redis
[root@linuxea helm]# ls
redis-4.2.10.tgz values.yaml
这些文件在打包的时候将时间改为unix元年的时间
[root@linuxea helm]# tar xf redis-4.2.10.tgz
tar: redis/Chart.yaml: implausibly old time stamp 1970-01-01 01:00:00
tar: redis/values.yaml: implausibly old time stamp 1970-01-01 01:00:00
tar: redis/templates/NOTES.txt: implausibly old time stamp 1970-01-01 01:00:00
tar: redis/templates/_helpers.tpl: implausibly old time stamp 1970-01-01 01:00:00
tar: redis/templates/configmap.yaml: implausibly old time stamp 1970-01-01 01:00:00
一个chart组成部分:https://docs.helm.sh/developing_charts/#the-chart-file-structure,翻译如下
wordpress/
Chart.yaml #YAML文件,包含有关chart的信息,名称,版本等等信息
LICENSE #OPTIONAL:包含chart许可证的纯文本文件
README.md #OPTIONAL:一个人类可读的README文件
requirements.yaml #OPTIONAL:列出chart依赖关系的YAML文件。如,lnmp的依赖关系。自动处理依赖
values.yaml #此chart的默认配置值。对模板中自定义变量的引用设定的默认值。
charts/ #包含此chart所依赖的任何chart的目录。charts于requirements类似。目录下存放每一个被当前charts所依赖的其他的charts的打包tgz格式文件。一旦tgz存放在此处,就会被依赖。不管requirements是否存在。手动依赖关系
templates/ #模板目录,当与值组合时。这取决于模板的语法,比如清单中定义的service,pvc等,这些便于复用的属性或者字段就会改造成能够通过模板编程语言,基于模板编程结果生成的信息并且自动替换到代码所在处。这需要对go模板语法理解。
#将生成有效的Kubernetes清单文件。
templates/NOTES.txt #OcTIONAL:包含简短使用说明的纯文本文件
redis文件树如下:
yaml定义
chart
apiVersion:chartAPI版本,始终为“v1”(必填)
name:chart的名称(必填),与目录名称保持一致
Version:SemVer 2版本(必填),版本格式
kubeVersion:SemVer系列兼容的Kubernetes版本(可选)
description:该项目的单句描述(可选)
keywords:
- 关于此项目的关键字列表(可选)
home:该项目主页的URL(可选)
sources:
- 此项目源代码的URL列表(可选)
maintainers:#(可选)
- name:维护者的名字(每个维护者都需要)
email:维护者的电子邮件(每个维护者可选)
url:维护者的URL(每个维护者可选)
engine:gotpl#模板引擎的名称(可选,默认为gotpl)
icon:要用作图标的SVG或PNG图像的URL(可选)。
appVersion:包含的应用程序版本(可选)。这不一定是SemVer。
deprecated:是否弃用此chart(可选,布尔值)
tillerVersion:此chart所需的Tiller版本。这应该表示为SemVer范围:“> 2.0.0”(可选)
requirements
dependencies:
- name: apache
version: 1.2.3
repository: http://example.com/charts
- name: mysql
version: 3.2.1
repository: http://another.example.com/charts
在dependencies中会引用一个列表,每一个列表是一个对象,每一个对象就定义一个被依赖的chart
- 该
name
字段是您想要的chart的名称。 - 该
version
字段是您想要的chart的版本。 - 该
repository
字段是chart存储库的完整URL。请注意,您还必须使用helm repo add
在本地添加该repo。
打包一个当前的chart,就会分析requirements文件语法格式,将每一个依赖的chart从指定的仓库中下载至本地完成打包。
运行helm dependency update CHARTS_NAME
,将使用的requirements文件将所有指定的依赖项下载到charts/
目录中。这样在执行一个应用的时候,打包内的依赖都被自动安装完成。
当然,如果我此前已知依赖关系,只需要将依赖的包下载到charts目录下,也是可以的。
- alias
也有一些依赖是通过特殊的名称进行依赖,这时候就可以用alias别名来定义依赖关系即可
dependencies:
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-1
templates
模板文件遵循编写Go模板的标准约定,详情参阅:https://golang.org/pkg/text/template/
- 变量
模板文件中{{.Values.imageRegistry}}
变量,这里的.values就是指明来在values.yaml文件。而imageRegistry
和dockerTag
才是第一个字段
image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
而在values中的值,分别如下:
imageRegistry: "quay.io/deis"
dockerTag: "latest"
也可以设置默认值预设值,如果.Values.storage存在就是用存在values值文件的值,如果不存在就是用默认default "minio",如下:
value: {{default "minio" .Values.storage}}
而以往使用的定义的配置清单,都可以引用模板语法格式,对一些可变动的属性值,可以做成变量引用,一些复杂的场景可以使用条件判断等,如:设置为ture或者false来启用或者关闭一段配置。
此后,在安装的时候使用--values=VALUES.yaml即可
预定义的值
可以从模板中的对象访问通过values.yaml
文件(或通过--set
标志)提供的值.Values
。也可以在模板中访问其他预定义的数据。
以下值是预定义的,可用于每个模板,并且无法覆盖。与所有值一样,名称区分大小写。
Release.Name
:发布的名称(不是chart)Release.Time
:chart发布上次更新的时间。这将匹配Last Released
Release对象上的时间。Release.Namespace
:chart发布到的名称空间。Release.Service
:进行发布的服务。通常这是Tiller
。Release.IsUpgrade
:如果当前操作是升级或回滚,则设置为true。Release.IsInstall
:如果当前操作是安装,则设置为true。Release.Revision
:修订号。它从1开始,每个都递增helm upgrade
。Chart
:内容Chart.yaml
。因此,chart版本可以Chart.Version
和维护者一起获得Chart.Maintainers
。Files
:类似于地图的对象,包含chart中的所有非特殊文件。这不会授予您访问模板的权限,但可以访问存在的其他文件(除非使用它们除外.helmignore
)。可以使用{{index .Files "file.name"}}
或使用{{.Files.Get name}}
或{{.Files.GetString name}}
函数访问文件。您也可以访问该文件的内容,[]byte
使用{{.Files.GetBytes}}
Capabilities
:类似于地图的对象,包含有关Kubernetes({{.Capabilities.KubeVersion}}
,Tiller({{.Capabilities.TillerVersion}}
和支持的Kubernetes API)版本({{.Capabilities.APIVersions.Has "batch/v1"
)的版本的信息
注意:将删除任何未知的Chart.yaml字段。它们将无法在Chart
对象内部访问。因此,Chart.yaml不能用于将任意结构化数据传递到模板中。但是,值文件可以用于此目的。
如果要修改一个值就可以使用set修改。
创建chart
helm create创建一个linuxea.com的chart
Chart.yaml
[root@linuxea helm]# helm create linuxea
Creating linuxea
而后生成如下清单
而后修改一下Chart文件
[root@linuxea linuxea]# cat Chart.yaml
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for linuxea
name: linuxea
version: 0.1.0
maintainer:
- name: mark
email: linuxea@gmail.com
依赖文件requirements,先不定义
NOTES.txt
这个文件是在安装生成chart之后,提示给用户的使用信息,也在helm status命令中显示
_helpers.tpl
tpl模板语法用法
yml
deployment.yaml
ingress.yaml
service.yaml
在deployment.yaml中语法格式,有1级字段和二级字段,如下:
[root@linuxea templates]# grep Values *.yaml
deployment.yaml: replicas: {{ .Values.replicaCount }}
deployment.yaml: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
并且还有一些复杂语法模式
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
在service.yaml中可以赋值大多数的可变变量
[root@linuxea templates]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "linuxea.com.fullname" . }}
labels:
app.kubernetes.io/name: {{ include "linuxea.name" . }}
helm.sh/chart: {{ include "linuxea.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "linuxea.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
以及ingress.yaml
[root@linuxea templates]# cat ingress.yaml
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "linuxea.fullname" . -}}
{{- $ingressPath := .Values.ingress.path -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
app.kubernetes.io/name: {{ include "linuxea.name" . }}
helm.sh/chart: {{ include "linuxea.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- with .Values.ingress.annotations }}
annotations:
{{ toYaml . | indent 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: {{ . | quote }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ $fullName }}
servicePort: http
{{- end }}
{{- end }}
- 修改values参数
简单修改几项
replicaCount: 2
打开resources,这里需要将{}删掉,如果启用了的话
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
- 检查语法
而后检查语法是否错误,在父级目录检查
[root@linuxea helm]# helm lint linuxea
==> Linting linuxea
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, no failures
- 打包
如果没有错误,就可以进行打包,如果有必要,也可以上传到仓库中
[root@linuxea helm]# helm package linuxea/
Successfully packaged chart and saved it to: /root/linuxea/manifests/helm/linuxea-0.1.0.tgz
[root@linuxea helm]# ll
total 40
drwxr-xr-x. 4 root root 93 Nov 18 12:08 linuxea
-rw-r--r--. 1 root root 2614 Nov 18 12:09 linuxea-0.1.0.tgz
本地仓库
我们打开本地的仓库,本地仓库需要运行才能正常使用
[root@linuxea linuxea]# helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
打开一个临时简单的仓库服务,也可以用nginx当作仓库服务使用
[root@linuxea prometheus]# helm serve
Regenerating index. This may take a moment.
Now serving you on 127.0.0.1:8879
[root@linuxea linuxea]# ss -tlnp|grep 8879
LISTEN 0 128 127.0.0.1:8879 *:* users:(("helm",pid=3816,fd=3))
但是,helm仓库不允许使用命令行上传,但是当创建之后就会被记录下来,可通过helm search查看
[root@linuxea helm]# helm search linuxea
NAME CHART VERSION APP VERSION DESCRIPTION
local/linuxea 0.1.0 1.0 A Helm chart for linuxea.com
- 尤为注意的是
NOTES.txt
文件需要真正反映安装相关配置参数,需要进行定义成具体相关的内容
安装chart
- 安装
[root@linuxea ~]# helm install --name linuxe local/linuxea
NAME: linuxe
LAST DEPLOYED: Sun Nov 18 12:10:27 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME AGE
linuxe-linuxea 1s
==> v1beta2/Deployment
linuxe-linuxea 1s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
linuxe-linuxea-666bf7dc5b-476gm 0/1 Pending 0 1s
linuxe-linuxea-666bf7dc5b-xgs8h 0/1 Pending 0 1s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=linuxea,app.kubernetes.io/instance=linuxe" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
[root@linuxea ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
linuxe-linuxea-666bf7dc5b-476gm 1/1 Running 0 1m
linuxe-linuxea-666bf7dc5b-xgs8h 1/1 Running 0 1m
linuxea-redis-master-0 1/1 Running 0 6h
linuxea-redis-slave-77f4768cd8-rf4l2 1/1 Running 1 6h
这里安装的信息是存储在NOTES.txt
,可以在此获取
[root@linuxea helm]# helm status linuxe
LAST DEPLOYED: Sun Nov 18 12:10:27 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
linuxe-linuxea-666bf7dc5b-476gm 1/1 Running 0 3m
linuxe-linuxea-666bf7dc5b-xgs8h 1/1 Running 0 3m
==> v1/Service
NAME AGE
linuxe-linuxea 3m
==> v1beta2/Deployment
linuxe-linuxea 3m
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=linuxea,app.kubernetes.io/instance=linuxe" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
卸载chart
--purge移除
[root@linuxea helm]# helm del --purge linuxe2
release "linuxe2" deleted
[root@linuxea helm]# helm del --purge linuxe21
Error: release: "linuxe21" not found
[root@linuxea helm]# helm del --purge linuxe1
release "linuxe1" deleted
[root@linuxea helm]# helm del --purge linuxe
release "linuxe" deleted
添加仓库
添加incubator,incubator是不稳定的版本
[root@linuxea helm]# helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/
"incubator" has been added to your repositories
[root@linuxea helm]# helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
incubator https://kubernetes-charts-incubator.storage.googleapis.com/