Kubernetes(k8s)之Pod生命周期
Posted Tuki_a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes(k8s)之Pod生命周期相关的知识,希望对你有一定的参考价值。
什么是Pod生命周期
和一个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID),并被调度到节点,pod在终止(根据重启策略)或删除之前一直运行在该节点。
如果一个节点死掉了,调度到该节点 的 Pod 也被计划在给定超时期限结束后删除。
Pod 自身不具有自愈能力。如果 Pod 被调度到某节点,但是该节点之后失效了,或者调度操作本身失效了,Pod 会被删除;与此类似,Pod 无法在节点资源 耗尽或者节点维护期间继续存活。Kubernetes 使用一种高级抽象,称作控制器,来管理这些相对而言可随时丢弃的 Pod 实例。
一般将pod对象从创建至结束的这段时间范围成为pod的生命周期,它主要包含下面的过程:
1、pod创建过程
2、运行初始化容器(init container)过程(可多可少,可有可无)
3、 运行主容器(main container)过程
容器启动后执行的钩子函数(post start),容器终止前执行的钩子函数( pre stop)
容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
4、pod终止过程
一张图来说明:
Init初始化容器
Init容器能干的事
Pod 可以包含多个容器,应用运行在这些容器里面。
Pod 可以有一个或多个先于应用容器启动的 Init 容器。
1、Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
2、Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。因为初始化容器运行完后就关闭了,别人不可能连到你的容器里再去用/扫描这些工具。
3、应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
4、Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
5、由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
Init容器特点
Init 容器与普通的容器非常像,除了如下两点:
它们总是运行到完成。
Init 容器不支持Readiness(就绪检查)/探针,因为它们必须在 Pod 就绪之前运行完成(必须在主容器运行之前运行成功),每个 Init 容器必须运行成功,下一个才能够运行。
如果 Pod 的init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的restartPolicy 值为 Never,它不会重新启动。
init初始化实例
编写一个包含初始化容器的yaml文件,各个参数的意义参照上一篇文资源清单。
先将后边的服务注释掉一个,看能否运行成功
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container #主容器,要在初始化容器运行完成后才能运行
image: busyboxplus
command: ['sh', '-c', 'echo The app is running! && sleep 3600'] #sh -c让bash将一个字串作为完整的命令来执行
initContainers:
- name: init-myservice #初始化容器的服务之一
image: busyboxplus
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"] #查询DNS的记录,查看域名解析是否正常,监控最下面的服务是否正常运行
- name: init-mydb #初始化容器的服务之一
image: busyboxplus
command: ['sh', '-c', "until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done"] #一直在作解析,svc名字.namespace后边是固定的,查询DNS的记录,监控最下面的服务是否正常运行
--- #用三个分隔符分开,上下互不影响,下面这两个服务是初始化容器要用启动的服务,这两个起不来初始化容器也不能启动完成
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
--- #这个初始化容器运行需要启动的服务被注释掉,pod运行应该失败
#apiVersion: v1
#kind: Service
#metadata:
# name: mydb
#spec:
# ports:
# - protocol: TCP
# port: 80
# targetPort: 9377
应用文件,查看状态,只完成了一个初始化容器的启动,符合预期,最后删掉
去掉注释,重新运行,可以看到两个初始化服务已经运行成功了
探针
探针是由 kubelet 对容器执行的定期诊断:
ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
成功:容器通过了诊断。
失败:容器未通过诊断。
未知:诊断失败,因此不会采取任何行动。
Kubelet 可以选择是否执行容器上运行的三种探针执行并做出反应:
1、存活探针livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success。
2、就绪探针readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod 匹配的所有Service的端点中删除该 Pod 的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。
3、startupProbe:指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
重启策略:
PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。
Pod 的生命:
一般Pod 不会消失,直到人为销毁他们,这可能是一个人或控制器。
建议创建适当的控制器来创建 Pod,而不是直接自己创建 Pod。因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
三种可用的控制器:
使用 Job 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 OnFailure 或 Never 的 Pod。
对预期不会终止的 Pod 使用 ReplicationController、ReplicaSet 和 Deployment ,例如 Web 服务器。 ReplicationController 仅适用于具有 restartPolicy 为 Always 的 Pod。
提供特定于机器的系统服务,使用 DaemonSet 为每台机器运行一个 Pod 。
livenessProbe存活探针
探针官方文档可点击查看
[root@server2 pod]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1 #容器启动后多少秒探测
periodSeconds: 3 #探测间隔
timeoutSeconds: 1 #探测超时后的秒数
应用文件,探测8080端口是否开着,一直不满足探测条件,就会一直重新探测
readinessProbe就绪探针
就绪探针在脚本的应用是判断80端口访问下,是否能够获取/test.html页面内容,如果能够获取内容,证明服务访问正常,一切准备就绪,可以进入下一周期,反之不满足,失败。
[root@server2 pod]# vim pod.yaml
文件内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
在没有就绪的情况下,服务不会暴露给外部,所以外部不能访问,只能通过内部访问。
[root@server2 pod]# vim svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysvc
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
后端为空,进入服务内部,发布测试页面,可以通过外部访问,处于就绪状态
以上是关于Kubernetes(k8s)之Pod生命周期的主要内容,如果未能解决你的问题,请参考以下文章
运维实战 kubernetes(k8s) 之 pod 的建立