唐抉的个人博客

Kubernetes实践之从yaml创建工作负载

字数统计: 3.5k阅读时长: 13 min
2023/03/31

Pod

Pod是Kubernetes中的基本单位。容器本身不会直接分配到主机上,而会封装到名为Pod的对象中。Kubernetes以Pod为最小单位进行调度、伸缩并共享资源、管理生命周期。

Pod通常表示单个应用程序,由一个或多个关系紧密的容器构成,这些容器拥有同样的生命周期,作为一个整体一起编排到Node上。这些容器共享环境、存储卷(volume)和IP空间。尽管Pod基于一个或多个容器,但应将Pod视作一个单一的整体、单独的应用程序。

Pod模板

在创建Pod时,需要定义一个模板文件(.yml文件),并将其称为Pod模板。可以用Pod模板来定义资源,以下是Pod模板的主要内容及对应说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
---
apiVersion: v1 # 使用的API版本,V1表示使用 Kubernetes API的稳定版本
kind: Pod # 要创建的资源对象,这里为关键字Pod
metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
name: String # 元数据,必填,Pod的名字
namespace: String # 元数据,Pod的命名空间
labels: # 元数据,标签列表
- key: value # 元数据,可定义多个标签的键值对
annotations: # 元数据,自定义注解列表
- key: value # 元数据,可定义多个标签的键值对
spec: # 该资源对象的具体设置,Pod中容器的详细配置,必填
containers: # Pod中的容器列表,必填,可以有多个容器
- name: String # 要创建的容器名称,必填
image: String # 容器的镜像地址,必填
imagePullPolicy: [Always|Never|IfNotPresent] # 镜像的下载策略,支持3种模式
command: [String] # 容器的启动命令列表(不配置则使用镜像内部的命令)
args: [String] # 启动参数列表
workingDir: String # 容器的工作目录
volumeMounts: # 挂载到容器内部的存储卷设置
- name: String # 为了引用Pod定义的共享存储卷名称,要用volumes[]部分定义的卷名
mountPath: String # 存储卷在容器内挂载的绝对路径,应少于512个字符
readOnly: Boolean # 是否为只读模式
ports: # 容器需要暴露的端口号列表
- name: String # 端口名称
containerPort: int # 容器要暴露的端口
hostPost: int # 容器所在主机监听的端口(把容器暴露的端口映射到宿主机的端口)
protocol: String # 端口协议,支持TCP和UDP,默认为TCP
env: # 容器运行前要设置的环境变量列表
- name: String # 环境变量名称
value: String # 环境变量值
resources: # 资源限制和请求的设置
limits: # 资源限制的设置
cpu: String # cpu限制,单位为CPU内核数,也可以使用小数,如0.1,0.1等价于表达式100m,表示100milicpu
memory: String # 内存限制,单位可以为MiB/GiB/MB/GB (1MB=1024x1024B=1024x1024x1000x1000B)。
requests: # 资源请求的设置
cpu: String # cpu请求,容器启动时的初始可用数量
memory: String # 内存请求,容器启动时的初始可用数量
livenessProbe: # Pod内容器健康检查的设置,当探测几次无响应后将自动重启该容器。
# 检查方法有exec、httpGet、tcpSocket,对一个容器只要设置一种方法即可
exec: # 通过exec方式来检查Pod内各容器的健康情况
command: [String] # exec方式需要指定的命令或脚本
httpGet: # 通过httpGet方式来检查Pod内各容器的健康情况,需要指定path、port
path: String
port: number
host: String
scheme: String
httpHeaders:
- name: String
value: String
tcpSocket: # 通过tcpSocket方式来检查Pod内各容器的健康情况
port: number
initialDelaySeconds: 0 # 容器启动完成后,首次探测的时间(单位为秒)
timeoutSeconds: 0 # 对容器进行健康检查时探测等待响应的超时时间(单位为秒,默认为1s)
periodSeconds: 0 # 对容器监控检查的定期探测时间设置(单位为秒,默认10s一次)
successThreshold: 0
failureThreshold: 0
securityContext: # 安全配置
privileged: false
restartPolicy: [Always|Never|OnFailure] # Pod的重启策略,有三种可以选
nodeSelector: # 节点选择,设置nodeSelector表示将该Pod调度到包含这个标签的节点上
- key: value
imagePullSecrets: # 拉取镜像时使用的secret名称
- name: String
hostNetwork: false # 是否使用主机网络模式,默认为false
volumes: # 在该Pod上定义的共享存储卷列表
- name: String # 共享存储卷名称
emptyDir: {} # 类型为emptyDir的存储卷,与Pod有相同生命周期的一个临时目录,为空值
hostPath: # 类型为hostPathr的存储卷,将会挂载Pod所在宿主机的目录
path: String
secret: #类型为secret的存储卷,在容器内部挂载集群中预定义的secret对象
secretName: String
items:
- key: String
path: String
configMap: #类型为secret的存储卷,挂载预定义的configMap对象到容器内部
name: String
items:
- key: String
path: String

控制器——Pod的管理

一般来说,用户不会直接创建Pod,而是创建控制器,让控制器来管理Pod。在控制器中定义Pod的部署方式,如有多少个副本、需要在哪种Node上运行等。根据不同的业务场景,Kubernetes提供了多种控制器。

Deployment 控制器(部署)

Deployment控制器是最常用的工作负载对象之一。

在使用Kubernetes时,通常要管理由多个相同Pod所组成的Pod集合,而不是单个Pod。通过Deployment控制器,可以定义Pod模板,并设置相应控制参数以实现水平伸缩,以调节正在运行的相同Pod数。

Deployment控制器保证在集群中部署的Pod数量和配置中的Pod数量一致。若Pod或主机出现故障,则会自动启用新的Pod进行补充。

创建Deployment 控制器也需要定义一个模板文件(.yml文件)。可以用Deployment控制器的模板来定义资源,以下是模板的主要内容及对应说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---
apiVersion: apps/v1 # 使用的API版本,V1表示使用稳定版本
kind: Deployment # 要创建的资源对象,这里为关键字Deployment
metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
name: String # 元数据,必填,Deployment控制器的名字
namespace: String # 元数据,Deployment控制器的命名空间
labels: # 元数据,标签列表
- key: value # 元数据,可定义多个标签的键值对
annotations: # 元数据,自定义注解列表
- key: value # 元数据,可定义多个标签的键值对
spec:
selector: # 必填,用于指定Deployment控制器针对的Pod的标签选择器,需要与template中的标签匹配
matchLabels: # 定义需要匹配的标签集合
key: value # 需要匹配的标签,可定义多个标签的键值对
template: [PodTemplate] # 必填,Pod模板,它与Pod具有完全相同的结构,不过他是嵌套的,且不需要带apiVersion或kind字段
replicas: int # 指定所需Pod的数量,默认为1
strategy: # 更新时替换旧Pod的策略
type: Recreate/RollingUpdate # Recreate表示现有的Pod都会在创建新的Pod之前被终止,RollingUpdate表示以滚动更新方式更新Pod
rollingUpdate:
maxSurge: int/int% # 在滚动更新时,在所需数量的Pod上允许创建的最大Pod数,也可用百分比形式
maxUnavailable: int/int% # 在滚动更新时,同时存在最大不可用Pod数,也可用百分比形式
progressDeadlineseconds: int # Deployment控制器处于进行状态时的等待秒数,超过这个时间将会变为失败
minReadySeconds: int # 指定新创建的Pod应该在没有任何容器崩溃的情况下准备好的最短秒数
revisionHistoryLimit: int # 指定要保留的允许回滚的旧ReplicaSet数量
paused: boolean # 默认为false,用于暂停和恢复部署,当暂停部署时,Pod模板中spec属性的任何更改都不会触发新的部署

DaemonSet 控制器(有状态副本集)

DaemonSet 控制器是一种特殊的Pod控制器,会在集群中的各个节点上运行单一的Pod副本。它非常适合部署那些为节点本身提供服务或执行维护的Pod。如对于日志收集和转发、监控以及运行以增加节点本身功能为目的的服务都使用DaemonSet 控制器。

DaemonSet 控制器的一些典型用法包括但不限于以下几种:

  • 运行集群存储Daemon控制器,如在每个Node上运行glusterd、ceph。
  • 在每个Node上运行日志收集Daemon控制器,如Fluentd、logstash。
  • 在每个Node上运行监控Daemon控制器,如Prometheus Node Exporter、collectd、Datadog代理、New Relic代理或Ganglia gmond。

创建DaemonSet 控制器的模板与Deployment控制器的模板相同

Job与CronJob控制器

Job工作负载

Job的工作负载对象基于某一特定任务而运行,当运行任务的容器完成工作后,就会成功退出。若需要执行一次性任务,而非提供连续的服务,则适合创建job工作负载。

Job控制器可以执行3种类型的任务:

  • 一次性任务:通常只会启动一个Pod(除非Pod失败)。一旦Pod成功终止,Job就算完成了。其模板如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ---
    apiVersion: batch/v1 # 使用的API版本,V1表示使用稳定版本
    kind: Job # 要创建的资源对象,这里为关键字Job
    metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
    name: String # 元数据,必填,Job工作负载的名字
    spec:
    template: # 必填,Pod模板,它与Pod具有完全相同的结构,不过他是嵌套的,且不需要带apiVersion或kind字段
    spec:
    activeDeadlineSeconds: int # 指定执行任务的上限时间(单位为秒),超时时任务将强制终止并删除
    ttlSecondsAfterFinished: int # 用于确定在所有任务执行完成后,需要等待多少秒才可删除Job,默认关闭
    restartPolicy: [Never|OnFailure]
    containers:
    - name: String
    image: String
    imagePullPolicy:
    command: [String]
    - --feature-gates=TTLSecondsAfterFinished=true # 手动开启自动删除Job功能
    args: [String]

  • 串行式任务:连续、多次地执行某一任务。当上一个任务完成时,接着执行下一个任务,直到全部任务执行完,可以通过spec.completions属性指定执行次数。其模板如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ---
    apiVersion: batch/v1 # 使用的API版本,V1表示使用稳定版本
    kind: Job # 要创建的资源对象,这里为关键字Job
    metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
    name: String # 元数据,必填,Job工作负载的名字
    spec:
    activeDeadlineSeconds: int # 指定执行任务的上限时间(单位为秒),超时时任务将强制终止并删除
    completions: int # 设置任务执行次数
    template: # 必填,Pod模板,它与Pod具有完全相同的结构,不过他是嵌套的,且不需要带apiVersion或kind字段
    spec:
    restartPolicy: [Never|OnFailure]
    containers:
    - name: String
    image: String
    imagePullPolicy:
    command: [String]
    args: [String]

  • 并行式任务:同一时间并发多次执行任务。可以通过spec.parallelism属性指定并发数,也可以配合spec.completions属性指定总任务的执行次数。其模板如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    ---
    apiVersion: batch/v1 # 使用的API版本,V1表示使用稳定版本
    kind: Job # 要创建的资源对象,这里为关键字Job
    metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
    name: String # 元数据,必填,Job工作负载的名字
    spec:
    activeDeadlineSeconds: int # 指定执行任务的上限时间(单位为秒),超时时任务将强制终止并删除
    completions: int # 设置任务执行次数
    parallelism: int # 设置任务并行数
    template: # 必填,Pod模板,它与Pod具有完全相同的结构,不过他是嵌套的,且不需要带apiVersion或kind字段
    spec:
    restartPolicy: [Never|OnFailure]
    containers:
    - name: String
    image: String
    imagePullPolicy:
    command: [String]
    args: [String]

CronJob控制器

CronJob控制器是在Job的基础上增加了时间调度,可以在给定的时间点运行一个任务,也可以定期地运行。

通过CronJob控制器,可以实现以下类型的Job:

  • 在未来的某个指定时间执行一次Job,例如某项临时任务
  • 周期性地运行Job,例如,定期备份,发送邮件等

CronJob控制器的模板如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
apiVersion: batch/v1betal # CronJob控制器目前只存在betal版本中
kind: CronJob # 要创建的资源对象,这里为关键字CronJob
metadata: # 表示该资源对象的元数据,一个资源对象可拥有多个元数据。表示资源的标识信息
name: String # 元数据,必填,CronJob控制器的名字
namespace: String # 元数据,CronJob控制器的命名空间
labels: # 元数据,标签列表
- key: value # 元数据,可定义多个标签的键值对
annotations: # 元数据,自定义注解列表
- key: value # 元数据,可定义多个标签的键值对
spec:
schedule: String # 必填,指定任务运行周期,格式同Cron
jobTemplate: [JobTemplate] # 必填,Job模板
startingDeadlineSeconds: int # 启动Job的期限(秒)。若执行时间超时,Job将被任务是失败的。若没有指定,则没有期限
concurrencyPolicy: [Allow|Forbid|Replace]
# 若上一个周期的Job没执行完,而下一个周期已开始,在这种并发场景下默认采用Allow策略,允许并发运行Job
# Forbid表示禁止并发运行,若上一个周期的Job没执行完,则下一个周期会被忽略并不再执行
# Replace表示取消当前正在运行的Job,用一个新的来替换
suspend: boolean # 若设置为true,而上一个周期的Job没执行完,而下一个周期已开始,则后续所有执行都会被挂起
successfulJobsHistoryLimit: int # 保留多少条执行成功的Job记录,默认为3
failedJobsHistoryLimit: int # 保留多少条执行失败的Job记录,默认为1
CATALOG
  1. 1. Pod
  2. 2. Pod模板
  3. 3. 控制器——Pod的管理
    1. 3.1. Deployment 控制器(部署)
    2. 3.2. DaemonSet 控制器(有状态副本集)
    3. 3.3. Job与CronJob控制器
      1. 3.3.1. Job工作负载
      2. 3.3.2. CronJob控制器