Pod生命周期
同一个pod中可以运行多个容器,我们在创建一个pod时可以通过创建多个容器来实现pod的整个生命周期,一个pod的创建包含如下过程:
Init容器(也叫做初始化容器):
Init容器就是做初始化工作的容器。可以有一个或多个,如果多个按照定义的顺序依次执行,只有所有的初始化容器执行完后,主容器才启动。由于一个Pod里的存储卷是共享的,所以Init Container里产生的数据可以被主容器使用到,Init Container可以在多种K8S资源里被使用到,如Deployment、DaemonSet, StatefulSet、Job等,但都是在Pod启动时,在主容器启动前执行,做初始化工作。
主容器:
容器钩子:
对于pod资源来说,容器钩子是在pods.spec.containers.lifecycle下定义的
初始化容器启动之后,开始启动主容器,在主容器启动之前有一个post start hook(容器启动后钩子)和pre stop hook(容器结束前钩子)
- postStart:该钩子在容器被创建后立刻触发,通知容器它已经被创建。如果该钩子对应的hook handler执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器,这个钩子不需要传递任何参
- preStop:该钩子在容器被删除前触发,其所对应的hook handler必须在删除该容器的请求发送给Docker daemon之前完成。在该钩子对应的hook handler完成后不论执行的结果如何,Docker daemon会发送一个SGTERN信号量给Docker daemon来删除该容器,这个钩子不需要传递任何参数
#查看postStart怎么定义的,可以用如下命令:
kubectl explain pods.spec.containers..postStart
#查看preStop怎么定义的,可以用如下命令:
kubectl explain pods.spec.containers.lifecycle.preStop
Init容器
# initContainers: # 初始化容器,在容器启动之前执行的一些初始化操作
# - command:
# - sh
# - -c
# - echo "I am InitContainer for init some configuration"
# image: busybox
# imagePullPolicy: IfNotPresent
# name: init-container
until ping 172.16.50.156 -c 1;do echo waiting for mysql;sleep 2;done;
until ping 172.16.50.157 -c 1;do echo waiting for redis;sleep 2;done;
验证方法
ifconfig ens192:1 172.16.50.158 netmask 255.255.255.0 up
ifconfig ens192:1 172.16.50.159 netmask 255.255.255.0 up
钩子函数
能够感知自身生命周期中的事件,并在相应的时刻运行用户指定的程序代码。
k8s在容器中的启动之后和停止之前提供了俩个钩子函数:
- post start :容器创建之后执行,如果失败了会重新启动容器。
- pre stop 容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会删除容器的操作。
Exec命令:在容器中执行一次命令
lifecycle:
postStart:
exec:
command:
-cat
- /tmp/healthy
TCPSocket:在当前容器尝试指定的socket
lifecycle:
postStart:
tcpSocket:
port:8080
HTTPGET:在当前容器中访问url http请求
lifecycle:
postStart:
httpGet:
path: /
port: 80
host: xxxx.xxx.xxx.xxx
scheme: HTTP
k8s 写一个yaml
apiVersion v1
kind Pod
metadata
name pod-hook-exec
namespace default
spec
containers
name main-container
image nginx1.8
ports
name nginx-port
containerPort80
lifecycle
postStart
exec
command'/bin/sh''-c'"echo poststart...? /usr/share/nginx/html/index.html"
preStop
exec
command"/usr/sbin/nginx"'-s'"quit"
# 创建pod
kubectl create -f pod-hook-exec.yaml
# 查看
kubectl get pods -o wide
# 访问
curl xxxx
容器探针
容器探针用于检测容器中的应用实例是否正常工作,是保障业务可用性的一种传统机制,如果经过探测,实例不符合预期,那么k8s可以摘除对应的pod,不承担业务浏览,支持2种探针。
liveness probes:存活性探针。用于检测实例是否正常运行,不正常就重启容器。
readiness probes 就绪探测针。用于检测当前实例是否可以接受请求,如果不能,k8s就会把流量给其它pod
liveness决定重启容器,readiness 决定是否将请求转发给容器
Exec命令:在容器中执行一次命令
lifecycle:
postStart:
exec:
command:
-cat
- /tmp/healthy
TCPSocket:在当前容器尝试指定的socket
lifecycle:
postStart:
tcpSocket:
port:8080
HTTPGET:在当前容器中访问url http请求
lifecycle:
postStart:
httpGet:
path: /
port: 80
host: xxxx.xxx.xxx.xxx
scheme: HTTP
容器探针:
livenessProbe:
指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success。
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success
#查看livenessProbe帮助命令:
kubectl explain pods.spec.containers.livenessProbe
#查看readinessProbe帮助命令:
kubectl explain pods.spec.containers.readinessProbe
常见的pod状态
(1)Pending:挂起,我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件。已经创建了但是没有适合它运行的节点叫做挂起,调度没有完成。
(2)Running:运行状态
(3)Failed:表示失败
(4)Succeeded:表示成功状态
(5)Unknown:未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown
容器探测详解
所谓容器探测就是我们在里面设置了一些探针,或者传感器来获取相应的数据用来判断容器存活与否或者就绪与否的标准;
目前k8s支持的存活性探测方式和就绪性探测方式都是一样的,探针类型有三种:
ExecAction:
TCPSocketAction:#Telnet 9999
HTTPGetAction: #200
如果探针是针对容器存活性检测的,就是容器存活性探针
如果探针是针对容器就绪状态检测的,就是融容器就绪性探针
kubectl explain pods.spec.containers
可以看到如下:
livenessProbe(容器存活性探针):
readinessProbe (容器就绪性探针)
lifecycle(容器生命周期探针):主要是用来定义容器启动后和结束前的钩子的
#查看livenessprobe和readinessprobe用法:
kubectl explain pods.spec.containers.livenessProbe
kubectl explain pods.spec.containers.readinessProbe
livenessProbe <Object>
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-probesreadinessProbe <Object>
Periodic probe of container service readiness. Container will be removed
from service endpoints if the probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
lifecycle <Object>
Actions that the management system should take in response to container lifecycle events. Cannot be updated.
(1)livenessProbe定义详解:
kubectl explain pods.spec.containers.livenessProbe
KIND: Pod
VERSION: v1
RESOURCE: livenessProbe <Object>
#livenessProbe是一个对象,内部的对象形式有三种,及探针类型有三个,exec,httpGet,tcpSock,我们平时定义的时候只需要定义三种探针中的任意一个即可
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.
#我们探测几次都失败了,才认为是失败的,我们不能够一锤定音,这样会导致误伤的,因此需要探测多次,默认是3次都探测失败,才认为是失败的
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.
#周期间隔时长,默认是10s中探测一次
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness. 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:
#每一次探测超时时间多长,探测请求之后始终没有响应,那么我们能等待的时间是多少,默认是1s
案例
apiVersion v1
kind Pod
metadata
name pod-liveness-exec
namespace default
spec
containers
name main-container
image nginx1.8
ports
name nginx-port
containerPort80
livenessProbe
exec
command'/bin/cat''/tmp/yunake.txt'
kubectl describe pod pod-liveness-exec
tcpsocket
vi pod-liveness-tcpsocket.yaml
apiVersion v1
kind Pod
metadata
name pod-liveness-exec
namespace default
spec
containers
name main-container
image nginx1.8
ports
name nginx-port
containerPort80
livenessProbe
tcpSocket
port8080
kubectl describe pod pod-liveness-tspsocket
kubectl create -f pod-liveness-tcpsocket.yaml
kubectl describe pod pod-liveness-tspsocket
httpGet
apiVersion v1
kind Pod
metadata
name pod-liveness-http
namespace default
spec
containers
name main-container
image nginx1.8
ports
name nginx-port
containerPort80
livenessProbe
httpGet
scheme HTTP
port80
path /
kubectl get pod pod-liveness-http
kubectl describe pod pod-liveness-http