Table of Contents generated with DocToc
- Chart 模版配置规范定义(v1.0.0)
规范主要用于定义 Chart 配置文件 values.yaml 的逻辑结构和类型。
我们将一个 Chart 包含的内容定义为一个应用,一个应用通常包含 Pod Controller,Service,Config,Volume 四块主要内容:
- Pod Controller:Deployment,StatefulSet,DaemonSet,Job,CronJob
- Service:Service
- Config:ConfigMap,Secret
- Volume:PVC,ConfigMap,Secret,EmptyDir
上述的对应关系并没有包含所有的 Kubernetes 资源,即我们认为其他资源是与应用是弱/无耦合的。
并且其中 ConfigMap,Secret 也不是由 Chart 主动创建的,而是应当在应用创建之前就应该在集群中存在,并由应用引用,产生单向依赖。
配置文件使用 yaml 格式,并且在实际使用中转换为 json 格式。
标准配置文件结构如下:
# 顶级配置 key ,固定为 _config
_config:
# 在配置文件中,所有以 _ 开头的字段用于存储特殊信息。
# 模板元数据,表示当前配置所属的 Chart 信息,此处数据用于存储模版最原始的信息
_metadata:
name: string # Chart 创建时的名称,不随 Chart 更新而更新
version: semvar # Chart 创建时的版本号,不随 Chart 更新而更新
description: string # Chart 创建时的描述,不随 Chart 更新而更新
template: # Chart 模板信息,为模板自动升级提供信息
type: string # Chart 模板类型
version: semvar # Chart 模板版本号
appVersion: string # Chart 创建 workload 时的版本号,会添加到 pod 的 label 中,目前多用于灰度发布。
# 配置控制器组,配置控制器组可以包含多个配置控制器
# 此处的配置控制器与上面所描述的 Pod Controller 不同,此处的配置控制器具有如下等价关系:
# 配置控制器 = 1个 Pod Controller 配置 +
# 1个 调度 配置 +
# 1个 容器组 配置 +
# 0个或多个 初始化容器 配置 +
# 1个或多个 基本容器 配置 +
# 0个或多个 数据卷 配置 +
# 0个或多个 服务 配置
controllers:
- type: string # 指定控制器的类型,可以是 Deployment,StatefulSet,DaemonSet,Job,CronJob
controller: # 控制器信息,对应特定 type 的控制器信息
...
schedule: # 调度信息,用于控制容器组的调度
...
pod: # 容器组信息,指定当前控制器下的所有容器(包括 initializers 和 containers)共享的设置内容
...
initContainers: # 初始化容器数组,可用于放置仅用于初始化阶段的容器,比如初始化数据
- ...
containers: # 基本容器数组,用于放置真正执行工作的容器
- ...
volumes: # 数据卷描述信息数组,这部分数据卷可以被多个容器共享访问
- ...
services: # 服务信息数组,当前控制器内的容器需要暴露服务时,在这里添加服务。一个控制器可有多个服务
- ...
configs: # 配置信息数组
- ...
secrets: # 加密配置信息数组
- ...
chartX:
# 子模版 chartX 的配置,其结构与上面的 _config 相同
_config:
...
_metadata
仅仅用于描述模板的基本信息。
- name,version,description 用于描述 Chart 的原始信息。用于从配置直接创建 Chart。
- template 用于描述 Chart 的模板信息。主要用于实现 Chart 的创建和升级。template 发生功能变更后,可依据模板名称和版本号进行升级。
字段类型定义:
int: 整数
uint: 自然数
pint: 正整数
float: 实数
string: 字符串
bool: 布尔值,只能是 true 或 false
默认值声明方式:
类型(默认值)
int(-1)
uint(0)
pint(1)
float(3.14)
string("default value")
bool(true)
所有有默认值的字段都是 Optional 的。
所有类型的 controller 共有字段如下:
annotations: # 控制器附加信息,仅用于保存控制器额外信息
- key: string # 键
value: string # 值
key 必须符合如下要求:
1. `前缀/键`或者`键`,比如 `caicloud.io/apple`和`apple`
2. 前缀是域名形式,必须符合 DNS_SUBDOMAIN,即`(([A-Za-z0-9][-A-Za-z0-9]*)?[A-Za-z0-9]\.)*([A-Za-z0-9][-A-Za-z0-9]*)?[A-Za-z0-9]`
3. 键必须符合 ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]
name: string("") # 实例前缀名,控制器名称
replica: uint(1) # 实例数量
strategy: # 实例滚动更新策略,两个选项不能同时为0
type: string("RollingUpdate") # 更新策略,只能为 RollingUpdate(滚动更新) 或者 Recreate(重新创建)
unavailable: uint(0) # 最大不可用数量
surge: uint(1) # 最大超量
ready: uint(0) # 实例从 Available 到 Ready 的最短时间
一个实例在运行时等价于一个容器组,可以通过 replica 指定需要的实例数量,即可在集群中同时跑多个实例。
当实例的配置需要更新时,根据更新策略决定如何重启实例。unavailable 表明当前控制器可以先关闭多少个运行中的实例。surge 表示当前控制器可以在 replica 的基础上多创建多少个新的实例。即在滚动更新过程中,实例的数量可能在[max(replica-unavailable,0),replica+surge]区间。
replica: uint(1) # 实例数量
name: string("") # 实例前缀名,控制器名称
domain: string("") # 实例域名
strategy: # 实例滚动更新策略
type: string("RollingUpdate") # 更新策略,只能为 RollingUpdate(滚动更新) 或者 OnDelete(删除时更新)
rollingUpdate: # 滚动更新配置,只有当 RollingUpdate 时才可以此选项
partition: uint(0) # 分段更新序号
podManagementPolicy: string("OrderedReady") # Pod 管理策略, 只能为 OrderedReady 或 Parallel
指定 name 和 domain 后,可通过 name-序号.domain 的形式访问每个实例。
比如 replica = 2, name = "web", domain = "cluster", 那么同一个分区内可使用 web-0.cluster,web-1.cluster 访问两个实例,同时能够直接使用 cluster 访问任意一个实例(RoundRobin)。
由于前缀名称和域名具有分区范围内的唯一性,因此同一个分区内的应用不能具有相同的 name 和 domain。同时由于 domain 能够被用于访问任意一个实例,因此也不能与同一分区下的 services 冲突。
name: string("") # 实例前缀名,控制器名称
strategy: # 实例滚动更新策略,两个选项不能同时为0
unavailable: pint(1) # 最大不可用数量
ready: uint(0) # 实例从 Available 到 Ready 的最短时间
name: string("") # 实例前缀名,控制器名称
parallelism: pint(1) # 最大并行实例数量
backoffLimit: pint(1) # 失败重试次数
completions: pint(1) # 总共需要完成的实例数量
active: uint(0) # 单个实例执行的最长时间,0表示不限制
一个任务可以同时执行多个实例,通过 parallelism 和 completions 可以控制任务是串行执行还是并行执行或是控制并行执行。
- 串行:completions = n, parallelism = 1 即可让 n 个实例串行执行,只有前一个完成后下一个才会执行
- 并行:completions = n, parallelism >= n 即可让 n 个实例同时并行执行
- 控制并行:completions = n, parallelism = k, k < n 即可让 n 个实例同时只有 k 个在执行。其中一个实例完成才能让下一个实例开始执行
name: string("") # 实例前缀名,控制器名称
rule: string # 定时规则,比如 "*/1 * * * *"
deadline: uint(0) # 任务启动超时时间
policy: string("Allow") # 任务并发策略,Allow,Forbid,Replace
suspend: bool(false) # 是否暂停当前定时任务
history: # 任务执行历史保留选项
success: uint(0) # 执行成功的任务保留数量
fail: uint(0) # 执行失败的任务保留数量
parallelism: pint(1) # 最大并行实例数量
backoffLimit: pint(1) # 失败重试次数
completions: pint(1) # 总共需要完成的实例数量
active: uint(0) # 单个实例执行的最长时间,0表示不限制
定时任务规则格式参考:https://en.wikipedia.org/wiki/Cron
定时任务启动超时时间:
举个例子,定时任务设置在每天 8:00:00 执行一次,然后这个字段设置为 10 秒,那么在 8:00:00 - 8:00:10 这个期间内,如果发生了某个特殊的事情,比如 kubernetes 的 定时器 在 7:59:59 - 8:00:11 这个时间段内一直是崩溃的,那么这个定时任务的这一次触发就会被错过,然后就会在定时任务的失败任务数量上加1。
定时任务使用一个 rule 来控制任务的执行。当一个任务未尚未完成,定时器又触发的时候通过 policy 来控制任务的执行方式:
- Allow:上次触发的任务和本次触发的任务一起执行
- Forbid:如果上次的任务尚未完成,那么跳过本次任务的执行
- Replace:取消上次的任务,并开始执行本次的任务
scheduler: string("") # 调度器名称,可选项为 空字符串,为空表示使用默认调度器
labels: # 控制器及 容器组 标签
string: string
affinity: # 亲和性设置
pod:
type: string("Required") # 类型可以为 Required 或 Prefered
terms:
- weight: pint # 权重,只有类型为 Prefered 时可以设置该字段,[1-100]
topologyKey: string("kubernetes.io/hostname") # 拓补域
namespaces: # 指定分区,不指定表示仅在当前分区
- string
selector: # 选择器,用于设置匹配的标签
labels: # 直接指定标签值
string: string
expressions: # 通过表达式查找标签
- key: string
operator: string # 操作符 In,NotIn,Exists,DoesNotExist
values: # 标签值列表
- string
node:
type: string("Required") # 类型可以为 Required 或 Prefered
terms:
- weight: 10 # 权重,只有类型为 Prefered 时可以设置该字段,[1-100]
expressions: # 通过表达式查找标签,表达式为 AND 表达式
- key: string # 这里的 key 不会自动加上前缀
operator: string # 操作符 In,NotIn,Exists,DoesNotExist,Gt,Lt
values:
- string
antiaffinity:
pod: # 反亲和性设置与亲和性设置相同
...
tolerations: # 节点容忍设置
- key: string("key") # key 值
operator: string("Equal") # 与 taint value 值的关系,可以为 Equal,Exists 默认为 Equal
value: string("value") # value 值
effect: string("NoSchedule") # 与 taint value 不匹配的之后的调度策略,可以为 NoSchedule PreferNoSchedule NoExecute
tolerationSeconds: uint(60) # 在 effect 为 NoExecute 时,如果不能忍受 taint, pod 在被驱逐之前可以继续在这个节点运行的时间。
topologyKey 具有如下值:
kubernetes.io/hostname
failure-domain.beta.kubernetes.io/zone
failure-domain.beta.kubernetes.io/region
拓补域用于定义一个节点集合。目前常用的拓补域的 key 有如上三种。拓补域与 Pod 的 亲和性/反亲和性 相关。
一个拓补域至少有一个节点,所有的 亲和性/反亲和性 的权重计算都是在一个域中进行。
比如有多个域,当一个 Pod 在调度时,调度器会根据 亲和性/反亲和性 的设置,在多个域中寻找一个权重最高的域,然后将 Pod 调度到该域中的一个节点上。
kubernetes.io/hostname
与其他两个稍有不同。这个 key 在每个节点上都有不同的值,也就是说,集群里的每个节点都构成了只有一个节点的域。
容忍策略 NoExecute 尚未实现。
restart: string("Always") # 重启策略,可以为 Always,OnFailure,Never
dns: string("ClusterFirst") # DNS 策略,可以为 Default,ClusterFirstWithHostNet,ClusterFirst
hostname: string("") # 主机名
subdomain: string("") # 子域名
termination: uint(30) # 优雅退出时间
serviceAccountName: string("") # ServiceAccount
priorityClassName: string("") # PriorityClassName
host:
network: bool(false) # 与主机共享 network namespace
pid: bool(false) # 与主机共享 pid namespace
ipc: bool(false) # 与主机共享 ipc namespace
hostAliases: # 向容器组的 /etc/hosts 文件添加条目
- ip: string # IP 地址
hostnames: # 主机名列表
- string
securityContext:
runAsNonRoot: bool(false) # 是否以非 root 用户运行
annotations: # 容器组附加信息,仅用于保存容器组额外信息
- key: string # 键
value: string # 值
在 controller 类型为 Deployment 时,restart 只能为 Always。
主机名和子域名构成 Pod 的访问域名:hostname.subdomain.namespace.svc.clusterdomain。
容器组的 annotations 用于存放用于扩展容器组能力的额外信息。可以被其他组件读取和识别,实现其他功能。
key 的规范参考 controller 的 annotations
name: string("") # 容器名称
image: string # 镜像地址
imagePullPolicy: string(Always) # 镜像拉取策略,可以设置为 Always,IfNotPresent
tty: bool(false) # 是否使用 tty
command: # 即 Docker EntryPoint
- string
args: # 即 Docker CMD
- string
workingDir: string("") # 工作目录
securityContext:
privileged: bool(false) # 是否启动特权模式
capabilities: # POISX CAP
add: # 添加 POISX CAP
- string
drop: # 移除 POISX CAP
- string
ports: # 容器端口
- port: pint(80) # 端口
hostPort: pint(0) # 暴露到主机端口
protocol: string("HTTP") # 端口协议,可以是 HTTP,HTTPS,TCP,UDP
envFrom: # env from,来自 Config 或 Secret
- prefix: string("") # 所有来自 目标 的 key 都会加这个前缀
type: string("Config") # 配置来源,可以是 Config 或 Secret
name: string # Config 或 Secret 的名称
optional: bool(false) # 是否可选,即目标不存在也就忽略而不是报错
downwardPrefix: string("") # 默认环境变量前缀
env: # env
- name: string # 环境变量名称
value: string # 环境变量值
from: # value 和 from 只能二选其一
type: string("Config") # 来源类型
name: string # Config 或 Secret 的名称
key: string # data 的 key
resource: string # type 为 ResourceFieldRef 时用的值
optional: bool(false) # 是否可选,即目标不存在也就忽略而不是报错
resources: # 资源限制
requests: # 请求的资源下限
cpu: string("100m") # CPU 资源
memory: string("100Mi") # 内存资源
storage: string("") # 存储资源
gpu: string("") # GPU 资源,Deprecated。建议使用 nvidia.com/gpu
nvidia.com/gpu: string("") # NVIDIA GPU 资源
caicloud.io/local-storage: "0" # 本地存储资源,只是作为标记、影响调度,并无实际意义
limits: # 请求的资源上限
cpu: string("100m") # CPU 资源
memory: string("100Mi") # 内存资源
storage: string("") # 存储资源
gpu: string("") # GPU 资源,Deprecated。建议使用 nvidia.com/gpu
nvidia.com/gpu: string("") # NVIDIA GPU 资源
caicloud.io/local-storage: "0" # 本地存储资源,只是作为标记、影响调度,并无实际意义
mounts: # 挂载数据卷位置
- name: string # 数据卷名称
readonly: bool(false) # 是否只读
path: string # 挂载路径
subpath: string("") # 挂载的数据卷子路径
propagation: string("None") # 挂载传播类型,可选项为 None,HostToContainer,Bidirectional
probe: # 健康检查
liveness: # 存活检查(参考 probe 设置)
...
readiness: # 可读检查(参考 probe 设置)
...
lifecycle: # 生命周期(参考 handler 设置)
postStart: # 启动后调用,调用失败则重启容器
...
preStop: # 停止前调用,调用后无论成功失败都会终止容器
...
initContainer 不支持 readiness probe 和 lifecycle,因此在 initContainer 中不能设置这几项。
initContainer 是串行执行的,一个成功后才能执行下一个。
默认的环境变量包括:
POD_NAMESPACE
POD_NAME
POD_IP
NODE_NAME
可以通过 downwardPrefix 为上述环境变量增加前缀。比如 downwardPrefix 为 ENV_
时:POD_NAMESPACE
变为 ENV_POD_NAMESPACE
。
handler: # 调用 handler 检查方式
...
delay: uint(0) # 从容器启动到发送健康检查请求的时间间隔(秒)
timeout: pint(1) # 单次请求的超时时间(秒)
period: pint(10) # 请求时间间隔(秒)
threshold:
success: pint(1) # 连续多少次请求成功则认为健康
failure: pint(3) # 连续多少次请求失败则认为不健康
type: string(HTTP) # handler 类型,可以为 HTTP,EXEC,TCP
method: # handler 方法
...
command: # 执行命令
- string
scheme: string(HTTP) # HTTP 或 HTTPS
host: string("") # Host 字段,默认是 pod ip, 如果只是想使用域名,请填在 headers 里面
port: pint # 容器端口
path: string # HTTP Path
headers: # 请求头
- name: string # Header 名称
value: string # Header 值
对于 host
这个字段,在 kubernetes 官网的解释里面说明,大部分情况下是用不上的,有一种情况是,如果你的 container 监听了 127.0.0.1
并且 pod 使用了 hostNetwork,则这个 host
需要修改成 127.0.0.1
。在其他通用的使用场景中,你的 container 里面提供了多个虚拟域名(如 nginx 反向代理),那么你应该在 headers
里面设置 Host
的值,而不是使用 host
。
port: pint # TCP 端口
name: string # 数据卷名称,在容器中被引用
type: string("Scratch") # 可选项为 Dedicated,Dynamic,Static,Scratch,Config,Secret,HostPath。Dedicated 仅在控制器为 StatefulSet 时可用
source: # source 的设置与 type 有关
...
storage: # 存储需求
request: string("5Gi") # 请求的最小存储容量
limit: string("10Gi") # 请求的最大存储容量
class: string # 存储方案名称
modes:
- string("ReadWriteOnce") # 数据卷读写模式,可以为 ReadWriteOnce,ReadOnlyMany,ReadWriteMany
Dynamic 和 Dedicated 两种类型的数据卷实际上都是使用存储方案来实现,即通过创建 PVC 并关联 storage class。
但是 Dynamic 只用于创建单一的 PVC,如果多个容器引用同一个 Dynamic,那么实际上多个副本是共享数据卷的(多副本时 mode 不能为 ReadWriteOnce)。
Dedicated 类型仅用于 StatefulSet 类型的控制器。StatefulSet 会根据 Dedicated 的设置动态创建多个 PVC,并且每个 Pod 会绑定不同的 PVC,即每个 Pod 的数据卷是独立的。
这两种类型的数据卷在部署后,volume 中的所有字段值都不能进行更改。
target: string # 已创建的数据卷名称
readonly: bool(false) # 是否以只读形式挂载
Static 类型的数据卷只能用于使用已经创建好数据卷(PVC)。
medium: string("") # 存储介质,可以为 空字符串 或 Memory
Scratch 表示使用临时数据卷 EmptyDir。
target: string # 已创建的 Config 或 Secret
items:
- key: string # 配置文件 data 中的 key
path: string # 设置 key 对应的值在数据卷中的绝对路径
mode: string("0644") # 文件读写模式,如果这里为空则使用默认文件读写模式
default: string("0644") # 默认文件读写模式
optional: bool(false) # 是否允许指定的 Config 或 Secret 不存在
Config 和 Secret 表示使用 配置 或 秘钥 作为数据卷。能够指定 配置 和 秘钥 的多个 key 作为文件使用。
path: string # 本地文件路径
endpoints: string # glusterfs endpoints
path: string # glusterfs volume path
readonly: bool(false) # 是否以只读形式挂载
name: string # 服务名称
type: string(ClusterIP) # 服务类型,可以是 ClusterIP,NodePort
ports:
- protocol: string(HTTP) # 端口协议,可以是 HTTP,HTTPS,TCP,UDP
targetPort: pint # 容器端口
port: pint # 服务端口
nodePort: uint(0) # 节点端口,[30000,32767]
annotations: # 服务附加信息,仅用于保存服务额外信息
- key: string # 键
value: string # 值
selector: # 服务会将流量路由到标签匹配的 Pod
string: string # 直接指定标签值
sessionAffinity: ClientIP # 会话保持类型 仅支持 ClientIP 和 None
affinityTimeout: 10800 # 会话保持超时时间 单位秒 默认 10800 范围是 (0, 86400]
服务可以以两种形式暴露给外部:
- ClusterIP:使用该形式暴露的服务,其它应用可以通过服务名访问当前服务
- NodePort:使用该形式暴露的服务,其它应用可以通过节点 IP 访问当前服务
服务类型为 NodePort 时,才可以设置 ports 中的 nodePort 字段。
服务在部署后,服务名称不可变更。
name: string # 配置名称
data:
- key: string # 键
value: string # 值
name: string # 加密配置名称
type: string(Opaque) # 加密配置类型
data:
- key: string # 键
value: string # 值,必须是原始值经过 base64 编码后的字符串
加密配置的类型包括:
- Opaque:默认加密配置类型,key 可以是任意有效的字符串
- kubernetes.io/service-account-token: ServiceAccount,key 包括
- kubernetes.io/service-account.name
- kubernetes.io/service-account.uid
- token
- kubernetes.kubeconfig
- ca.crt
- namespace
- kubernetes.io/dockercfg: Docker config,key 包括
- .dockercfg
- kubernetes.io/dockerconfigjson: Docker config json,key 包括
- .dockerconfigjson
- kubernetes.io/basic-auth: Basic auth,key 包括
- username
- password
- kubernetes.io/ssh-auth: SSH auth,key 包括
- ssh-privatekey
- kubernetes.io/tls: TLS 证书密钥(PEM),key 包括
- tls.crt
- tls.key
_config:
_metadata:
name: template
version: 1.0.0
description: "A basic template for application"
creationTime: "2017-07-14 12:00:00"
source: "/library/template/1.0.0"
class: Default
template:
type: "template.caicloud.io/application"
version: 1.0.0
controllers:
- type: StatefulSet
controller:
replica: 3
name: "mysqlcluster"
domain: "mysql"
schedule:
labels:
cpu: heavy
io: heavy
affinity:
node:
type: Prefered
terms:
- weight: 10
expressions:
- key: cpu
operator: NotIn
values:
- heavy
- midium
pod:
type: Required
terms:
- selector:
labels:
cpu: heavy
antiaffinity:
pod:
type: Prefered
terms:
- weight: 10
selector:
expressions:
- key: cpu
operator: In
values:
- heavy
- midium
pod:
host:
network: true
initContainers:
- image: mysql-init:v1.0.0
mounts:
- name: db-volume
path: /var/lib/mysql
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
containers:
- image: mysql:v5.6
ports:
- protocol: TCP
port: 3306
mounts:
- name: db-volume
path: /var/lib/mysql
- name: shared-volume
path: /var/lib/logs
envFrom:
- type: Config
name: someconfigmap
prefix: XXXX_
optional: false
downwardPrefix: MY_ENV
env:
- name: XXSS_
value: "sd"
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
probe:
liveness:
handler:
type: HTTP
method:
port: 80
path: /liveness
delay: 10
readiness:
handler:
type: EXEC
method:
command:
- curl
- http://localhost
delay: 15
volumes:
- name: db-volume
type: Dedicated
source:
class: hdd
modes:
- ReadWriteOnce
storage:
request: 5Gi
propagation: None
- name: shared-volume
type: Dynamic
source:
class: ssd
modes:
- ReadWriteMany
storage:
request: 5Gi
limit: 100Gi
services:
- name: mysql1
type: ClusterIP
ports:
- protocol: HTTP
targetPort: 80
port: 80
sessionAffinity: ClientIP
affinityTimeout: 10800
- name: mysql2
type: NodePort
ports:
- protocol: HTTPS
targetPort: 443
port: 443
nodePort: 31222
- type: Deployment
controller:
replica: 1
name: simplelog
containers:
- image: cargo.caicloudprivatetest.com/caicloud/simplelog
mounts:
- name: cfgvolume
path: /etc/simplelog
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
services:
- name: log1
type: ClusterIP
ports:
- protocol: HTTP
targetPort: 80
port: 80
volumes:
name: cfgvolume
type: Config
source:
target: simplecfg
items:
- key: "config.yaml"
path: "config.yaml"
configs:
- name: simplecfg
data:
- key: "config.yaml"
value: |
sync: "5m"
deadline: "3h"
secrets:
- name: simplesecret
data:
- key: "encrypted.cfg"
value: c3luYzogIjVtIgpkZWFkbGluZTogIjNoIgo=
subchart:
_config:
略