Kubernetes Helm
说明
Helm 是 Kubernetes 生态系统中的软件包管理工具,方便编排
常用命令
|
|
Chart说明
|
|
内置对象
|
|
提示和技巧
- include 函数允许引入另一个模板,然后将结果传递给其他模板函数
required 函数允许根据模板渲染的要求声明特定的值条目,如果该值为空,则显示定义的错误信息
1value: {{required "A valid .Values.who entry required!" .Values.who}}quote 为双引号将其包起来,并将字符串两边的空字符去掉
- indent函数 ,对应缩进空格
tpl 函数允许开发人员将字符串计算为模板内的模板
1{{tpl TEMPLATE_STRING VALUES}}sha256sum 函数可用于确保在一个文件发生更改时更新 deployment 的注释
- 在 templates/ 目录中,任何以下划线 “-“ 开头的文件都不会输出
values文件
- chart中的values.yaml文件
- 如果是子chart,来自父chart的values.yaml文件
- value 文件通过helm install -f传递文件
- 通过–set 来设置变量
流程控制
|
|
变量
|
|
命名模板
|
|
访问模板文件
Helm 通过 .Files 对象提供对文件的访问
- 向Helm chart添加额外的文件是可以的,Chart必须小于1M
- 某些文件不能通过.Files 对象访问, templates下无法访问文件, 使用.helmignore排除的文件不能被访问
- chart 不保留UNIX模式信息,因此文件级权限在涉及.Files对象时不会影响文件的可用性12345678apiVersion: v1kind: Secretmetadata:name: {{.Release.Name}}-secrettype: Opaquedata:token: |-{{.Files.Get "files/config1.tom1" | b64enc}}
子chart和全局值
子chart
- 子chart被认为是独立的, 子chart不能明确依赖于其父chart
- 子chart无法访问其父项的值
- 父chart 可以覆盖子chart的值
- Helm有全局概念,可以被所有chart访问
全局chart值
全局值是可以从任何 chart 或子 chart 用完全相同的名称访问的值
values 数据类型有一个保留部分,称为 Values.global, 可以设置全局值1salad: {{.Values.global.salad}}
与子chart共享模板
父 chart 和子 chart 可以共享模板。任何 chart 中的任何定义块都可用于其他 chart
Jumpserver 实例
说明
- 主要通过deployment和service来实现
- 数据存储通过nfs来实现
- 通过子chart来定义不同应用,如下目录
- 通过_helpers.tpl中定义不同变量
目录结构
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556.├── Chart.yaml├── charts│ ├── core│ │ ├── Chart.yaml│ │ ├── templates│ │ │ ├── NOTES.txt│ │ │ ├── _helpers.tpl│ │ │ ├── deployment.yaml│ │ │ └── service.yaml│ │ └── values.yaml│ ├── guacamole│ │ ├── Chart.yaml│ │ ├── templates│ │ │ ├── NOTES.txt│ │ │ ├── _helpers.tpl│ │ │ ├── deployment.yaml│ │ │ └── service.yaml│ │ └── values.yaml│ ├── koko│ │ ├── Chart.yaml│ │ ├── templates│ │ │ ├── NOTES.txt│ │ │ ├── _helpers.tpl│ │ │ ├── deployment.yaml│ │ │ └── service.yaml│ │ └── values.yaml│ ├── mysql│ │ ├── Chart.yaml│ │ ├── templates│ │ │ ├── NOTES.txt│ │ │ ├── _helpers.tpl│ │ │ ├── deployment.yaml│ │ │ └── service.yaml│ │ └── values.yaml│ ├── nginx│ │ ├── Chart.yaml│ │ ├── templates│ │ │ ├── NOTES.txt│ │ │ ├── _helpers.tpl│ │ │ ├── deployment.yaml│ │ │ └── service.yaml│ │ └── values.yaml│ └── redis│ ├── Chart.yaml│ ├── templates│ │ ├── NOTES.txt│ │ ├── _helpers.tpl│ │ ├── deployment.yaml│ │ └── service.yaml│ └── values.yaml├── templates│ ├── NOTES.txt│ ├── _helpers.tpl│ └── configmap.yaml└── values.yaml
YAML文件
mysql
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284########################## deployment.yaml ########################### deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: {{ include "mysql.fullname" . }}labels:{{- include "mysql.labels" . | nindent 4 }}spec:{{- if not .Values.autoscaling.enabled }}replicas: {{ .Values.replicaCount }}{{- end }}selector:matchLabels:{{- include "mysql.selectorLabels" . | nindent 6 }}strategy:rollingUpdate: # 滚动更新maxSurge: {{ .Values.rollingUpdate.maxSurge }} # 指定可以超过期望的pod数量的最大百分比,也可以是个数maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }} # 指定升级过程中不可用Pod的最大数量type: {{ .Values.rollingUpdate.type }}template:metadata:{{- with .Values.podAnnotations }}annotations:{{- toYaml . | nindent 8 }}{{- end }}labels:{{- include "mysql.selectorLabels" . | nindent 8 }}spec:{{- with .Values.imagePullSecrets }}imagePullSecrets:{{- toYaml . | nindent 8 }}{{- end }}securityContext:{{- toYaml .Values.podSecurityContext | nindent 8 }}containers:- name: {{ .Chart.Name }}securityContext:{{- toYaml .Values.securityContext | nindent 12 }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"imagePullPolicy: {{ .Values.image.pullPolicy }}ports:- name: mysqlcontainerPort: 3306protocol: TCPvolumeMounts:- name: mysqlmountPath: /var/lib/mysqlenv:- name: DB_PORTvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: db_port- name: DB_USERvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: db_user- name: DB_NAMEvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: db_name- name: DB_PASSWORDvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: db_passwordresources:{{- toYaml .Values.resources | nindent 12 }}volumes:{{- include "mysql.persistence.volume" (list . "mysql") | nindent 6 }} # 这里使用_helpers.tpl定义的mysql.persistence.volume{{- with .Values.nodeSelector }}nodeSelector:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.affinity }}affinity:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.tolerations }}tolerations:{{- toYaml . | nindent 8 }}{{- end }}########################## service.yaml ########################### service.yamlapiVersion: v1kind: Servicemetadata:# name: {{ include "mysql.fullname" . }}name: mysqllabels:{{- include "mysql.labels" . | nindent 4 }}spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: mysqlprotocol: TCPname: mysql # httpselector:{{- include "mysql.selectorLabels" . | nindent 4 }}sessionAffinity: ClientIP########################## _helpers.tpl ########################### _helpers.tpl{{/*Expand the name of the chart.*/}}{{- define "mysql.name" -}}{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}{{- end }}{{/*Create a default fully qualified app name.We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).If release name contains chart name it will be used as a full name.*/}}{{- define "mysql.fullname" -}}{{- if .Values.fullnameOverride }}{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}{{- else }}{{- $name := default .Chart.Name .Values.nameOverride }}{{- if contains $name .Release.Name }}{{- .Release.Name | trunc 63 | trimSuffix "-" }}{{- else }}{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}{{- end }}{{- end }}{{- end }}{{/*Create chart name and version as used by the chart label.*/}}{{- define "mysql.chart" -}}{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}{{- end }}{{/*Common labels*/}}{{- define "mysql.labels" -}}helm.sh/chart: {{ include "mysql.chart" . }}{{ include "mysql.selectorLabels" . }}{{- if .Chart.AppVersion }}app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}{{- end }}app.kubernetes.io/managed-by: {{ .Release.Service }}{{- end }}{{/*Selector labels*/}}{{- define "mysql.selectorLabels" -}}app.kubernetes.io/name: {{ include "mysql.name" . }}app.kubernetes.io/instance: {{ .Release.Name }}{{- end }}{{/*Create the name of the service account to use*/}}{{- define "mysql.serviceAccountName" -}}{{- if .Values.serviceAccount.create }}{{- default (include "mysql.fullname" .) .Values.serviceAccount.name }}{{- else }}{{- default "default" .Values.serviceAccount.name }}{{- end }}{{- end }}{{/*Define persistence volumes.*/}}{{- define "mysql.persistence.volume" -}}{{- $dot := index . 0 -}}{{- $name := index . 1 -}}{{- if $dot.Values.persistence -}}{{- if $dot.Values.persistence.nfs -}}- name: {{ $name | quote }}nfs:server: {{ $dot.Values.persistence.nfsserver | quote }}path: {{ $dot.Values.persistence.nfspath | quote }}{{- else -}}- name: {{ $name | quote }}emptyDir: {}{{- end -}}{{- end -}}{{- end -}}########################## values.yaml ########################### values.yaml# Default values for mysql.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 1image:repository: "wojiushixiaobai/jms_mysql"pullPolicy: IfNotPresent# Overrides the image tag whose default is the chart appVersion.tag: "1.5.6"imagePullSecrets: []nameOverride: ""fullnameOverride: ""serviceAccount:# Specifies whether a service account should be createdcreate: true# Annotations to add to the service accountannotations: {}# The name of the service account to use.# If not set and create is true, a name is generated using the fullname templatename: ""podAnnotations: {}podSecurityContext: {}# fsGroup: 2000securityContext: {}# capabilities:# drop:# - ALL# readOnlyRootFilesystem: true# runAsNonRoot: true# runAsUser: 1000service:type: ClusterIPport: 3306ingress:enabled: falseannotations: {}# kubernetes.io/ingress.class: nginx# kubernetes.io/tls-acme: "true"hosts:- host: chart-example.localpaths: []tls: []# - secretName: chart-example-tls# hosts:# - chart-example.localresources: {}# We usually recommend not to specify default resources and to leave this as a conscious# choice for the user. This also increases chances charts run on environments with little# resources, such as Minikube. If you do want to specify resources, uncomment the following# lines, adjust them as necessary, and remove the curly braces after 'resources:'.# limits:# cpu: 100m# memory: 128Mi# requests:# cpu: 100m# memory: 128Miautoscaling:enabled: falseminReplicas: 1maxReplicas: 100targetCPUUtilizationPercentage: 80# targetMemoryUtilizationPercentage: 80nodeSelector: {}tolerations: []affinity: {}rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatepersistence:nfs: truenfsserver: 192.168.238.100nfspath: /data/mysql#nfs:# server: 192.168.238.100# path: /data/mysqlredis
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194########################## deployment.yaml ########################### deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: {{ include "redis.fullname" . }}labels:{{- include "redis.labels" . | nindent 4 }}spec:{{- if not .Values.autoscaling.enabled }}replicas: {{ .Values.replicaCount }}{{- end }}selector:matchLabels:{{- include "redis.selectorLabels" . | nindent 6 }}strategy:rollingUpdate: # 滚动更新maxSurge: {{ .Values.rollingUpdate.maxSurge }} # 指定可以超过期望的pod数量的最大百分比,也可以是个数maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }} # 指定升级过程中不可用Pod的最大数量type: {{ .Values.rollingUpdate.type }}template:metadata:{{- with .Values.podAnnotations }}annotations:{{- toYaml . | nindent 8 }}{{- end }}labels:{{- include "redis.selectorLabels" . | nindent 8 }}spec:{{- with .Values.imagePullSecrets }}imagePullSecrets:{{- toYaml . | nindent 8 }}{{- end }}securityContext:{{- toYaml .Values.podSecurityContext | nindent 8 }}containers:- name: {{ .Chart.Name }}securityContext:{{- toYaml .Values.securityContext | nindent 12 }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"imagePullPolicy: {{ .Values.image.pullPolicy }}ports:- name: rediscontainerPort: 6379protocol: TCPvolumeMounts:- name: redismountPath: /var/lib/redisenv:- name: REDIS_PORTvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: redis_port- name: REDIS_HOSTvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: redis_host- name: REDIS_PASSWORDvalueFrom:configMapKeyRef:name: {{.Release.Name}}-cfgkey: redis_passwordresources:{{- toYaml .Values.resources | nindent 12 }}volumes: # 使用nfs来存储- name: redisnfs:path: {{ .Values.nfs.path }}server: {{ .Values.nfs.server }}{{- with .Values.nodeSelector }}nodeSelector:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.affinity }}affinity:{{- toYaml . | nindent 8 }}{{- end }}{{- with .Values.tolerations }}tolerations:{{- toYaml . | nindent 8 }}{{- end }}########################## service.yaml ########################### service.yamlapiVersion: v1kind: Servicemetadata:# name: {{ include "redis.fullname" . }}name: redislabels:{{- include "redis.labels" . | nindent 4 }}spec:type: {{ .Values.service.type }}ports:- port: {{ .Values.service.port }}targetPort: redisprotocol: TCPname: redisselector:{{- include "redis.selectorLabels" . | nindent 4 }}sessionAffinity: ClientIP########################## service.yaml ########################### service.yaml# Default values for redis.# This is a YAML-formatted file.# Declare variables to be passed into your templates.replicaCount: 1image:repository: "wojiushixiaobai/jms_redis"pullPolicy: IfNotPresent# Overrides the image tag whose default is the chart appVersion.tag: "1.5.6"imagePullSecrets: []nameOverride: ""fullnameOverride: ""serviceAccount:# Specifies whether a service account should be createdcreate: true# Annotations to add to the service accountannotations: {}# The name of the service account to use.# If not set and create is true, a name is generated using the fullname templatename: ""podAnnotations: {}podSecurityContext: {}# fsGroup: 2000securityContext: {}# capabilities:# drop:# - ALL# readOnlyRootFilesystem: true# runAsNonRoot: true# runAsUser: 1000service:type: ClusterIPport: 6379ingress:enabled: falseannotations: {}# kubernetes.io/ingress.class: nginx# kubernetes.io/tls-acme: "true"hosts:- host: chart-example.localpaths: []tls: []# - secretName: chart-example-tls# hosts:# - chart-example.localresources: {}# We usually recommend not to specify default resources and to leave this as a conscious# choice for the user. This also increases chances charts run on environments with little# resources, such as Minikube. If you do want to specify resources, uncomment the following# lines, adjust them as necessary, and remove the curly braces after 'resources:'.# limits:# cpu: 100m# memory: 128Mi# requests:# cpu: 100m# memory: 128Miautoscaling:enabled: falseminReplicas: 1maxReplicas: 100targetCPUUtilizationPercentage: 80# targetMemoryUtilizationPercentage: 80nodeSelector: {}tolerations: []affinity: {}rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatenfs:server: 192.168.238.100path: /data/redis
其他应用core、guacamole、koko、nginx的实现方式见Github
验证
|
|
参考链接
https://hub.kubeapps.com
https://whmzsu.github.io/helm-doc-zh-cn/
https://github.com/helm/charts