pod的调度
控制器:
- rc/rs 副本数量控制器
主要保证pod的数量符合管理员要求,并不会对pod进行额外的管理
以下三种控制器,本质上是服务控制器。具备以下特性:
- 副本数量的控制
- 服务的滚动更新(更新pod)
- 支持更新失败的回滚
- deployment // 更适用于无状态服务
Deployment 用于管理运行一个应用负载的一组 Pod,通常适用于不保持状态的负载。
一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。
你负责描述 Deployment 中的目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。不要管理 Deployment 所拥有的 ReplicaSet。
以下是 Deployments 的典型用例:
- 创建 Deployment 以将 ReplicaSet 上线。ReplicaSet 在后台创建 Pod。 检查 ReplicaSet 的上线状态,查看其是否成功。
- 通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态 。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
- 如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
- 扩大 Deployment 规模以承担更多负载。
- 暂停 Deployment 的上线 以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
- 使用 Deployment 状态来判定上线过程是否出现停滞。
- 清理较旧的不再需要的 ReplicaSet 。
- StatefulSet // 适用于有状态服务
tatefulSet 运行一组 Pod,并为每个 Pod 保留一个稳定的标识。 这可用于管理需要持久化存储或稳定、唯一网络标识的应用。
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。
StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值:
稳定的、唯一的网络标识符。
稳定的、持久的存储。
有序的、优雅的部署和扩缩。
有序的、自动的滚动更新。
在上面描述中,“稳定的”意味着 Pod 调度或重调度的整个过程是有持久性的。 如果应用程序不需要任何稳定的标识符或有序的部署、删除或扩缩, 则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment 或者 ReplicaSet 可能更适用于你的无状态应用部署需要。
限制:
给定 Pod 的存储必须由 PersistentVolume Provisioner (例子在这里) 基于所请求的 storage class 来制备,或者由管理员预先制备。
删除或者扩缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
StatefulSet 当前需要无头服务来负责 Pod 的网络标识。你需要负责创建此服务。
当删除一个 StatefulSet 时,该 StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序且体面地终止,可以在删除之前将 StatefulSet 缩容到 0。
在默认 Pod 管理策略(OrderedReady) 时使用滚动更新, 可能进入需要人工干预才能修复的损坏状态。
- Daemonset // 在每一个筛选出来的节点上运行一个pod
DaemonSet 定义了提供节点本地设施的 Pod。这些设施可能对于集群的运行至关重要,例如网络辅助工具,或者作为 add-on 的一部分。
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的一些典型用法:
在每个节点上运行集群守护进程
在每个节点上运行日志收集守护进程
在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
- job 适合运行单次计算任务而非服务等需要长时间运行的业务
Job 会创建一个或者多个 Pod,并将继续重试 Pod 的执行,直到指定数量的 Pod 成功终止。 随着 Pod 成功结束,Job 跟踪记录成功完成的 Pod 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pod。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。
运维角度,job的常用于:
- 服务部署测试
一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
创建job
[root@control ~]# vim job1.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never // pod不会重启
backoffLimit: 4 // 最大失败次数为4
[root@control ~]# kubectl apply -f job1.yml
job.batch/pi created
[root@control ~]# kubectl get job
NAME STATUS COMPLETIONS DURATION AGE
pi Complete 1/1 10s 19s
[root@control ~]# kubectl get job/pi
NAME STATUS COMPLETIONS DURATION AGE
pi Complete 1/1 10s 47s
查看作业计算结果
[root@control ~]# kubectl logs job/pi
[root@control ~]# kubectl logs pi-2cjhv
控制任务执行次数和并发数
[root@control ~]# kubectl delete job pi
job.batch "pi" deleted
[root@control ~]# vim job1.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 6 // 次数
parallelism: 2 // 并发
completionMode: Indexed
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
root@control ~]# kubectl apply -f job1.yml
job.batch/pi created
[root@control ~]# kubectl get job/pi
NAME STATUS COMPLETIONS DURATION AGE
pi Running 0/6 7s 7s
[root@control ~]# kubectl get job/pi
NAME STATUS COMPLETIONS DURATION AGE
pi Running 0/6 10s 10s
[root@control ~]# kubectl get job/pi
NAME STATUS COMPLETIONS DURATION AGE
pi Running 2/6 19s 19s
[root@control ~]# kubectl describe job/pi
Name: pi
Namespace: default
Selector: batch.kubernetes.io/controller-uid=f5f72ef9-8078-42d5-a1d1-6b3b478e3a9f
Labels: batch.kubernetes.io/controller-uid=f5f72ef9-8078-42d5-a1d1-6b3b478e3a9f
batch.kubernetes.io/job-name=pi
controller-uid=f5f72ef9-8078-42d5-a1d1-6b3b478e3a9f
job-name=pi
Annotations: <none>
Parallelism: 2
Completions: 6
Completion Mode: Indexed
Suspend: false
Backoff Limit: 4
Start Time: Thu, 26 Sep 2024 10:45:39 +0800
Completed At: Thu, 26 Sep 2024 10:46:12 +0800
Duration: 33s
Pods Statuses: 0 Active (0 Ready) / 6 Succeeded / 0 Failed
Completed Indexes: 0-5
Pod Template:
Labels: batch.kubernetes.io/controller-uid=f5f72ef9-8078-42d5-a1d1-6b3b478e3a9f
batch.kubernetes.io/job-name=pi
controller-uid=f5f72ef9-8078-42d5-a1d1-6b3b478e3a9f
job-name=pi
Containers:
pi:
Image: perl:5.34.0
Port: <none>
Host Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 34s job-controller Created pod: pi-0-snpd2
Normal SuccessfulCreate 34s job-controller Created pod: pi-1-mxb2c
Normal SuccessfulCreate 24s job-controller Created pod: pi-2-zgmc5
Normal SuccessfulCreate 24s job-controller Created pod: pi-3-qnpls
Normal SuccessfulCreate 13s job-controller Created pod: pi-4-dwxzf
Normal SuccessfulCreate 13s job-controller Created pod: pi-5-vzrh2
Normal Completed 1s job-controller Job completed
cronjob
CronJob 创建基于时隔重复调度的 Job。
CronJob 用于执行排期操作,例如备份、生成报告等。 一个 CronJob 对象就像 Unix 系统上的 crontab(cron table)文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。
cronjob 的常用于:
- 日志备份
- 定期生成服务的可用性报告
- 定时清理平台上不使用的资源
CronJob 有所限制,也比较特殊。 例如在某些情况下,单个 CronJob 可以创建多个并发任务。 请参阅下面的限制。
当控制平面为 CronJob 创建新的 Job 和(间接)Pod 时,CronJob 的 .metadata.name 是命名这些 Pod 的部分基础。 CronJob 的名称必须是一个合法的 DNS 子域值, 但这会对 Pod 的主机名产生意外的结果。为获得最佳兼容性,名称应遵循更严格的 DNS 标签规则。 即使名称是一个 DNS 子域,它也不能超过 52 个字符。这是因为 CronJob 控制器将自动在你所提供的 Job 名称后附加 11 个字符,并且存在 Job 名称的最大长度不能超过 63 个字符的限制。
[root@control ~]# vim cronjob.yml
[root@control ~]# kubectl apply -f cronjob.yml
cronjob.batch/hello created
[root@control ~]# kubectl descibe cronjob hello
error: unknown command "descibe" for "kubectl"
Did you mean this?
describe
[root@control ~]# kubectl describe cronjob hello
Name: hello
Namespace: default
Labels: <none>
Annotations: <none>
Schedule: * * * * *
Concurrency Policy: Allow
Suspend: False
Successful Job History Limit: 3
Failed Job History Limit: 1
Starting Deadline Seconds: <unset>
Selector: <unset>
Parallelism: <unset>
Completions: <unset>
Pod Template:
Labels: <none>
Containers:
hello:
Image: busybox:latest
Port: <none>
Host Port: <none>
Command:
/bin/sh
-c
date; echo Hello from the Kubernetes cluster
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Last Schedule Time: Thu, 26 Sep 2024 11:05:00 +0800
Active Jobs: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 10s cronjob-controller Created job hello-28788665
Normal SawCompletedJob 7s cronjob-controller Saw completed job: hello-28788665, condition: Complete
[root@control ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-28788665-tgvx5 0/1 Completed 0 105s
hello-28788666-9t2c2 0/1 Completed 0 45s
my-nginx-7549dd6888-lhnr6 1/1 Running 4 (168m ago) 5d17h
my-nginx-7549dd6888-z84x4 1/1 Running 4 (168m ago) 5d17h
nginx-deployment-7f588fbd68-4lrb5 1/1 Running 2 (168m ago) 41h
nginx-deployment-7f588fbd68-8jnm5 1/1 Running 2 (168m ago) 41h
nginx-deployment-7f588fbd68-mvgzg 1/1 Running 2 (168m ago) 41h
web-0 1/1 Running 2 (168m ago) 41h
web-1 1/1 Running 2 (168m ago) 41h
[root@control ~]# kubectl get job // cronjob 创建的job,再由job进行pod启动执行
NAME STATUS COMPLETIONS DURATION AGE
hello-28788665 Complete 1/1 3s 110s
hello-28788666 Complete 1/1 3s 50s
// 根据策略,cronjob将只保存最近三次执行成功和一次执行失败的job记录,较早记录会被移除。
自动扩容:
- 水平扩容,增加pod副本数量, K8S 直接支持水平扩容
- HPA 自动扩容策略,监控pod资源使用率,在使用达到限制阈值时,根据算法计算的期望副本数,进行pod副本数量的调整。
- 垂直扩容, 放宽pod的资源使用,