我们一般将pod对象从创建至终这段时间范围成为pod的生命周期,它主要包含以下的过程:

在整个生命周期中,Pod会出现5种状态:

初始化容器是在pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征
初始化容器有很多的应用场景,下面列出的是最常见的几个
接下来做一个案例,模拟下面这个需求
假设要以主容器来运行nginx,但是要求在运行nginx之前要能够连接上mysql和redis所在服务器
为了简化测试,事先规定好mysql和redis服务器的地址
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer namespace: dev
labels:
user: ayanami
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 initContainers: - name: test-mysql
image: busybox:1.30 command: ['sh','-c','until ping 192.168.145.231 -c 1; do echo waiting for mysql...;sleep 2; done'] - name: test-redis
image: busybox:1.30 command: ['sh','-c','until ping 192.168.145.232 -c 1; do echo waiting for redis...;sleep 2; done']
[root@master ~]# vim pod-initcontainer.yaml
[root@master ~]# kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created
[root@master ~]# kubectl get pod pod-initcontainer -n dev
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 20s
发现container一直处于初始化状态
此时添加ip地址(注:ens32是你的网卡的名字,不同机器可能不同,可以用ifconfig查看)
[root@master ~]# ifconfig ens32:1 192.168.145.231 netmask 255.255.255.0 up
[root@master ~]# ifconfig ens32:2 192.168.145.232 netmask 255.255.255.0 up
[root@master ~]# kubectl get pod pod-initcontainer -n dev
NAME READY STATUS RESTARTS AGE
pod-initcontainer 1/1 Running 0 19m
发现pod跑起来了
钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码
k8s在主容器的启动之后和停止之前提供了两个钩子函数
钩子处理器支持使用下面三种方式定义动作:
......
lifecycle:
postStart:
exec:
command: - cat - /tmp/healthy
......
......
lifecycle:
postStart:
tcpSocket:
port: 8080 ......
......
lifecycle:
postStart:
httpGet:
path: #uri地址
port:
host:
scheme: HTTP #支持的协议,http或者https
......
下面演示钩子函数的使用
创建pod-hook-exec.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 lifecycle:
postStart:
exec: #在容器启动的时候执行一个命令,修改掉nginx的默认首页内容
command: ["/bin/sh","-c","echo postStart... > /usr/share/nginx/html/index.html"]
preStop: #在容器停止之前停止nginx服务
exec:
command: ["/usr/sbin/nginx","-s","quit"]
使用配置文件
[root@master ~]# vim pod-hook-exec.yaml
[root@master ~]# kubectl create -f pod-hook-exec.yaml
pod/pod-hook-exec created
[root@master ~]# kubectl get pod pod-hook-exec -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hook-exec 1/1 Running 0 43s 10.244.2.22 node1 <none> <none> [root@master ~]# curl 10.244.2.22:80 postStart...
容器探测用于检测容器中的应用实例是否能正常工作,是保障业务可用性的一种传统机制。如果经过探测,实例的状态不符合预期
,那么K8S就会把该问题实例“摘除”,不承担业务流量,k8s提供了两种探针来实现容器探测,分别是:
即livenessProbe决定是否重启容器,readinesProbe决定是否将请求转发给容器
上面两种探针目前均支持三种探测方式:
......
livenessProbe:
exec:
command: - cat - /tmp/healthy
......
......
livenessProbe:
tcpSocket:
port: 8080
......
......
lifecycle:
postStart:
httpGet:
path: #uri地址
port:
host:
scheme: HTTP #支持的协议,http或者https
......
下面以liveness probes为例,做几个演示:
创建pod-liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
exec:
command: ["/bin/cat","/tmp/hello.txt"] #执行一个查看文件的命令
使用配置文件
[root@master ~]# vim pod-liveness-exec.yaml
[root@master ~]# kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created
[root@master ~]# kubectl get pod pod-liveness-exec -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-exec 1/1 Running 1 102s
发现pod重启了一次,查看错误信息
[root@master ~]# kubectl describe pod pod-liveness-exec -n dev
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/pod-liveness-exec to node1
Normal Pulled 49s (x4 over 2m20s) kubelet, node1 Container image "nginx:1.17.1" already present on machine
Normal Created 49s (x4 over 2m20s) kubelet, node1 Created container main-container
Normal Started 49s (x4 over 2m20s) kubelet, node1 Started container main-container
Normal Killing 49s (x3 over 109s) kubelet, node1 Container main-container failed liveness probe, will be restarted
Warning Unhealthy 39s (x10 over 2m9s) kubelet, node1 Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
修改文件内容
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
exec:
command: ["/bin/ls","/tmp/"] #执行一个查看文件的命令
使用配置文件
[root@master ~]# vim pod-liveness-exec.yaml
[root@master ~]# kubectl delete -f pod-liveness-exec.yaml
[root@master ~]# kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created
[root@master ~]# kubectl get pod pod-liveness-exec -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-exec 1/1 Running 0 84s
说明没有重启
创建pod-liveness-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-tcpsocket namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
tcpSocket:
port: 8080 #尝试访问8080端口
使用配置文件
[root@master ~]# vim pod-liveness-tcpsocket.yaml
[root@master ~]# kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created
[root@master ~]# kubectl get pod pod-liveness-tcpsocket -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-tcpsocket 1/1 Running 1 29s
[root@master ~]# kubectl describe pod pod-liveness-tcpsocket -n dev
Events:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/pod-liveness-tcpsocket to node1
Normal Pulled 43s (x4 over 2m10s) kubelet, node1 Container image "nginx:1.17.1" already present on machine
Normal Created 43s (x4 over 2m10s) kubelet, node1 Created container main-container
Normal Started 43s (x4 over 2m10s) kubelet, node1 Started container main-container
Normal Killing 43s (x3 over 103s) kubelet, node1 Container main-container failed liveness probe, will be restarted
Warning Unhealthy 33s (x10 over 2m3s) kubelet, node1 Liveness probe failed: dial tcp 10.244.2.25:8080: connect: connection refused
更改文件内容
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-tcpsocket namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
tcpSocket:
port: 80 #尝试访问80端口
重新使用配置文件
[root@master ~]# vim pod-liveness-tcpsocket.yaml
[root@master ~]# kubectl delete -f pod-liveness-tcpsocket.yaml
pod "pod-liveness-tcpsocket" deleted
[root@master ~]# kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created
[root@master ~]# kubectl get pod pod-liveness-tcpsocket -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-tcpsocket 1/1 Running 0 18s
表明没有问题
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
httpGet: #其实就是访问http://127.0.0.1:80/hello
scheme: HTTP #支持的协议,http或https
port: 80 path: /hello #uri地址
使用配置文件
[root@master ~]# vim pod-liveness-httpget.yaml
[root@master ~]# kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created
[root@master ~]# kubectl get pod pod-liveness-httpget -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-httpget 1/1 Running 1 75s
[root@master ~]# kubectl describe pod pod-liveness-httpget -n dev
Events:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/pod-liveness-httpget to node2
Normal Pulled 18s (x3 over 74s) kubelet, node2 Container image "nginx:1.17.1" already present on machine
Normal Created 18s (x3 over 74s) kubelet, node2 Created container main-container
Normal Killing 18s (x2 over 48s) kubelet, node2 Container main-container failed liveness probe, will be restarted
Normal Started 17s (x3 over 73s) kubelet, node2 Started container main-container
Warning Unhealthy 8s (x7 over 68s) kubelet, node2 Liveness probe failed: HTTP probe failed with statuscode: 404
可以看见pod在重启,详细描述说明没找到这个网址
修改配置文件
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget namespace: dev
spec:
containers: - name: main-container
image: nginx:1.17.1 ports: - name: nginx-port
containerPort: 80 livenessProbe:
httpGet: #其实就是访问http://127.0.0.1:80/
scheme: HTTP #支持的协议,http或https
port: 80 path: / #uri地址
重新使用配置文件
[root@master ~]# kubectl delete -f pod-liveness-httpget.yaml
pod "pod-liveness-httpget" deleted
[root@master ~]# kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created
[root@master ~]# kubectl get pod pod-liveness-httpget -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-httpget 1/1 Running 0 24s
Events:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/pod-liveness-httpget to node2
Normal Pulled 27s kubelet, node2 Container image "nginx:1.17.1" already present on machine
Normal Created 27s kubelet, node2 Created container main-container
Normal Started 27s kubelet, node2 Started container main-container
表明配置没有问题
在容器探测中,一旦容器探测出现了问题,kubernetes就会对容器所在的Pod进行重启,其实这是由Pod的默认重启策略决定的。Pod的重启策略有3种:
新建pod-lifecycle.yaml,内容如下:
[root@k8s-master ~]# cat pod-lifecycle.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-lifecycle
namespace: dev
labels:
user: bulut
spec:
containers:
- name: nginx-container
image: nginx:latest
restartPolicy: Never
[root@k8s-master ~]#
至此,已经使用liveness probe演示了三种探测方式,但是查看livenessProbe的子属性,会发现除了这三种方式,还有一些其他的配置,在这里一并解释下
[root@master ~]# kubectl explain pod.spec.containers.livenessProbe
KIND: Pod
VERSION: v1
RESOURCE: livenessProbe <Object> DESCRIPTION:
Periodic probe of container liveness. Container will be restarted if the
probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
Probe describes a health check to be performed against a container to
determine whether it is alive or ready to receive traffic.
FIELDS:
exec <Object> One and only one of the following should be specified. Exec specifies the
action to take.
failureThreshold <integer> Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
httpGet <Object> HTTPGet specifies the http request to perform.
initialDelaySeconds <integer> Number of seconds after the container has started before liveness probes
are initiated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
periodSeconds <integer> How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
successThreshold <integer> Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
tcpSocket <Object> TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
timeoutSeconds <integer> Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes