pod 生命周期
我们一般将 pod 对象从创建至终的这段时间范围称为 pod 的生命周期,它主要包含下面的过程
- pod 创建过程
- 运行初始化容器(init container)过程
- 运行主容器(main container)
- pod 终止过程
在整个生命周期中,pod 会出现 5 种状态(相位),分别如下
- 挂起(Pending):apiserver 已经创建了 pod 资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中
- 运行中(Running):pod 已经被调度至某节点,并且所有容器都已经被 kubelet 创建完成
- 成功(Succeeded):pod 中的所有容器都已经成功终止并且不会被重启
- 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非 0 值的退出状态
- 未知(UnkNown):apiserver 无法正常获取到 pod 对象的状态信息,通常由网络通信失败所导致
创建和终止
pod 的创建过程
-
用户通过 kubectl 或其他 api 客户端提交需要创建的 pod 信息给 apiServer
-
apiServer 开始生成 pod 对象的信息,并将信息存入 etcd,然后返回确认信息至客户端
-
apiServer 开始反映 etcd 中的 pod 对象的变化,其它组件使用 watch 机制来跟踪检查 apiServer 上的变动
-
scheduler 发现有新的 pod 对象要创建,开始为 Pod 分配主机并将结果信息更新至 apiServer
-
node 节点上的 kubelet 发现有 pod 调度过来,尝试调用 docker 启动容器,并将结果回送至 apiServer
-
apiServer 将接收到的 pod 状态信息存入 etcd 中
pod 的终止过程
- 用户向 apiServer 发送删除 pod 对象的命令
- apiServcer 中的 pod 对象信息会随着时间的推移而更新,在宽限期内(默认30s),pod 被视为 dead
- 将 pod 标记为 terminating 状态
- kubelet 在监控到 pod 对象转为 terminating 状态的同时启动 pod 关闭过程
- 端点控制器监控到 pod 对象的关闭行为时将其从所有匹配到此端点的 service 资源的端点列表中移除
- 如果当前 pod 对象定义了 preStop 钩子处理器,则在其标记为 terminating 后即会以同步的方式启动执行
- pod 对象中的容器进程收到停止信号
- 宽限期结束后,若 pod 还存在仍在运行的进程,那么 pod 对象会收到立即终止的信号
- kubelet 请求 apiServer 将此 pod 资源的宽限期设置为 0 从而完成删除操作,此时 pod 对于用户已不可见
初始化容器
初始化容器是在 pod 的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征:
初始化容器有很多的应用场景,下面列出的是最常见的几个
接下来做一个案例,模拟下面这个需求:
假设要以主容器来运行 Nginx,但是要求在运行 Nginx 之前先要能够连接上 MysqL 和 redis 所在服务器
为了简化测试,事先规定好MysqL(192.168.90.14)
和redis(192.168.90.15)
服务器的地址
创建 pod-initcontainer.yaml,内容如下:
apiVersion: v1
kind: Pod
Metadata:
name: pod-initcontainer
namespace: zouzou
spec:
containers:
- name: main-container
image: Nginx:1.14
ports:
- name: Nginx-port
containerPort: 80
initContainers: # 初始化容器,有两个,分别 ping MysqL 和 redis,MysqL 可以 ping 通才会 ping redis
- name: test-MysqL
image: busyBox:1.30
command: ['sh', '-c', 'until ping 192.168.90.14 -c 1 ; do echo waiting for MysqL...; sleep 2; done;']
- name: test-redis
image: busyBox:1.30
command: ['sh', '-c', 'until ping 192.168.90.15 -c 1 ; do echo waiting for reids...; sleep 2; done;']
执行下面命令
# 创建pod
[root@dce-10-6-215-215 ~]# kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created
# 查看pod状态
# 发现pod卡在启动第一个初始化容器过程中,后面的容器不会运行
[root@dce-10-6-215-215 ~]# kubectl describe pod pod-initcontainer -n zouzou
........
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
normal Scheduled 49s default-scheduler Successfully assigned dev/pod-initcontainer to node1
normal Pulled 48s kubelet, node1 Container image "busyBox:1.30" already present on machine
normal Created 48s kubelet, node1 Created container test-MysqL
normal Started 48s kubelet, node1 Started container test-MysqL
# 动态查看pod
[root@dce-10-6-215-215 ~]# kubectl get pods pod-initcontainer -n zouzou -w
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 15s
pod-initcontainer 0/1 Init:1/2 0 52s
pod-initcontainer 0/1 Init:1/2 0 53s
pod-initcontainer 0/1 PodInitializing 0 89s
pod-initcontainer 1/1 Running 0 90s
# 接下来新开一个shell,为当前服务器新增两个ip,观察pod的变化
[root@dce-10-6-215-215 ~]# ifconfig ens33:1 192.168.90.14 netmask 255.255.255.0 up
[root@dce-10-6-215-215 ~]# ifconfig ens33:2 192.168.90.15 netmask 255.255.255.0 up
钩子函数
钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码
k8s 在主容器的启动之后和停止之前提供了两个钩子函数
钩子处理器支持使用下面三种方式定义动作
- Exec 命令:在容器内执行一次命令
……
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
……
- Tcpsocket:在当前容器尝试访问指定的 socket
……
lifecycle:
postStart:
tcpsocket:
port: 8080
……
- HTTPGet:在当前容器中向某 url 发起 http 请求
……
lifecycle:
postStart:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.5.3 #主机地址
scheme: HTTP #支持的协议,http或者https
……
接下来,以 exec 方式为例,演示下钩子函数的使用,创建 pod-hook-exec.yaml 文件,内容如下:
apiVersion: v1
kind: Pod
Metadata:
name: pod-hook-exec
namespace: zouzou
spec:
containers:
- name: main-container
image: Nginx:1.14
ports:
- name: Nginx-port
containerPort: 80
lifecycle:
postStart:
exec: # 在容器启动的时候执行一个命令,修改掉 Nginx 的默认首页内容
command: ["/bin/sh", "-c", "echo postStart... > /usr/share/Nginx/html/index.html"]
preStop:
exec: # 在容器停止之前停止Nginx服务,这个效果在这里看不到
command: ["/usr/sbin/Nginx","-s","quit"]
启动 pod,查看内容
# 创建 pod
[root@dce-10-6-215-215 tmp]# kubectl apply -f pod-hook-exec.yaml
pod/pod-hook-exec created
# 查看 pod 的详细信息
[root@dce-10-6-215-215 tmp]# kubectl get pod pod-hook-exec -n zouzou -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READInesS GATES
pod-hook-exec 1/1 Running 0 48s 172.29.34.229 dce-10-6-215-200 <none> <none>
# 查看内容,可以看到返回的是更改后的
[root@dce-10-6-215-215 tmp]# curl 172.29.34.229:80
postStart...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。