存活探针

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。

  1. -> [root@kube0.vm] [~] cat exec-liveness.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. labels:
  6. test: liveness
  7. name: liveness-exec
  8. spec:
  9. containers:
  10. - name: liveness
  11. image: busybox
  12. args:
  13. - /bin/sh
  14. - -c
  15. - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
  16. livenessProbe:
  17. exec:
  18. command:
  19. - cat
  20. - /tmp/healthy
  21. initialDelaySeconds: 5
  22. periodSeconds: 5

运行然后30秒后查看

  1. -> [root@kube0.vm] [~] k create -f exec-liveness.yaml
  2. pod/liveness-exec created
  3. -> [root@kube0.vm] [~] k describe po liveness-exec
  4. .......
  5. Liveness: exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
  6. .......
  7. Events:
  8. Type Reason Age From Message
  9. ---- ------ ---- ---- -------
  10. Normal Scheduled <unknown> default-scheduler Successfully assigned default/liveness-exec to kube1.vm
  11. Normal Pulling <invalid> kubelet, kube1.vm Pulling image "busybox"
  12. Normal Pulled <invalid> kubelet, kube1.vm Successfully pulled image "busybox"
  13. Normal Created <invalid> kubelet, kube1.vm Created container liveness
  14. Normal Started <invalid> kubelet, kube1.vm Started container liveness
  15. Warning Unhealthy <invalid> (x3 over <invalid>) kubelet, kube1.vm Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  16. 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字段有:

  1. 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自动配置。

  1. apiVersion: v1
  2. kind: ReplicationController
  3. metadata:
  4. name: nginx-rc
  5. spec:
  6. replicas: 3 # 副本数量
  7. selector: # pod选择器,决定RC的操作对象
  8. app: nginx
  9. template: # pod模板
  10. metadata:
  11. labels:
  12. app: nginx
  13. spec:
  14. containers:
  15. - name: nginx
  16. image: nginx
  17. ports:
  18. - containerPort: 80

使用ReplicationController

创建ReplicationController

  1. -> [root@kube0.vm] [~] k create -f nginx-rc.yaml
  2. replicationcontroller/nginx-rc created

查看pod,确实新建了3个pod。

  1. -> [root@kube0.vm] [~] k get po --show-labels
  2. NAME READY STATUS RESTARTS AGE LABELS
  3. nginx-rc-2c47w 0/1 ContainerCreating 0 5s app=nginx
  4. nginx-rc-jrcl2 0/1 ContainerCreating 0 5s app=nginx
  5. nginx-rc-qgchh 0/1 ContainerCreating 0 5s app=nginx

查看ReplicationController,rc是ReplicationController的简写。

  1. -> [root@kube0.vm] [~] k get rc
  2. NAME DESIRED CURRENT READY AGE
  3. nginx-rc 3 3 3 5m58s

查看详情

  1. -> [root@kube0.vm] [~] k describe rc nginx-rc
  2. Name: nginx-rc
  3. Namespace: default
  4. Selector: app=nginx
  5. Labels: app=nginx
  6. Annotations: <none>
  7. Replicas: 3 current / 3 desired # 当前数量、期望数量
  8. Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed # 各种状态下的数量
  9. Pod Template:
  10. Labels: app=nginx
  11. Containers:
  12. nginx:
  13. Image: nginx
  14. Port: 80/TCP
  15. Host Port: 0/TCP
  16. Environment: <none>
  17. Mounts: <none>
  18. Volumes: <none>
  19. Events:
  20. Type Reason Age From Message
  21. ---- ------ ---- ---- -------
  22. Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-2c47w
  23. Normal SuccessfulCreate 7m26s replication-controller Created pod: nginx-rc-jrcl2
  24. 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配置,修改在保存后会立刻做出改变。

  1. -> [root@kube0.vm] [~] k edit rc nginx-rc
  2. replicationcontroller/nginx-rc edited
  3. 通过KUBE_EDITOR环境变量可以指定用什么编辑器打开。

kubectl scale

可以使用kubectl scale命令进行扩缩容。

  1. -> [root@kube0.vm] [~] k scale rc nginx-rc --replicas=6
  2. 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的描述文件:

  1. apiVersion: apps/v1 # api版本与ReplicationController不同
  2. kind: ReplicaSet
  3. metadata:
  4. name: nginx-rs
  5. spec:
  6. replicas: 3
  7. selector: # ReplicaSet的pod选择器有matchLabels和matchExpressions,与ReplicationController的是相似的,但更强大
  8. matchLabels:
  9. app: nginx
  10. template: # 模板内容是一致的
  11. metadata:
  12. labels:
  13. app: nginx
  14. spec:
  15. containers:
  16. - name: nginx
  17. image: nginx
  18. ports:
  19. - containerPort: 80

主要区别在于pod选择器。ReplicaSet的创建于ReplicationController一样,缩写是rs,就不再赘叙了。

matchExpressions

上面描述文件的选择器使用matchExpressions可以改为:

  1. selector:
  2. matchExpressions:
  3. - key: app
  4. operator: In
  5. values:
  6. - 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,继续吧。。。

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: nginx-ds
  5. spec: # 去掉了replicas,因为不需要
  6. selector:
  7. matchLabels:
  8. app: nginx
  9. template:
  10. metadata:
  11. labels:
  12. app: nginx
  13. spec:
  14. nodeSelector: # 添加了一个节点的标签选择器,选择只部署地区在在北京的节点上
  15. region: "beijing"
  16. containers:
  17. - name: nginx
  18. image: nginx
  19. ports:
  20. - containerPort: 80

创建DaemonSet

先给kube1.vm打个标签

  1. -> [root@kube0.vm] [~] k label node kube1.vm region=beijing
  2. node/kube1.vm labeled
  3. -> [root@kube0.vm] [~] k get node -L region
  4. NAME STATUS ROLES AGE VERSION REGION
  5. kube0.vm Ready master 40h v1.17.3
  6. kube1.vm Ready <none> 40h v1.17.3 beijing
  7. kube2.vm Ready <none> 40h v1.17.3

提交描述文件

  1. -> [root@kube0.vm] [~] k create -f nginx-ds.yaml
  2. daemonset.apps/nginx-ds created
  3. -> [root@kube0.vm] [~] k get ds,po -o wide
  4. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
  5. daemonset.apps/nginx-ds 1 1 1 1 1 region=beijing 52s nginx nginx app=nginx
  6. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  7. pod/nginx-ds-5z95c 1/1 Running 0 52s 10.244.1.24 kube1.vm <none> <none>

给kube2.vm也打个标签

  1. -> [root@kube0.vm] [~] k label node kube2.vm region=beijing
  2. node/kube2.vm labeled
  3. -> [root@kube0.vm] [~] k get ds,po -o wide
  4. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
  5. daemonset.apps/nginx-ds 2 2 1 2 1 region=beijing 113s nginx nginx app=nginx
  6. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  7. pod/nginx-ds-5z95c 1/1 Running 0 113s 10.244.1.24 kube1.vm <none> <none>
  8. pod/nginx-ds-b46lb 0/1 ContainerCreating 0 3s <none> kube2.vm <none> <none>

Job

Job可以运行一种pod,在该pod内的进程成功结束时,不再重启。一旦任务完成,pod就被认为处于完成状态。

比如可以使用在将一些数据导出到其他地方,这个工作可能会持续几个小时。

我们基于busybox镜像,sleep一段时间用于模拟这个操作。

job.yaml

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job
  5. spec:
  6. template: # 没有指定selector,会根据pod标签中自动创建
  7. metadata:
  8. labels:
  9. app: job
  10. spec:
  11. restartPolicy: OnFailure # 执行遇到异常则重启,默认为Always。
  12. containers:
  13. - name: sleepbusybox
  14. image: busybox
  15. command: ["/bin/sh","-c","sleep 60;echo this is busybox"]

restartPolicy表示pod的重启策略,默认Always,其他两项为OnFailure和Never。

运行查看

创建job

  1. -> [root@kube0.vm] [~] k create -f job.yaml
  2. job.batch/job created

60秒内查看:

  1. -> [root@kube0.vm] [~] k get job,pod
  2. NAME COMPLETIONS DURATION AGE
  3. job.batch/job 0/1 14s 14s
  4. NAME READY STATUS RESTARTS AGE
  5. pod/job-4sfv4 1/1 Running 0 14s

60秒后查看:

  1. -> [root@kube0.vm] [~] k get job,pod
  2. NAME COMPLETIONS DURATION AGE
  3. job.batch/job 1/1 68s 71s
  4. NAME READY STATUS RESTARTS AGE
  5. pod/job-4sfv4 0/1 Completed 0 71s

使用jsonpath获取 pod name 查看log

  1. -> [root@kube0.vm] [~] k logs $(k get po --selector=app=job --output=jsonpath={.items..metadata.name})
  2. this is busybox

completions与parallelism

job描述文件下的spec有两个字段:

  • completions:job要确保完成多少个pod,默认为1。
  • parallelism:最多并行运行多少个pod,默认为1。

job-batch.yaml

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job-batch
  5. spec:
  6. completions: 5
  7. parallelism: 2
  8. template:
  9. # 与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。

  1. apiVersion: batch/v1beta1
  2. kind: CronJob
  3. metadata:
  4. name: cron-job
  5. spec:
  6. schedule: "*/3 * * * * " # 每三分钟运行一次
  7. jobTemplate: # job的模板
  8. spec:
  9. template: # pod的模板
  10. metadata:
  11. labels:
  12. app: job-in-cron
  13. spec:
  14. restartPolicy: OnFailure
  15. containers:
  16. - name: sleepbusybox
  17. image: busybox
  18. command: ["/bin/sh","-c","sleep 60;echo this is busybox"]

运行

创建cron-job

  1. -> [root@kube0.vm] [~] k create -f cronjob.yaml
  2. cronjob.batch/cron-job created

等了几分钟

  1. -> [root@kube0.vm] [~] k get all
  2. NAME READY STATUS RESTARTS AGE
  3. pod/cron-job-1590053040-pqhhh 0/1 Completed 0 97s
  4. NAME COMPLETIONS DURATION AGE
  5. job.batch/cron-job-1590053040 1/1 68s 97s
  6. NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
  7. cronjob.batch/cron-job */3 * * * * False 0 105s 4m39s

又等了几分钟

  1. -> [root@kube0.vm] [~] k get all
  2. NAME READY STATUS RESTARTS AGE
  3. pod/cron-job-1590053040-pqhhh 0/1 Completed 0 3m4s
  4. pod/cron-job-1590053220-whflp 0/1 ContainerCreating 0 3s
  5. NAME COMPLETIONS DURATION AGE
  6. job.batch/cron-job-1590053040 1/1 68s 3m4s
  7. job.batch/cron-job-1590053220 0/1 3s 3s
  8. NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
  9. cronjob.batch/cron-job */3 * * * * False 1 12s 6m6s

可以看到就当前的描述文件而言,cron-job每次创建一个job,job创建一个pod的运行。

startingDeadlineSeconds

cronjob.spec.startingDeadlineSeconds规定pod必须预定时间之后的startingDeadlineSeconds秒内运行,超过此时间则不运行,并将其显示未Failed。

小结

  • 使用存活探针检查容器是否存活。
  • ReplicationController创建并管理Pod,但并不是绑定关系。它始终保持期望数量的副本正在运行。
  • ReplicationController将被弃用,ReplicaSet拥有更强的标签选择器。
  • DaemonSet会在每个节点上保持运行有且只有一个Pod,可以通过nodeSelector让其只在特定节点运行。
  • Job创建Pod运行完成后,Pod为为Completed状态。completions与parallelism指定需要完成的数量与并行度。
  • restartPolicy:默认Always,还有OnFailure、Never。
  • CronJob创建Job,Job创建Pod。
  • 命令:edit、scale

Kubernetes学习笔记(二):部署托管的Pod -- 存活探针、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob的更多相关文章

  1. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  2. Kubernetes学习笔记(八):Deployment--声明式的升级应用

    概述 本文核心问题是:如何升级应用. 对于Pod的更新有两种策略: 一是删除全部旧Pod之后再创建新Pod.好处是,同一时间只会有一个版本的应用存在:缺点是,应用有一段时间不可用. 二是先创建新Pod ...

  3. amazeui学习笔记二(进阶开发1)--项目结构structure

    amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...

  4. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  5. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  6. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  7. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  8. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  9. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

随机推荐

  1. SSL/TLS 漏洞“受戒礼”,RC4算法关闭

    SSL/TLS 漏洞"受戒礼" 一.漏洞分析 事件起因 2015年3月26日,国外数据安全公司Imperva的研究员Itsik Mantin在BLACK HAT ASIA 2015 ...

  2. libcurl库返回状态码解释与速查

    libcurl库返回状态码解释与速查     CURLE_OK(0) 支持返回 CURLE_UNSUPPORTED_PROTOCOL(1) 你的URL传递给libcurl的使用协议,这libcurl的 ...

  3. 表达式求值--数据结构C语言算法实现

    这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...

  4. Spring Developer Tools 源码分析:三、重启自动配置'

    接上文 Spring Developer Tools 源码分析:二.类路径监控,接下来看看前面提到的这些类是如何配置,如何启动的. spring-boot-devtools 使用了 Spring Bo ...

  5. Java ArrayList工作原理及实现

    http://yikun.github.io/2015/04/04/Java-ArrayList%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE% ...

  6. 理解CAS算法在JAVA中的作用

  7. 数学--数论--HDU1576 A / B(逆元)

    问题描述 要求(A / B)%9973,但由于A很大,我们只被告知n(n = A%9973)(我们给定的A必能被B整除,且gcd(B,9973)= 1). 输入项 数据的第一行是一个T,表示有T组数据 ...

  8. Python安装第三方模块出错 No module named setuptools

    在安装 zabbix-alerta 第三方模块时候报错 python setup.py install 此时需要安装 setuptools 模块, 这里用自动化脚本安装 wget https://bo ...

  9. JWT的浅谈

    在实际工作过程中,运行jmeter脚本的时候,开发给了一个jwt的授权信息,到底是做什么用的呢,翻阅了一些资料,整理如下: 一.JWT(Json Web Token)是什么 JWT是一串格式为xxxx ...

  10. 【Python】Django2.0集成Celery4.1详解

    环境准备 Python3.6 pip install Django==2.0.1 pip install celery==4.1.0 pip install eventlet (加入协程支持) 安装e ...