Kubernetes学习笔记(三):部署托管的Pod -- 存活探针、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob
存活探针#
Kubernetes可以通过存活探针(liveness probe)检查容器是否存活。如果探测失败,Kubernetes将定期执行探针并重新启动容器。
官方文档请见:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
存活探针分为三种:
- exec:在容器内执行任意命令,并检查命令的退出状态码,为0则成功,否则失败。
- httpGet:执行http get请求,http code大于等于200并且小于400表示成功,否则失败。
- tcp:尝试与指定端口建立socket连接,建立成功则探测成功,否则失败。
exec探针#
从官网复制个yaml,但是要将image从k8s.gcr.io/busybox更改为busybox。
-> [[email protected]] [~] cat exec-liveness.yaml
apiVersion: v1
kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
运行然后30秒后查看
-> [[email protected]] [~] k create -f exec-liveness.yaml
pod/liveness-exec created
-> [[email protected]] [~] k describe po liveness-exec
.......
Liveness: exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3 ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/liveness-exec to kube1.vm Normal Pulling <invalid> kubelet, kube1.vm Pulling image "busybox" Normal Pulled <invalid> kubelet, kube1.vm Successfully pulled image "busybox" Normal Created <invalid> kubelet, kube1.vm Created container liveness Normal Started <invalid> kubelet, kube1.vm Started container liveness Warning Unhealthy <invalid> (x3 over <invalid>) kubelet, kube1.vm Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory Normal Killing <invalid> kubelet, kube1.vm Container liveness failed liveness probe, will be restarted
前30秒,/tmp/healthy是存在的,探针返回成功。30秒后,因为/tmp/healthy不存在了,所以一直失败,直到失败3次后重启。
livenessProbe下的字段#
这时候kubectl explain po.spec.containers.livenessProbe
就派上了用场。
- exec:exec探针配置
- httpGet:httpGet探针配置
- tcpSocket:tcpSocket探针配置
- initialDelaySeconds:初始延迟时间,在此时间内不进行探测,给程序预留启动时间。
- periodSeconds:探测周期,默认10s
- timeoutSeconds:超时时间,默认1s
- failureThreshold:被认为失活的最小连续失败次数,默认3次
- successThreshold:失败后被认为存活的最小连续成功次数,默认为1次。
这些参数在上面的kubectl describe
的结果中的Liveness字段有:
exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
注意事项#
- 一定要检查程序的内部,而没有外界因素影响。
例如,当服务器无法连接到数据库时,前端服务的探针不应返回失败。因为问题在数据库,重启前端服务也无法解决问题。 - 无须再探针中实现重试
- 探针要轻量
ReplicationController#
ReplicationController是一种Kubernetes资源,可以确保他的pod始终处于运行状态。
ReplicationController描述文件分为三大部分:
- label selector(标签选择器):用于确定ReplicationController管理哪些pod
- replica count(副本个数):指定运行pod的数量
- pod template(pod模板):用于创建pod
ReplicationController的目的就是创建和管理若干个pod副本,它会持续监控正在运行的pod列表,保证标签选择器匹配的pod数量与副本个数一致。如果少于副本数量,就要根据pod模板创建新的副本;如果多余副本数量,就要删除多余的pod。
数量少的原因可能是:
- 增加了副本个数
- pod所在的工作节点出现故障
- pod的标签更改了,导致pod与ReplicationController的标签选择器不再匹配了。此时,如果它不被任何ReplicationController的标签选择器匹配,它就称为一个孤儿了。
数量多的原因可能是:
- 减少了副本个数
- 新建的pod与该ReplicationController的标签选择器匹配
- 已存在的pod标签修改后与该ReplicationController的标签选择器匹配
nginx-rc.yaml#
API服务器会检查模板中的标签是否与selector匹配,如果不匹配是无法创建的。可以不指定selector,它会根据模板中的labels自动配置。
apiVersion: v1
kind: ReplicationController
metadata: name: nginx-rc spec: replicas: 3 # 副本数量 selector: # pod选择器,决定RC的操作对象 app: nginx template: # pod模板 metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
使用ReplicationController#
创建ReplicationController
-> [[email protected]] [~] k create -f nginx-rc.yaml replicationcontroller/nginx-rc created
查看pod,确实新建了3个pod。
-> [[email protected]] [~] k get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-rc-2c47w 0/1 ContainerCreating 0 5s app=nginx nginx-rc-jrcl2 0/1 ContainerCreating 0 5s app=nginx nginx-rc-qgchh 0/1 ContainerCreating 0 5s app=nginx
查看ReplicationController,rc是ReplicationController的简写。
-> [[email protected]] [~] k get rc NAME DESIRED CURRENT READY AGE nginx-rc 3 3 3 5m58s
查看详情
-> [[email protected]] [~] k describe rc nginx-rc
Name: nginx-rc
Namespace: default Selector: app=nginx Labels: app=nginx Annotations: <none> Replicas: 3 current / 3 desired # 当前数量、期望数量 Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed # 各种状态下的数量 Pod Template: Labels: app=nginx Containers: nginx: Image: nginx Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-2c47w Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-jrcl2 Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-qgchh
可以搞一些破坏,比如更改、删除pod的标签,或者干脆删除pod。ReplicationController会因为当前数量与期望数量不符而创建新的副本。
控制器如何创建的pod#
控制器通过创建一个新的副本代替被删除的副本时,它并没有对删除本身做出反应,而是针对由此产生的状态——副本数量不足做出反应。
虽然控制器会立即受到pod被删除的通知,但这并不是它创建新副本的原因。该通知会触发控制器检查实际的副本数量并采取相应措施。
kubectl edit#
kubectl edit rc nginx-rc
可以在编辑器中打开nginx-rc的yaml配置,修改在保存后会立刻做出改变。
-> [[email protected]] [~] k edit rc nginx-rc replicationcontroller/nginx-rc edited 通过KUBE_EDITOR环境变量可以指定用什么编辑器打开。
kubectl scale#
可以使用kubectl scale
命令进行扩缩容。
-> [[email protected]] [~] k scale rc nginx-rc --replicas=6
replicationcontroller/nginx-rc scaled
以上操作会修改spec.replicas
字段,就像通过kubectl edit
修改一样。
删除ReplicationController#
使用 kubectl delete 删除ReplicationController时,pod也会被删除。但由于pod是被ReplicationController创建的而不是它的组成部分,所以可以通过指定--cascade=false
而不删除pod。
注意事项#
- pod永远不会被重新安置到另一个节点。
- 虽然一个pod没有绑定在ReplicationController上,但该pod在
metadata.ownerReferences
引用它。
ReplicaSet#
ReplicationController最终将要被弃用,代替它的是ReplicaSet。它们的行为完全相同,但是ReplicaSet的选择器更具有表达力。
nginx-rs.yaml#
让我们来看一个ReplicaSet的描述文件:
apiVersion: apps/v1 # api版本与ReplicationController不同
kind: ReplicaSet metadata: name: nginx-rs spec: replicas: 3 selector: # ReplicaSet的pod选择器有matchLabels和matchExpressions,与ReplicationController的是相似的,但更强大 matchLabels: app: nginx template: # 模板内容是一致的 metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
主要区别在于pod选择器。ReplicaSet的创建于ReplicationController一样,缩写是rs,就不再赘叙了。
matchExpressions#
上面描述文件的选择器使用matchExpressions可以改为:
selector:
matchExpressions:
- key: app
operator: In
values: - nginx
每个表达式都必须包含key、operator(运算符),有可能包含values(取决于运算符),运算符有以下四种:
- In:Label的值必须与values中的一个相等
- NotIn:Label的值不能与values中的任何一个相等
- Exists:Pod必须包含一个指定名称的标签,values无所谓
- DoesNotExists:Pod不得包含指定名称的标签,values不能指定
DaemonSet#
DaemonSet与ReplicaSet的不同在于,DaemonSet可以让pod在集群的每个节点上运行,有且只有一个。
如果节点下线,DaemonSet不会在其他地方重建pod;如果集群新加入了一个节点,DaemonSet会立刻部署一个新的pod。如果有人删除了pod,DaemonSet会建立一个新的。
这些pod通常用于执行系统级别或基础结构相关的工作,如日志收集和资源监控。典型的例子就是Kubernetes自己的kube-proxy。
如果想让DaemonSet只在特定节点运行pod,需要通过pod模板中的nodeSelector属性指定。
DaemonSet中没有期望副本数的概念,它不需要。因为它的工作是确保有一个匹配它选择器的pod在节点上运行。
nginx-ds.yaml#
可能这里用继续用nginx作为例子不太恰当,但目前我们关注的重点是DaemonSet,继续吧。。。
apiVersion: apps/v1
kind: DaemonSet
metadata: name: nginx-ds spec: # 去掉了replicas,因为不需要 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: nodeSelector: # 添加了一个节点的标签选择器,选择只部署地区在在北京的节点上 region: "beijing" containers: - name: nginx image: nginx ports: - containerPort: 80
创建DaemonSet#
先给kube1.vm打个标签
-> [[email protected]] [~] k label node kube1.vm region=beijing
node/kube1.vm labeled
-> [[email protected]] [~] k get node -L region
NAME STATUS ROLES AGE VERSION REGION
kube0.vm Ready master 40h v1.17.3 kube1.vm Ready <none> 40h v1.17.3 beijing kube2.vm Ready <none> 40h v1.17.3
提交描述文件
-> [[email protected]] [~] k create -f nginx-ds.yaml
daemonset.apps/nginx-ds created
-> [[email protected]] [~] k get ds,po -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/nginx-ds 1 1 1 1 1 region=beijing 52s nginx nginx app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-ds-5z95c 1/1 Running 0 52s 10.244.1.24 kube1.vm <none> <none>
给kube2.vm也打个标签
-> [[email protected]] [~] k label node kube2.vm region=beijing
node/kube2.vm labeled
-> [[email protected]] [~] k get ds,po -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR daemonset.apps/nginx-ds 2 2 1 2 1 region=beijing 113s nginx nginx app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-ds-5z95c 1/1 Running 0 113s 10.244.1.24 kube1.vm <none> <none> pod/nginx-ds-b46lb 0/1 ContainerCreating 0 3s <none> kube2.vm <none> <none>
Job#
Job可以运行一种pod,在该pod内的进程成功结束时,不再重启。一旦任务完成,pod就被认为处于完成状态。
比如可以使用在将一些数据导出到其他地方,这个工作可能会持续几个小时。
我们基于busybox镜像,sleep一段时间用于模拟这个操作。
job.yaml#
apiVersion: batch/v1
kind: Job
metadata:
name: job
spec: template: # 没有指定selector,会根据pod标签中自动创建 metadata: labels: app: job spec: restartPolicy: OnFailure # 执行遇到异常则重启,默认为Always。 containers: - name: sleepbusybox image: busybox command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
restartPolicy表示pod的重启策略,默认Always,其他两项为OnFailure和Never。
运行查看#
创建job
-> [[email protected]] [~] k create -f job.yaml job.batch/job created
60秒内查看:
-> [[email protected]] [~] k get job,pod
NAME COMPLETIONS DURATION AGE
job.batch/job 0/1 14s 14s
NAME READY STATUS RESTARTS AGE
pod/job-4sfv4 1/1 Running 0 14s
60秒后查看:
-> [[email protected]] [~] k get job,pod
NAME COMPLETIONS DURATION AGE
job.batch/job 1/1 68s 71s
NAME READY STATUS RESTARTS AGE
pod/job-4sfv4 0/1 Completed 0 71s
使用jsonpath获取 pod name 查看log
-> [root@kube0.vm] [~] k logs $(k get po --selector=app=job --output=jsonpath={.items..metadata.name})
this is busybox
completions与parallelism#
job描述文件下的spec有两个字段:
- completions:job要确保完成多少个pod,默认为1。
- parallelism:最多并行运行多少个pod,默认为1。
job-batch.yaml
apiVersion: batch/v1
kind: Job
metadata: name: job-batch spec: completions: 5 parallelism: 2 template: # 与job.yaml相同
activeDeadlineSeconds#
job.spec.activeDeadlineSeconds
属性来限制Job在集群中的存活时间,超过此值,所有的pod都被终止。Job的status变为 type: Failed
,reason: DeadlineExceeded
CronJob#
与Linux的crontab类似,使pod可以在特定时间运行,或者周期运行。
cronjob.yaml#
这个描述文件是个套娃。。
CronJob包含job的模板,也就是jobTemplate;job里还包含pod的模板,也就是template。
schedule字段中的值是"分 小时 每月第几天 月份 星期几",详情请参考Linux crontab。
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job
spec: schedule: "*/3 * * * * " # 每三分钟运行一次 jobTemplate: # job的模板 spec: template: # pod的模板 metadata: labels: app: job-in-cron spec: restartPolicy: OnFailure containers: - name: sleepbusybox image: busybox command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
运行#
创建cron-job
-> [[email protected]] [~] k create -f cronjob.yaml cronjob.batch/cron-job created
等了几分钟
-> [[email protected]] [~] k get all
NAME READY STATUS RESTARTS AGE
pod/cron-job-1590053040-pqhhh 0/1 Completed 0 97s NAME COMPLETIONS DURATION AGE job.batch/cron-job-1590053040 1/1 68s 97s NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/cron-job */3 * * * * False 0 105s 4m39s
又等了几分钟
-> [root@kube0.vm] [~] k get all
NAME READY STATUS RESTARTS AGE
pod/cron-job-1590053040-pqhhh 0/1 Completed 0 3m4s pod/cron-job-1590053220-whflp 0/1 ContainerCreating 0 3s NAME COMPLETIONS DURATION AGE job.batch/cron-job-1590053040 1/1 68s 3m4s job.batch/cron-job-1590053220 0/1 3s 3s NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/cron-job */3 * * * * False 1 12s 6m6s
可以看到就当前的描述文件而言,cron-job每次创建一个job,job创建一个pod的运行。
startingDeadlineSeconds#
cronjob.spec.startingDeadlineSeconds
规定pod必须预定时间之后的startingDeadlineSeconds秒内运行,超过此时间则不运行,并将其显示未Failed。
存活探针#
Kubernetes可以通过存活探针(liveness probe)检查容器是否存活。如果探测失败,Kubernetes将定期执行探针并重新启动容器。
官方文档请见:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
存活探针分为三种:
- exec:在容器内执行任意命令,并检查命令的退出状态码,为0则成功,否则失败。
- httpGet:执行http get请求,http code大于等于200并且小于400表示成功,否则失败。
- tcp:尝试与指定端口建立socket连接,建立成功则探测成功,否则失败。
exec探针#
从官网复制个yaml,但是要将image从k8s.gcr.io/busybox更改为busybox。
-> [[email protected]] [~] cat exec-liveness.yaml
apiVersion: v1
kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
运行然后30秒后查看
-> [[email protected]] [~] k create -f exec-liveness.yaml
pod/liveness-exec created
-> [[email protected]] [~] k describe po liveness-exec
.......
Liveness: exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3 ....... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/liveness-exec to kube1.vm Normal Pulling <invalid> kubelet, kube1.vm Pulling image "busybox" Normal Pulled <invalid> kubelet, kube1.vm Successfully pulled image "busybox" Normal Created <invalid> kubelet, kube1.vm Created container liveness Normal Started <invalid> kubelet, kube1.vm Started container liveness Warning Unhealthy <invalid> (x3 over <invalid>) kubelet, kube1.vm Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory Normal Killing <invalid> kubelet, kube1.vm Container liveness failed liveness probe, will be restarted
前30秒,/tmp/healthy是存在的,探针返回成功。30秒后,因为/tmp/healthy不存在了,所以一直失败,直到失败3次后重启。
livenessProbe下的字段#
这时候kubectl explain po.spec.containers.livenessProbe
就派上了用场。
- exec:exec探针配置
- httpGet:httpGet探针配置
- tcpSocket:tcpSocket探针配置
- initialDelaySeconds:初始延迟时间,在此时间内不进行探测,给程序预留启动时间。
- periodSeconds:探测周期,默认10s
- timeoutSeconds:超时时间,默认1s
- failureThreshold:被认为失活的最小连续失败次数,默认3次
- successThreshold:失败后被认为存活的最小连续成功次数,默认为1次。
这些参数在上面的kubectl describe
的结果中的Liveness字段有:
exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
注意事项#
- 一定要检查程序的内部,而没有外界因素影响。
例如,当服务器无法连接到数据库时,前端服务的探针不应返回失败。因为问题在数据库,重启前端服务也无法解决问题。 - 无须再探针中实现重试
- 探针要轻量
ReplicationController#
ReplicationController是一种Kubernetes资源,可以确保他的pod始终处于运行状态。
ReplicationController描述文件分为三大部分:
- label selector(标签选择器):用于确定ReplicationController管理哪些pod
- replica count(副本个数):指定运行pod的数量
- pod template(pod模板):用于创建pod
ReplicationController的目的就是创建和管理若干个pod副本,它会持续监控正在运行的pod列表,保证标签选择器匹配的pod数量与副本个数一致。如果少于副本数量,就要根据pod模板创建新的副本;如果多余副本数量,就要删除多余的pod。
数量少的原因可能是:
- 增加了副本个数
- pod所在的工作节点出现故障
- pod的标签更改了,导致pod与ReplicationController的标签选择器不再匹配了。此时,如果它不被任何ReplicationController的标签选择器匹配,它就称为一个孤儿了。
数量多的原因可能是:
- 减少了副本个数
- 新建的pod与该ReplicationController的标签选择器匹配
- 已存在的pod标签修改后与该ReplicationController的标签选择器匹配
nginx-rc.yaml#
API服务器会检查模板中的标签是否与selector匹配,如果不匹配是无法创建的。可以不指定selector,它会根据模板中的labels自动配置。
apiVersion: v1
kind: ReplicationController
metadata: name: nginx-rc spec: replicas: 3 # 副本数量 selector: # pod选择器,决定RC的操作对象 app: nginx template: # pod模板 metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
使用ReplicationController#
创建ReplicationController
-> [[email protected]] [~] k create -f nginx-rc.yaml replicationcontroller/nginx-rc created
查看pod,确实新建了3个pod。
-> [[email protected]] [~] k get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-rc-2c47w 0/1 ContainerCreating 0 5s app=nginx nginx-rc-jrcl2 0/1 ContainerCreating 0 5s app=nginx nginx-rc-qgchh 0/1 ContainerCreating 0 5s app=nginx
查看ReplicationController,rc是ReplicationController的简写。
-> [[email protected]] [~] k get rc NAME DESIRED CURRENT READY AGE nginx-rc 3 3 3 5m58s
查看详情
-> [[email protected]] [~] k describe rc nginx-rc
Name: nginx-rc
Namespace: default Selector: app=nginx Labels: app=nginx Annotations: <none> Replicas: 3 current / 3 desired # 当前数量、期望数量 Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed # 各种状态下的数量 Pod Template: Labels: app=nginx Containers: nginx: Image: nginx Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-2c47w Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-jrcl2 Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-qgchh
可以搞一些破坏,比如更改、删除pod的标签,或者干脆删除pod。ReplicationController会因为当前数量与期望数量不符而创建新的副本。
控制器如何创建的pod#
控制器通过创建一个新的副本代替被删除的副本时,它并没有对删除本身做出反应,而是针对由此产生的状态——副本数量不足做出反应。
虽然控制器会立即受到pod被删除的通知,但这并不是它创建新副本的原因。该通知会触发控制器检查实际的副本数量并采取相应措施。
kubectl edit#
kubectl edit rc nginx-rc
可以在编辑器中打开nginx-rc的yaml配置,修改在保存后会立刻做出改变。
-> [[email protected]] [~] k edit rc nginx-rc replicationcontroller/nginx-rc edited 通过KUBE_EDITOR环境变量可以指定用什么编辑器打开。
kubectl scale#
可以使用kubectl scale
命令进行扩缩容。
-> [[email protected]] [~] k scale rc nginx-rc --replicas=6
replicationcontroller/nginx-rc scaled
以上操作会修改spec.replicas
字段,就像通过kubectl edit
修改一样。
删除ReplicationController#
使用 kubectl delete 删除ReplicationController时,pod也会被删除。但由于pod是被ReplicationController创建的而不是它的组成部分,所以可以通过指定--cascade=false
而不删除pod。
注意事项#
- pod永远不会被重新安置到另一个节点。
- 虽然一个pod没有绑定在ReplicationController上,但该pod在
metadata.ownerReferences
引用它。
ReplicaSet#
ReplicationController最终将要被弃用,代替它的是ReplicaSet。它们的行为完全相同,但是ReplicaSet的选择器更具有表达力。
nginx-rs.yaml#
让我们来看一个ReplicaSet的描述文件:
apiVersion: apps/v1 # api版本与ReplicationController不同
kind: ReplicaSet metadata: name: nginx-rs spec: replicas: 3 selector: # ReplicaSet的pod选择器有matchLabels和matchExpressions,与ReplicationController的是相似的,但更强大 matchLabels: app: nginx template: # 模板内容是一致的 metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
主要区别在于pod选择器。ReplicaSet的创建于ReplicationController一样,缩写是rs,就不再赘叙了。
matchExpressions#
上面描述文件的选择器使用matchExpressions可以改为:
selector:
matchExpressions:
- key: app
operator: In
values: - nginx
每个表达式都必须包含key、operator(运算符),有可能包含values(取决于运算符),运算符有以下四种:
- In:Label的值必须与values中的一个相等
- NotIn:Label的值不能与values中的任何一个相等
- Exists:Pod必须包含一个指定名称的标签,values无所谓
- DoesNotExists:Pod不得包含指定名称的标签,values不能指定
DaemonSet#
DaemonSet与ReplicaSet的不同在于,DaemonSet可以让pod在集群的每个节点上运行,有且只有一个。
如果节点下线,DaemonSet不会在其他地方重建pod;如果集群新加入了一个节点,DaemonSet会立刻部署一个新的pod。如果有人删除了pod,DaemonSet会建立一个新的。
这些pod通常用于执行系统级别或基础结构相关的工作,如日志收集和资源监控。典型的例子就是Kubernetes自己的kube-proxy。
如果想让DaemonSet只在特定节点运行pod,需要通过pod模板中的nodeSelector属性指定。
DaemonSet中没有期望副本数的概念,它不需要。因为它的工作是确保有一个匹配它选择器的pod在节点上运行。
nginx-ds.yaml#
可能这里用继续用nginx作为例子不太恰当,但目前我们关注的重点是DaemonSet,继续吧。。。
apiVersion: apps/v1
kind: DaemonSet
metadata: name: nginx-ds spec: # 去掉了replicas,因为不需要 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: nodeSelector: # 添加了一个节点的标签选择器,选择只部署地区在在北京的节点上 region: "beijing" containers: - name: nginx image: nginx ports: - containerPort: 80
创建DaemonSet#
先给kube1.vm打个标签
-> [[email protected]] [~] k label node kube1.vm region=beijing
node/kube1.vm labeled
-> [[email protected]] [~] k get node -L region
NAME STATUS ROLES AGE VERSION REGION
kube0.vm Ready master 40h v1.17.3 kube1.vm Ready <none> 40h v1.17.3 beijing kube2.vm Ready <none> 40h v1.17.3
提交描述文件
-> [[email protected]] [~] k create -f nginx-ds.yaml
daemonset.apps/nginx-ds created
-> [[email protected]] [~] k get ds,po -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/nginx-ds 1 1 1 1 1 region=beijing 52s nginx nginx app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-ds-5z95c 1/1 Running 0 52s 10.244.1.24 kube1.vm <none> <none>
给kube2.vm也打个标签
-> [[email protected]] [~] k label node kube2.vm region=beijing
node/kube2.vm labeled
-> [[email protected]] [~] k get ds,po -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR daemonset.apps/nginx-ds 2 2 1 2 1 region=beijing 113s nginx nginx app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-ds-5z95c 1/1 Running 0 113s 10.244.1.24 kube1.vm <none> <none> pod/nginx-ds-b46lb 0/1 ContainerCreating 0 3s <none> kube2.vm <none> <none>
Job#
Job可以运行一种pod,在该pod内的进程成功结束时,不再重启。一旦任务完成,pod就被认为处于完成状态。
比如可以使用在将一些数据导出到其他地方,这个工作可能会持续几个小时。
我们基于busybox镜像,sleep一段时间用于模拟这个操作。
job.yaml#
apiVersion: batch/v1
kind: Job
metadata:
name: job
spec: template: # 没有指定selector,会根据pod标签中自动创建 metadata: labels: app: job spec: restartPolicy: OnFailure # 执行遇到异常则重启,默认为Always。 containers: - name: sleepbusybox image: busybox command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
restartPolicy表示pod的重启策略,默认Always,其他两项为OnFailure和Never。
运行查看#
创建job
-> [[email protected]] [~] k create -f job.yaml job.batch/job created
60秒内查看:
-> [[email protected]] [~] k get job,pod
NAME COMPLETIONS DURATION AGE
job.batch/job 0/1 14s 14s
NAME READY STATUS RESTARTS AGE
pod/job-4sfv4 1/1 Running 0 14s
60秒后查看:
-> [[email protected]] [~] k get job,pod
NAME COMPLETIONS DURATION AGE
job.batch/job 1/1 68s 71s
NAME READY STATUS RESTARTS AGE
pod/job-4sfv4 0/1 Completed 0 71s
使用jsonpath获取 pod name 查看log
-> [root@kube0.vm] [~] k logs $(k get po --selector=app=job --output=jsonpath={.items..metadata.name})
this is busybox
completions与parallelism#
job描述文件下的spec有两个字段:
- completions:job要确保完成多少个pod,默认为1。
- parallelism:最多并行运行多少个pod,默认为1。
job-batch.yaml
apiVersion: batch/v1
kind: Job
metadata: name: job-batch spec: completions: 5 parallelism: 2 template: # 与job.yaml相同
activeDeadlineSeconds#
job.spec.activeDeadlineSeconds
属性来限制Job在集群中的存活时间,超过此值,所有的pod都被终止。Job的status变为 type: Failed
,reason: DeadlineExceeded
CronJob#
与Linux的crontab类似,使pod可以在特定时间运行,或者周期运行。
cronjob.yaml#
这个描述文件是个套娃。。
CronJob包含job的模板,也就是jobTemplate;job里还包含pod的模板,也就是template。
schedule字段中的值是"分 小时 每月第几天 月份 星期几",详情请参考Linux crontab。
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job
spec: schedule: "*/3 * * * * " # 每三分钟运行一次 jobTemplate: # job的模板 spec: template: # pod的模板 metadata: labels: app: job-in-cron spec: restartPolicy: OnFailure containers: - name: sleepbusybox image: busybox command: ["/bin/sh","-c","sleep 60;echo this is busybox"]
运行#
创建cron-job
-> [[email protected]] [~] k create -f cronjob.yaml cronjob.batch/cron-job created
等了几分钟
-> [[email protected]] [~] k get all
NAME READY STATUS RESTARTS AGE
pod/cron-job-1590053040-pqhhh 0/1 Completed 0 97s NAME COMPLETIONS DURATION AGE job.batch/cron-job-1590053040 1/1 68s 97s NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/cron-job */3 * * * * False 0 105s 4m39s
又等了几分钟
-> [root@kube0.vm] [~] k get all
NAME READY STATUS RESTARTS AGE
pod/cron-job-1590053040-pqhhh 0/1 Completed 0 3m4s pod/cron-job-1590053220-whflp 0/1 ContainerCreating 0 3s NAME COMPLETIONS DURATION AGE job.batch/cron-job-1590053040 1/1 68s 3m4s job.batch/cron-job-1590053220 0/1 3s 3s NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/cron-job */3 * * * * False 1 12s 6m6s
可以看到就当前的描述文件而言,cron-job每次创建一个job,job创建一个pod的运行。
startingDeadlineSeconds#
cronjob.spec.startingDeadlineSeconds
规定pod必须预定时间之后的startingDeadlineSeconds秒内运行,超过此时间则不运行,并将其显示未Failed。