K8S容器编排之POD健康检测(1)
K8S容器编排之POD健康检测(1)
Pod健康检测机制
对于Pod
的健康状态检测,kubernetes
提供了两类探针(Probe)来执行对Pod的健康状态检测:
-
LivenessProbe探针:
用于判断容器是否存活,即Pod是否为running
状态,如果LivenessProbe探针
探测到容器不健康,则kubele
t将kill
掉容器,并根据容器的重启策略是否重启,如果一个容器不包含LivenessProbe
探针,则Kubelet
认为容器的LivenessProbe
探针的返回值永远成功。
-
ReadinessProbe探针:
用于判断容器是否启动完成,即容器的Ready
是否为True
,可以接收请求,如果ReadinessProbe探测
失败,则容器的Ready
将为False
,控制器将此Pod
的Endpoint
从对应的service
的Endpoint
列表中移除,从此不再将任何请求调度此Pod
上,直到下次探测成功。
每类探针都支持三种探测方法:
exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。
httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康。
tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康。
探针探测的结果有以下三者之一:Success:Container通过了检查。
Failure:Container未通过检查。
Unknown:未能执行检查,因此不采取任何措施。
LivenessProbe探针配置
示例一:通过exec方式做健康探测
exec-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
在该配置文件中,对容器执行livenessProbe
检查,periodSeconds
字段指定kubelet每5s执行一次检查,检查的命令为cat /tmp/healthy
,initialDelaySeconds
字段告诉kubelet
应该在执行第一次检查之前等待5秒,
如果命令执行成功,则返回0,那么kubelet就认为容器是健康的,如果为非0,则Kubelet会Kill掉容器并根据重启策略来决定是否需要重启。
当容器启动时,它会执行以下命令:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
对于容器的前30秒,有一个/tmp/healthy
文件。因此,在前30秒内,该命令cat /tmp/healthy
返回成功代码。30秒后,cat /tmp/healthy
返回失败代码。
创建Pod:
kubectl create -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
在30秒
内,查看Pod事件
:
kubectl describe pod liveness-exec
输出表明尚未探测到失败
:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
35秒
后,再次查看Pod事件
:
kubectl describe pod liveness-exec
在输出的中显示探测失败
,并且容器已被杀死
并重新创建
。
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
再等30秒
,确认Container已重新启动
:
kubectl get pod liveness-exec
下面输出中RESTARTS
的次数已增加:
AME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
示例二:通过HTTP方式做健康探测
pods/probe/http-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
在配置文件中,使用k8s.gcr.io/liveness
镜像,创建出一个Pod
,其中periodSeconds
字段指定kubelet
每3秒执行一次探测,initialDelaySeconds
字段告诉kubelet
延迟等待3秒,探测方式为向容器中运行的服务发送HTTP GET
请求,请求8080端口下的/healthz
, 任何大于或等于200
且小于400
的代码表示成功。任何其他代码表示失败。
创建此Pod
kubectl create -f https://k8s.io/examples/pods/probe/http-liveness.yaml
10秒后,查看Pod事件以验证liveness探测失败并且Container已重新启动:
kubectl describe pod liveness-http
httpGet
探测方式有如下可选的控制字段
host
:要连接的主机名,默认为Pod IP
,可以在http request head
中设置host头部
。
scheme
: 用于连接host
的协议,默认为HTTP
。
path
:http服务器上的访问URI。
httpHeaders
:自定义HTTP
请求headers
,HTTP
允许重复headers
。
port
: 容器上要访问端口号或名称。
示例三:通过TCP方式做健康探测
Kubelet
将尝试在指定的端口上打开容器上的套接字,如果能建立连接,则表明容器健康。
pods/probe/tcp-liveness-readiness.yaml
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
TCP检查方式
和HTTP检查方式
非常相似,示例中两种探针都使用了,在容器启动5秒后,kubelet
将发送第一个readinessProbe探针
,这将连接到容器的8080
端口,如果探测成功,则该Pod
将被标识为ready
,10秒后,kubelet
将进行第二次连接。
除此之后,此配置还包含了livenessProbe探针
,在容器启动15秒后,kubelet
将发送第一个livenessProbe探针
,仍然尝试连接容器的8080端口,如果连接失败则重启容器。
创建:
kubectl create -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
15秒后,查看Pod事件以验证活动探测:
kubectl describe pod goproxy
当容器有多个端口时,通常会给每个端口命名,所以在使用探针探测时,也可以直接写自定义的端口名称
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
目录 返回
首页