Pod控制器由master的控制器管理器(kube-controller-manager)组件提供,pod控制器的主要作用是对pod资源进行创建、修改、删除等操作。常见的pod控制器由Replication Controller、ReplicaSet、Deployment、DaemonSet、StatefulSet、Job和CronJob。
1、pod控制器与pod对象
(1)pod控制器
Pod控制器资源通过持续地监控集群中运行着的pod资源对象来确保受其管控的资源严格符合用户期望的状态。一个pod控制器至少由标签选择器、期望的副本数量、pod模板三部分组成。
(2)pod控制器资源的定义
Pod控制器资源定义同pod资源的定义相同,也是通过apiVersion、kind、metadata、spec、status等五个字段及子字段组成,status为当前状态不需要再资源配置清单中定义。Spec字段通常要内嵌replicas、selector、template字段;而template为pod模板的定义,该字段主要定义pod资源需要定义的metadata字段和spec字段,用法与自助式pod资源的定义相同。
2、ReplicaSet控制器
ReplicaSet控制器主要用于确保其管控的pod对象副本数在任一时刻都能精确满足期望的数量。
(1)ReplicaSet控制器的主要功能
1)确保Pod资源对象的数量精确反应期望值
2)确保pod健康运行
3)弹性伸缩
(2)ReplicaSet的资源定义清单
ReplicaSet控制器资源的定义与pod资源定义类似,其spec字段嵌套的子字段及作用如下:
replicas:期望pod副本的数量
selector:当前控制器匹配Pod对象副本的标签选择器,支持matchLabels和matchExpressions两种匹配机制
template:用于补充pod副本数量时使用的pod模板资源
minReadySeconds:新建的pod对象,在启动后的多长时间内如果其容器未发生奔溃等异常情况则视为就绪。默认0
# replicaset类型pod控制器资源定义清单
[root@master01 test02]# cat test01.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: test-replicaset
spec:
replicas: 2
selector:
matchLabels:
app: test-rep
template:
metadata:
labels:
app: test-rep
spec:
containers:
- name: repset-test
image: nginx:1.12
ports:
- name: http
containerPort: 80
# 创建replicaset控制器
[root@master01 test02]# kubectl apply -f test01.yaml
replicaset.apps/test-replicaset created
# 查看创建的控制器的状态
[root@master01 test02]# kubectl get replicaset test-replicaset
NAME DESIRED CURRENT READY AGE
test-replicaset 2 2 2 3m16s
(3)replicaset对pod的管理
任何原因导致的pod副本缺失时都会有ReplicaSet控制器自动补充,多余的则会被ReplicaSet控制器删除。Pod资源的变动时间可通过“kubectl describe replicasets”命令查看。
# 查看replicaset控制器的状态
[root@master01 test02]# kubectl describe replicasets test-replicaset
Name: test-replicaset
Namespace: default
. . . . . .
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 8m36s replicaset-controller Created pod: test-replicaset-gj5xx
Normal SuccessfulCreate 8m36s replicaset-controller Created pod: test-replicaset-25cpv
(4)更新replicaset控制器
replicaSet控制器的核心组成部分是标签选择器,副本数量及Pod模板,但更新操作一般是围绕replicas和template两个字段值进行的。
1)更改pod模板、升级应用
Replicaset控制器的模板可以随时按需修改,但修改只会影响之后由其创建的pod对象。更新时我们先修改配置文件,然后可以一次性删除控制器相关的所有的pod副本及相关的标签或者分批删除旧的副本或更改其标签。
# 为了使更新效果明显,将配置中的nginx更改为httpd
[root@master01 test02]# cat test01.yaml
. . . . . .
containers:
- name: repset-test
image: httpd:latest
. . . . . .
# 对清单配置文件执行”kubectl apply”或”kubectl replace”完成控制器资源的修改操作
[root@master01 test02]# kubectl replace -f test01.yaml
# 删除该控制器下的所有pod副本
[root@master01 test02]# kubectl delete pods -l app=test-rep
# 再次查看时已经更新完成
[root@master01 test02]# kubectl get pods -l app=test-rep -w
NAME READY STATUS RESTARTS AGE
test-replicaset-6w977 1/1 Running 0 119s
test-replicaset-lw99r 1/1 Running 0 119s
2)replicaSet控制器的扩容与缩容
replicaSet控制器对pod数量的增加与缩减都可以通过修改资源的定义文件或者命令实现。通过修改定义文件的扩缩容都是实时的。
# 修改资源定义文件,将pod数量扩至5个
[root@master01 test02]# sed -i "s#replicas: 2#replicas: 5#g" test01.yaml
# 让配置清单生效
[root@master01 test02]# kubectl replace -f test01.yaml
# 查看状态
[root@master01 test02]# kubectl get replicaset test-replicaset
NAME DESIRED CURRENT READY AGE
test-replicaset 5 5 5 53m
# 通过命令将pod的数量缩减至3个
[root@master01 test02]# kubectl scale replicasets test-replicaset --replicas=3
replicaset.extensions/test-replicaset scaled
# 查看缩减后的pod
[root@master01 test02]# kubectl get pods -l app=test-rep
NAME READY STATUS RESTARTS AGE
test-replicaset-6w977 1/1 Running 0 17m
test-replicaset-lw99r 1/1 Running 0 17m
test-replicaset-x865r 1/1 Running 0 9m2s
“kubectl scale”命令还支持通过参数”—current-replicas”在现有pod副本数量符合指定的值时才执行扩展操作。
# 当pod数量为2个时扩展为6个,因为pod数量部位两个所以报错
[root@master01 test02]# kubectl scale replicasets test-replicaset --current-replicas=2 --replicas=6
error: Expected replicas to be 2, was 3
# 当pod数量为3个时扩展为6个,
[root@master01 test02]# kubectl scale replicasets test-replicaset --current-replicas=3 --replicas=6
replicaset.extensions/test-replicaset scaled
(5)删除replicaSet控制器资源
使用”kubectl delete”命令删除replicaset对象时默认会一并删除其管控的个pod对象,有时,这些pod资源可能不是该replicaset控制器创建的,此时可以使用”—cascade=false”选项,取消级联,删除相关的pod对象。
# 删除名称为test-replicaset的replicaset控制器并取消与pod的级联
[root@master01 test02]# kubectl delete replicasets test-replicaset --cascade=false
replicaset.extensions "test-replicaset" deleted
# 删除控制器后查看pod
[root@master01 test02]# kubectl get pods -l app=test-rep
NAME READY STATUS RESTARTS AGE
test-replicaset-2kqw8 1/1 Running 0 2m54s
test-replicaset-6w977 1/1 Running 0 63m
test-replicaset-lw99r 1/1 Running 0 63m
test-replicaset-rmq4t 1/1 Running 0 2m54s
test-replicaset-rsxxb 1/1 Running 0 2m54s
test-replicaset-x865r 1/1 Running 0 54m
3、Deployment控制器
Deployment控制器是构建与ReplicaSet控制器之上,可为Pod和ReplicaSet资源提供声明式更新的一种控制器;Deployment控制器的主要作用还是为了Pod资源的健康运行,但大部分功能可通过调用ReplicaSet控制器来实现,同时还添加了事件和状态查看、回滚、版本记录、暂停和启动、多种自动更新方案等特性。
(1)创建Deployment控制器
Deployment控制器资源清单定义与replicaset控制器资源定义的方式基本相同。
# 定义deployment控制器的配置清单
[root@master01 test02]# cat test02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test
spec:
replicas: 2
selector:
matchLabels:
app: test-deploy
template:
metadata:
labels:
app: test-deploy
spec:
containers:
- name: test-deploy
image: nginx:1.12
ports:
- name: http
containerPort: 80
# 创建deployment
[root@master01 test02]# kubectl apply -f test02.yaml
# 查看创建的deployment控制器
[root@master01 test02]# kubectl get deployments deployment-test
NAME READY UP-TO-DATE AVAILABLE AGE
deployment-test 2/2 2 2 2m50s
deployment控制器创建完成后,该控制器会自动创建相关的replicaset控制器,并以deployment控制器名称加hash值命名。
# 查看有replicaset控制器创建的deployment控制器
[root@master01 test02]# kubectl get replicasets -l app=test-deploy
NAME DESIRED CURRENT READY AGE
deployment-test-65b8b4f5b8 2 2 2 6m18s
(2)Deployment控制器的更新策略
相对于replicaset控制器,deployment控制器的更新只需要用于指定在Pod模板中需要修改的内容,剩下的步骤则由其自动完成。
Deployment控制器也支持两种更新策略,重新创建和滚动更新,默认更新策略为滚动更新。
1)重新创建(recreate):重新创建是先删除现有的pod对象,然后由控制器基于新模板重新创建出新版本的资源对象。
2)滚动更新(rolling update):在删除一部分旧版本pod的同时。补充新建一部分新版本pod对象;使更新的过程中业务不中断,但要求应用程序能够支持新旧版本同时工作的情形。
滚动更新时,应用升级期间还要确保可用的pod对象数量不低于阈值以确保应用能够正常处理请求,变动的方式和pod对象的数量通过spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable两个字段协同定义,他们的值都可以是一个期望值的百分比,他们的作用如下:
1)maxSurge:指定升级期间存在的pod对象数量最多可超出期望值的个数。
2)maxUnavilable:指定升级期间正常可用的pod副本数量最多不能低于期望值的个数。
更新时,还可以使用deployment.spec.minReadySecondsz字段控制应用升级的速度,该字段能够定义在新的pod对象创建后至少需要等多久才能将其视为就绪,再次期间,更新操作将会被阻塞。
Deployment也支持用户保留其滚动更新历史中的旧ReplicaSet对象版本;可保存的历史版本数量由spec.revisionHistoryLimit属性定义;而只有保存在revision历史中的ReplicaSet版本可用于回滚。为了保存历史版本可在创建deployment对象时使用”--record”选项。
(3)升级deployment
由于deployment控制的资源定义是声明式的配置,因此修改配置更适合使用”apply”和”patch”命令进行;如果只是修改容器镜像,则使用”set image”命令更适合。
# 通过打补丁的方式设置更新速度为10s,更新时的pod数量最多只能比定义的数量多1个,最少只能比定义的数量少一个。
[root@master01 ~]# kubectl patch deployments deployment-test -p '{"spec":{"minReadySeconds":10,"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1}}}}'
deployment.extensions/deployment-test patched
# 更换镜像
[root@master01 test02]# kubectl set image deployments deployment-test test-deploy=httpd
deployment.extensions/deployment-test image updated
# 更新pod的数量为5个
[root@master01 test02]# kubectl patch deployments deployment-test -p '{"spec":{"replicas":5}}'
deployment.extensions/deployment-test patched
# 监控更新过程
[root@master01 test02]# kubectl get deployments deployment-test --watch
NAME READY UP-TO-DATE AVAILABLE AGE
deployment-test 5/5 5 5 19h
(4)金丝雀发布
Deployment控制器还支持自定义控制更新过程中的滚动节奏,如“暂停”或“继续”等更新操作。
金丝雀发布是在更新的过程,第一批新的pod资源更新完成后立即暂停更新过程,然后帅选出小部分的请求路由至新版本的pod中,并观察新版本的pod是否稳定并按预期的方式运行,待观察没问题后继续完成余下pod资源的滚动更新;有问题则立刻回滚更新操作。
# 设置maxSurge为1,设置maxUnavailable为0
[root@master01 test02]# kubectl patch deployments deployment-test -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
deployment.extensions/deployment-test patched
# 更改pod中容器镜像,在第一批新版本pod对象创建完成后转为暂停
[root@master01 test02]# kubectl set image deployments deployment-test test-deploy=tomcat && kubectl rollout pause deployments deployment-test
deployment.extensions/deployment-test paused
# 查看跟新过程中的状态信息
[root@master01 test02]# kubectl rollout status deployments deployment-test
Waiting for deployment "deployment-test" rollout to finish: 2 out of 5 new replicas have been updated...
# 继续之前的更新过程
[root@master01 ~]# kubectl rollout resume deployments deployment-test
deployment.extensions/deployment-test resumed
(5)回滚deployment控制器应用的发布
在更新的过程中,如果更新失败或更新无法继续进行时,需要将应用回滚到之前的版本或指定的历史记录中的版本。
# 将更新回滚到上一个版本
[root@master01 ~]# kubectl rollout undo deployments deployment-test
deployment.extensions/deployment-test rolled back
# 查看历史版本
[root@master01 ~]# kubectl rollout history deployments deployment-test
deployment.extensions/deployment-test
REVISION CHANGE-CAUSE
1 <none>
3 <none>
4 <none>
# 回滚到指定的历史版本
[root@master01 ~]# kubectl rollout undo deployments deployment-test --to-revision=3
deployment.extensions/deployment-test rolled back
在回滚的过程中,如果此前的滚动更新状态处于“暂停”状态,那么回滚操作就需要先将pod模板的版本改回到之前的版本,然后继续更新,否则,一直将处于“暂停”状态无法回滚。
4、Daemonset控制器
Daemonset控制器用于在集群中的全部节点上同时运行一份指定的pod资源的副本,后续加入集群的节点也会自动创建该pod副本;管理员可以使用节点选择器及节点标签在指定的节点上运行指定的pod对象。Daemonset控制器通常用于运行执行系统及操作任务的应用。
(1)定义DaemonSet控制器
DaemonSet控制器的资源定义方法同前面两种控制器的定义方法相同,但不支持replicas字段。
# 定义daemonset控制器资源配置文件
[root@master01 test02]# cat test03.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: test-daemonset
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
name: filebeat
labels:
app: filebeat
spec:
containers:
- name: filebeat
image: fluent/fluentd:v1.3
# 创建daemonset控制器
[root@master01 test02]# kubectl apply -f test03.yaml
daemonset.apps/test-daemonset created
# 查看daemonset控制器的运行状态
[root@master01 test02]# kubectl get daemonsets
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
test-daemonset 2 2 2 2 2 <none> 3m36s
(2)daemonset更新
Daemonset控制器也支持滚动更新(RollingUpdata)和删除时更新(OnDelete)两种更新策略,默认为滚动更新;同时也支持使用maxUnavilabe属性设置最大不可用pod资源数,也可使用minReadySeconds字段控制更新节奏。删除更新是删除相应节点pod后重建并更新为新版本,滚动更新策略是一次删除一个工作节点上的pod资源,待其新版本pod资源重建完成后再开始操作另外一个节点的pod资源。
# 更新镜像
[root@master01 test02]# kubectl set image daemonsets test-daemonset filebeat=fluent/fluentd
daemonset.extensions/test-daemonset image updated
5、job控制器
Job控制器用于调配pod对象运行一次性任务,容器中的进程在正常运行结束后不会对其进行重启操作,而是将pod对象置于“Completed”状态。
Job控制器的对象有两种分别是单工作队列的串行job和多工作队列的并行式job。
(1)定义创建job控制器
Job控制器spec字段内嵌的必要字段仅为templte;并且job控制器属于API群组”batch/v1”内。
# 定义一个job
[root@master01 test02]# cat test04.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
template:
spec:
containers:
- name: test-job
image: alpine
command: ["/bin/sh","-c","sleep 120"]
restartPolicy: Never
# 创建job控制器
[root@master01 test02]# kubectl apply -f test04.yaml
job.batch/test-job created
# 查看job控制器
[root@master01 test02]# kubectl get job test-job
NAME COMPLETIONS DURATION AGE
test-job 0/1 11s 11s
(2)并行式job
将job.spec.parallelism字段属性值设置为1,并设置任务数字段” job.spec.completions”属性值,便能够让pod控制器以串行方式运行多任务;如果设置job.spec.parallelism属性值大于等于2,且job.spec.completions的属性值为1,则为并行任务,job.spec.completions的属性值大于等于2则为串行多任务。
# 定义一个串行多任务的job控制器
[root@master01 test02]# cat test05.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: test-job2
spec:
parallelism: 3
completions: 5
template:
spec:
containers:
- name: test-job2
image: alpine
command: ["/bin/sh","-c","sleep 120"]
restartPolicy: Never
(3)job控制器扩容
Job控制器的job.spec.parallelism字段属性值表示同时运行的pod的对象数,此属性值支持运行时调整来改变运行的pod数量,实现扩容和缩容。
# 对job控制器控制的pod进行缩容
[root@master01 test02]# kubectl scale jobs test-job2 --replicas=1
kubectl scale job is DEPRECATED and will be removed in a future version.
job.batch/test-job2 scaled
(4)删除job
Job控制器控制的pod运行结束后,用户可根据自己需求删除或保留;如果,某些控制器的应用无法正常结束运行,restartPolicy又定义为重启(值为OnFailure或者Always)。对此job控制器提供了两个属性用于抑制这种情况发生:
job.spec.activeDeadlineSeconds:用于为其指定最大活动时间的长度,超出将被终止
job.spec.backoffLimit:将作业标记为失败状态之前的重试次数,默认为6
6、CronJob控制器
CronJob控制器用于管理Job控制器资源的运行时间,CronJob控制器可以控制pod周期性的执行一些任务,有点类似于linux定时任务。
创建CronJob控制器时spec字段可嵌套的主要字段有:
1)jobTemplate:必选字段;Job控制器模板,用于为CronJob控制器生成Job对象。
2)schedule:必选字段,为cron格式的作业调度运行的时间点。
3)concurrencyPolicy:并发执行策略,定义前一次作业运行未完成时是否以及如何运行后一次作业,值有”Allow”和”Forbid”。
4)failedJobHistoryLimit:为失败的任务执行保留的历史记录数
5)successfulJobHistoryLimit:为成功的任务执行保留的历史记录数。
6)startingDeadlineSeconds:因各种原因缺乏执行作业的时间点所导致的启动作业错误的超长时间,会被记入错误的历史记录
7)suspend:是否挂起后续的任务执行,默认为false
# cronjob控制器资源定义
[root@master01 test02]# cat test06.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: test-cronjob
labels:
app: cronjob
spec:
schedule: "*/3 * * * *"
jobTemplate:
metadata:
labels:
app: cronjob-test
spec:
parallelism: 3
template:
spec:
containers:
- name: testcronjob
image: alpine
command:
- /bin/sh
- -c
- date; echo hello k8s; sleep 30
restartPolicy: OnFailure
# 创建crontab控制器并查看其运行状态
[root@master01 test02]# kubectl apply -f test06.yaml
cronjob.batch/test-cronjob created
[root@master01 test02]# kubectl get cronjobs test-cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
test-cronjob */3 * * * * False 0 <none> 18s
查看状态时各字段的含义如下:SCHEDULE为调度的时间点,SUSPEND代表后续任务是否处于挂起状态,ACTIVE表示活动状态的job对象的数量,LAST SCHEDULE表示上次调度运行至此刻的时长。
7、Pod中断预算
Pod中断预算(PBD)类型的资源用于为自愿的中断做好预算方案,限制可自愿中断的最大Pod副本数量或确保最少可用的Pod副本数,以确保服务的高可用。
自愿中断:由于用户特地执行的管理操作导致的pod中断
非自愿中断:由不可控外界因素导致的Pod中断退出的操作。
部署在在kubernetes的每个应用程序都可以创建一个对应的PDB对象以限制自愿中断时最大可以中断的副本数量或最少应该保持可用的副本数量,从而保证应用自身的高可用。支持PDB的pod控制器类型主要包括Deployment,ReplicaSet和statefulSet等。
定义PDB资源时,其spec字段主要嵌套的字段有:
1)Select:当前PDB对象使用的标签选择器,一般与相关的pod控制器使用同一个选择器。
2)minAvailabel:Pod自愿中断的场景中,至少要保证可用的Pod对象数量或比例。
3)maxUnavailable:Pod自愿中断场景中,最多可转化为不可用状态的pod对象数量或比例。
# 定义一个pdb资源对象,对deployment控制器test-deploy创建的pod对象设置中断预算。
[root@master01 test02]# cat test07.yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: test-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: test-deploy
# 创建并查看创建的pdb
[root@master01 test02]# kubectl apply -f test07.yaml
poddisruptionbudget.policy/test-pdb created
[root@master01 test02]# kubectl get pdb
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
test-pdb 2 N/A 3 20s