怎样配置Rancher2中的Charts
Helm是目前Kubernetes服务编排领域的唯一开源子项目,是Kubernetes应用的一个包管理工具。
Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。
具体来说,Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库,通过chart仓库可用来存储和分享chart,使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。
Rancher2中由于编排工具改为k8s,不再有rancher-compose.yml和docker-compose.yml,采用helm进行包管理。
1. Chart中的配置模板层级
rancher2中Chart模板采用了多层级的配置,一个项目由若干模块组成。为了便于集中配置,将所有的配置都模板化,只需在values.yaml中配置即可。
helm-repo-qa repo源
└─app
├─app-sample 项目名
│ │ catalogIcon.png 项目图标
│ │
│ ├─10.0.0-auto-sample-0.1.1-2988 版本(%d.%d.%d-%s,SemVer 2标准)
│ │ │ .helmignore helm默认文件
│ │ │ Chart.yaml 描述了Chart名称、描述信息与版本
│ │ │ questions.yaml 部署时变量,主要配置consul和category
│ │ │ values.yaml 存储了模板文件变量
│ │ │
│ │ └─templates
│ │ │ NOTES.txt 部署后的备注
│ │ │ _helpers.tpl 运行时参数
│ │ │
│ │ └─auto-sample 项目组成模块(字母开头,允许小写英文/数字/-)
│ │ deployment.yaml 模块容器配置模板
│ │ service.yaml 模块服务暴露模板
│ │
新建模板时需要关注:template/*; catalogIcon.png; Chart.yaml; values.yaml
deploymen.yaml和service.yaml中已经固定了常用的配置模板,而不需要单独修改其中内容,可以统一在values.yaml中修改配置。所以values.yaml是最重要的配置项。
通常情况下,一个depolyment包含一个主容器,有一些包含initContainer用于取consul
2. 生成母模板templates
为项目生成的渲染模板在rancher2-template
我们为template定义了通用模板,绝大部分的配置需求可以都在values中完成定义。一个项目下,templates为每个模块定义了deployment和service,用于定义镜像和服务发现。
auto-sample-deployment.yaml
{{- if .Values.autoSample.enabled -}}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: {{ template "name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: "{{ .Values.autoSample.name }}"
name: {{ template "autoSample.fullname" . }}
spec:
replicas: {{ .Values.autoSample.replicaCount }}
template:
metadata:
{{- if .Values.autoSample.podAnnotations }}
annotations:
{{ toYaml .Values.autoSample.podAnnotations | indent 8 }}
{{- end }}
labels:
app: {{ template "name" . }}
component: "{{ .Values.autoSample.name }}"
release: {{ .Release.Name }}
spec:
containers:
- name: {{ template "name" . }}-{{ .Values.autoSample.name }}
image: "{{ .Values.autoSample.image.repository }}:{{ .Values.autoSample.image.tag }}"
imagePullPolicy: "{{ .Values.autoSample.image.pullPolicy }}"
env:
{{- range $key, $value := .Values.autoSample.env }}
- name: {{ $key }}
value: {{ $value }}
{{- end }}
{{- if .Values.autoSample.command }}
command:
{{ toYaml .Values.autoSample.command | indent 12 }}
{{- end }}
{{- if .Values.autoSample.args }}
args:
{{ toYaml .Values.autoSample.args | indent 12 }}
{{- end }}
{{- if .Values.autoSample.ports }}
ports:
{{ toYaml .Values.autoSample.ports | indent 12 }}
{{- end }}
{{- if .Values.autoSample.resources }}
resources:
{{ toYaml .Values.autoSample.resources | indent 12 }}
{{- end }}
{{- if .Values.autoSample.volumeMounts }}
volumeMounts:
{{ toYaml .Values.autoSample.volumeMounts | indent 12 }}
{{- end }}
{{- if .Values.autoSample.nodeSelector }}
nodeSelector:
{{ toYaml .Values.autoSample.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.autoSample.tolerations }}
tolerations:
{{ toYaml .Values.autoSample.tolerations | indent 8 }}
{{- end }}
{{- if .Values.autoSample.affinity }}
affinity:
{{ toYaml .Values.autoSample.affinity | indent 8 }}
{{- end }}
{{- if .Values.autoSample.volumes }}
volumes:
{{ toYaml .Values.autoSample.volumes | indent 8 }}
{{- end }}
{{- end -}}
service用于namespace内部应用发现
auto-sample-service.yml
{{- if .Values.autoSample.enabled -}}
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ template "name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: "{{ .Values.autoSample.name }}"
name: {{ template "autoSample.fullname" . }}
spec:
clusterIP: "None"
ports:
{{ toYaml .Values.autoSample.service.ports | indent 4 }}
selector:
app: {{ template "name" . }}
release: {{ .Release.Name }}
component: "{{ .Values.autoSample.name }}"
type: "{{ .Values.autoSample.service.type }}"
{{- end -}}
关于label
label用于标记每个部署,并且支持资源调度。k8s需要对资源大量打标签(Node, APP, pod, ...)。
3. 需求样例
通过建立一个项目,说明如何配置helm。
项目auto-sample包括一个模块autoSample,需要进行init初始化,起1份应用,镜像为 registry-ci.*******.com/automation/auto-sample:0.1.1-2990 不需要启动命令,不需要暴露端口到宿主机,不指定宿主机节点,不需要额外挂载主机磁盘,不做容量限制。默认开通42端口/TCP进行namespace内服务发现。
values.yaml
autoSample:
enabled: true
image:
pullPolicy: IfNotPresent
repository: registry-ci.*******.com/automation/auto-sample
tag: 0.1.1-2990
registrySecret: reg-ci-secret
name: auto-sample
replicaCount: 1
service:
ports:
- port: 42
protocol: TCP
targetPort: 42
volumeMounts:
- mountPath: /tmp/
name: consul-volume
volumes:
- emptyDir: {}
name: consul-volume
4. Step-by-step guide for values.yaml
4.1. 最外层的key--模块名称
key==autoSample是用来适配多模块程序的部署的,方便将多个模块的templates目录下的文件参数集中配置,并不是模块的名称。键值和模块template通常由ponyes统一生成,不要随意修改,需要和每一个模块内部文件参数对应。
4.2. 模块必填参数:
参数名称 | 含义 | 例子 |
---|---|---|
enabled | 表明该模块对应的templates下的配置需要生效 | enabled: true |
name | 模块的名称,必须由(小写字母,数字,-)组成,部署后出现在labels.component,也可用于指定部署后workload名称 | name: app-sample |
image: pullPolicy: registrySecret repository: tag: |
镜像的配置 1. 默认IfNotPresent,可选["IfNotPresent", "Always", "Never"] 2. CI流程需要secret ["reg-secret", "reg-ci-secret"] 3. registry路径 4. 镜像版本 |
image: pullPolicy: Always registrySecret: reg-secret repository: registry.*******.com/automation/auto-sample tag: 0.1.2-10 |
replicaCount | 每次部署时pod的数量 | replicaCount: 1 |
4.3. 模块选填参数:
该部分用于定义可选参数和k8s高级特性。
此处定义的值主要在deployment.yml中引用
参数名称 | 含义 | 例子 |
---|---|---|
podAnnotations | 备注信息,rancher自身大量使用 | https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ |
env | 环境变量 | env: - name: DEMO_GREETING value: "Hello from the environment" |
command | 命令,相当于docker-compose的entrypoint | command: ["/bin/bash"] |
args | 参数,相当于docker-compose的command | args: ["-c", "/usr/bin/*******-init"] |
ports | pod端口暴露到宿主机端口,默认不需配 推荐ingress做7层转发 |
容器tcp端口5044端口映射到当前主机5044端口 ports: - containerPort: 5044 hostPort: 5044 protocol: TCPprotocol: TCP |
resources | 约束cpu内存使用 spec.containers[].resources.limits.cpu spec.containers[].resources.limits.memory spec.containers[].resources.requests.cpu spec.containers[].resources.requests.memory https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#how-pods-with-resource-requests-are-scheduled |
resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
volumeMounts | 容器内磁盘挂载 | volumeMounts: - mountPath:/*******/ponyes/logs name: ponyes-vol0 - mountPath:/tmp/ name: consul-volume |
volumes | 宿主机磁盘挂载 | volumes: - emptyDir: {} name: consul-volume - hostPath: path: /*******/local_logs/logs/devops/ponyes/ type: "" name: ponyes-vol0 |
readinessProbe | 启动时间长,防止自动删除 | readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5 |
livenessProbe | 检测应用在长时间使用后是否仍正常 三种形式:命令行,http get,TCP Socket open |
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-readiness-probes |
nodeSelector | 最简单的资源约束,采用key:value形式选择 | nodeSelector: disktype: ssd kubernetes.io/hostname: rancher2-node01 |
tolerations | 容忍不参与调度的污点节点可以参与调度 | tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" |
affinity | 亲和性/反亲和性,基于label的调度,分为节点亲和/反亲和,pod亲和/反亲和 | https://kubernetes.io/blog/2017/03/advanced-scheduling-in-kubernetes/ |
此处定义的值在service.yml中引用。默认采用headless的ClusterIP
参数名称 | 含义 | 例子 |
---|---|---|
service.ports | 端口发现,默认42端口(互联网名称服务) | service: ports: - port: 42 protocol: TCP targetPort: 42 |
service.type | ClusterIP,NodePort,LoadBalancer,ExternalName | 默认不配 |
5. additional values from questions.yaml
固定模板,但是可以在launch时认为调整值的变量可以放在此处,比如一套模板需要同时部署在qa和stg环境,但是consul值不同时,可以将变量定义在questions,方便CD. categories可按照不同产品分组,方便launch时查找。
categories:
- devops
questions:
- default: ""
description: "Consul Server Host, http/https and port should be included."
label: "consul-server"
required: true
type: string
variable: consulServer
- default: ""
description: "Consul login token"
label: "consul-login-token"
required: true
type: string
variable: consulToken
- default: "/container/"
description: ""
label: "OVERWRITE_CONSUL_PATH_FOLDER"
required: false
type: string
variable: consulFolderPath
6. 在templates中引用values
默认的渲染模板可以满足大多数项目的需求。
values.yaml和questions.yaml中的变量采用以下方式在template中定义:
{{ .Values.consulServer }}
{{ .Values.autoSample.image.repository }}
网友评论