Fork me on GitHub
Fork me on GitHub

Kubernetes Pod探针

探针类型

探针主要有两种:livenessProbe和readinessProbe。

1
[root@spark32 ~]# kubectl explain pods.spec.containers

容器探测无非就是我们在里面设置了一些探针,或传感器来获取相应的数据作为判定其存活与否的标准和就绪与否的标准。对于 livenessProbe和readinessProbe 这两种探针,可定义的具体探针有三种:

  • ExecAction
  • TCPSocketAction
  • HTTPGetAction

每次定义三者之中的一个就可以了。

1
$ kubectl explain pods.spec.containers.livenessProbe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- exec <Object>
exec探针。执行用户自定义命令,这个命令得是容器中存在的命令才行
- failureThreshold <integer>
探测几次都失败,才认为是失败的。默认是3个。
- httpGet <Object>
httpGet探针
- initialDelaySeconds <integer>
在容器启动以后多久做探测,很多时间容器启动了,但是主程序很可能还没初始化完成。因此应该等一些时间在探测。默认是容器一启动就探测。
- periodSeconds <integer>
每次探测之间间隔多长时间,默认10s
- successThreshold <integer>
成功几次说明ok,默认是1次
- tcpSocket <Object>
tcpSocket探针
- timeoutSeconds <integer>
超时时间,发出探测,多久没响应,默认1s。

readiness探测所使用的字段和liveness字段是一样的。只是两者探测目的不一样。

livenessProbe探针示例

exec探测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@spark32 ~]# kubectl explain pods.spec.containers.livenessProbe.exec
KIND: Pod
VERSION: v1
RESOURCE: exec <Object>
DESCRIPTION:
One and only one of the following should be specified. Exec specifies the
action to take.
ExecAction describes a "run in container" action.
FIELDS:
command <[]string>
Command is the command line to execute inside the container, the working
directory for the command is root ('/') in the container's filesystem. The
command is simply exec'd, it is not run inside a shell, so traditional
shell instructions ('|', etc) won't work. To use a shell, you need to
explicitly call out to that shell. Exit status of 0 is treated as
live/healthy and non-zero is unhealthy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@spark32 manifests]# vim liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["sh","-c","touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/healthy"]
initialDelaySeconds: 1 #默认0s,即容器一启动就探测
periodSeconds: 3 #每隔多长时间进行探测
[root@spark32 manifests]# kubectl create -f liveness-exec.yaml
pod/liveness-exec-pod created

过个30s,然后去查看下这个pod的状态:

1
[root@spark32 manifests]# kubectl describe pod liveness-exec-pod

httpGet探测

如果容器内是个web服务,可以使用TCP套接字探测,还可以使用HTTP探测。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@spark32 manifests]# kubectl explain pods.spec.containers.livenessProbe.httpGet
KIND: Pod
VERSION: v1
RESOURCE: httpGet <Object>
DESCRIPTION:
HTTPGet specifies the http request to perform.
HTTPGetAction describes an action based on HTTP Get requests.
FIELDS:
host <string>
Host name to connect to, defaults to the pod IP. You probably want to set
"Host" in httpHeaders instead.
httpHeaders <[]Object>
Custom headers to set in the request. HTTP allows repeated headers.
path <string>
Path to access on the HTTP server.
port <string> -required-
Name or number of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
scheme <string>
Scheme to use for connecting to the host. Defaults to HTTP.

  • host
    默认往Pod IP发请求。

  • httpHeaders <[]Object>
    自定义首部。

  • path
    向哪个url发请求

  • port -required-
    Name or number of the port to access on the container. Number must be in
    the range 1 to 65535. Name must be an IANA_SVC_NAME.
    如果我们在containers暴露定义了名称,这里port这个字段可以使用定义的名称。

  • scheme
    Scheme to use for connecting to the host. Defaults to HTTP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@spark32 manifests]# vim liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1 #默认0s,即容器一启动就探测
periodSeconds: 3 #每隔多长时间进行探测
1
2
3
[root@spark32 manifests]# kubectl create -f liveness-httpget.yaml
pod/liveness-httpget-pod created
[root@spark32 manifests]# kubectl describe pod liveness-httpget-pod


下面手动进入Pod中的容器,删除这个index.html文件,然后看看探针是否探测失败:

1
2
3
4
[root@spark32 manifests]# kubectl exec -it liveness-httpget-pod -- /bin/sh
/ # ls /usr/share/nginx/html/
50x.html index.html
/ # rm -f /usr/share/nginx/html/index.html

在另一个终端 describe 这个pod:

1
[root@spark32 manifests]# kubectl describe pod liveness-httpget-pod | grep -i liveness

readinessProbe探针示例

就绪性探测必要性


如果你不定义就绪,那么容器一启动,该容器状态就显示为1,就绪。
就绪性探测和service调度有着重要的关联性。service是个固定入口端点,为动态地、有生命周期的Pod资源提供一个固定的入口端口。客户端不是直接访问Pod,而是访问service。service使用标签选择器关联至各Pod资源。这里有个问题,比如现在又创建了一个新Pod出来,这个新Pod正好符合这个service标签选择器的选择条件,立即把这个Pod作为后端对象了。用户请求进来可能被调度到这个新Pod上了。但是这个新Pod一创建成功,就被service关联到后端去了,但是此时Pod里的服务很有可能还没就绪。这个时候有请求被调度上来,肯定是访问不到服务的。因此要做就绪性探测,否则Pod一创建就被立即关联到service上了。所以以后使用Pod必须要做readinessProbe。
readinessProbe和livenessProbe支持的探针都是一样的,但是两者目的不一样。

httpGet探测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@spark32 manifests]# cp liveness-httpget.yaml readiness-httpget.yaml
[root@spark32 manifests]# vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1 #默认0s,即容器一启动就探测
periodSeconds: 3 #每隔多长时间进行探测
1
2
3
4
5
6
7
8
9
10
[root@spark32 manifests]# kubectl create -f readiness-httpget.yaml
[root@spark32 manifests]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client-69fd89d767-95nqt 1/1 Running 1 6d21h
liveness-httpget-pod 1/1 Running 1 34m
myapp-5bc569c47d-qq8lb 1/1 Running 0 7d
myapp-5bc569c47d-stvj9 1/1 Running 0 7d
myapp-5bc569c47d-tzlsf 1/1 Running 0 7d
nginx-deploy-55d8d67cf-wf28j 1/1 Running 0 7d1h
readiness-httpget-pod 1/1 Running 0 3s

已经显示为就绪状态。然后我们进入这个Pod中的容器,删除index.html文件

1
2
[root@spark32 manifests]# kubectl exec -it readiness-httpget-pod -- /bin/sh
/ # rm -f /usr/share/nginx/html/index.html



1
/ # echo "hi" >> /usr/share/nginx/html/index.html

Pod生命周期中的另外一种行为lifecycle:启动后钩子和终止前钩子

在主容器刚刚启动之后,用户可以手动嵌入做一些操作,可以做一个 post start,比如执行完一个命令就退出。
如果主容器要退出,在结束之前,也可以做一些事情,pre stop。类似于awk的BEGIN和END。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@spark32 manifests]# kubectl explain pods.spec.containers.lifecycle
KIND: Pod
VERSION: v1
RESOURCE: lifecycle <Object>
DESCRIPTION:
Actions that the management system should take in response to container
lifecycle events. Cannot be updated.
Lifecycle describes actions that the management system should take in
response to container lifecycle events. For the PostStart and PreStop
lifecycle handlers, management of the container blocks until the action is
complete, unless the container process fails, in which case the handler is
aborted.
FIELDS:
postStart <Object>
PostStart is called immediately after a container is created. If the
handler fails, the container is terminated and restarted according to its
restart policy. Other management of the container blocks until the hook
completes. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
preStop <Object>
PreStop is called immediately before a container is terminated due to an
API request or management event such as liveness probe failure, preemption,
resource contention, etc. The handler is not called if the container
crashes or exits. The reason for termination is passed to the handler. The
Pod's termination grace period countdown begins before the PreStop hooked
is executed. Regardless of the outcome of the handler, the container will
eventually terminate within the Pod's termination grace period. Other
management of the container blocks until the hook completes or until the
termination grace period is reached. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@spark32 manifests]# kubectl explain pods.spec.containers.lifecycle.postStart
KIND: Pod
VERSION: v1
RESOURCE: postStart <Object>
DESCRIPTION:
PostStart is called immediately after a container is created. If the
handler fails, the container is terminated and restarted according to its
restart policy. Other management of the container blocks until the hook
completes. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
Handler defines a specific action that should be taken
FIELDS:
exec <Object>
One and only one of the following should be specified. Exec specifies the
action to take.
httpGet <Object>
HTTPGet specifies the http request to perform.
tcpSocket <Object>
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@spark32 manifests]# kubectl explain pods.spec.containers.lifecycle.preStop
KIND: Pod
VERSION: v1
RESOURCE: preStop <Object>
DESCRIPTION:
PreStop is called immediately before a container is terminated due to an
API request or management event such as liveness probe failure, preemption,
resource contention, etc. The handler is not called if the container
crashes or exits. The reason for termination is passed to the handler. The
Pod's termination grace period countdown begins before the PreStop hooked
is executed. Regardless of the outcome of the handler, the container will
eventually terminate within the Pod's termination grace period. Other
management of the container blocks until the hook completes or until the
termination grace period is reached. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
Handler defines a specific action that should be taken
FIELDS:
exec <Object>
One and only one of the following should be specified. Exec specifies the
action to take.
httpGet <Object>
HTTPGet specifies the http request to perform.
tcpSocket <Object>
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported

【示例】:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@spark32 manifests]# vim poststart-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: poststart-pod
namespace: default
spec:
containers:
- name: busybox-httpd
image: busybox:latest
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: ["mkdir","-p","/data/web/html"]
command: ["/bin/sh","-c","sleep 3600"]
[root@spark32 manifests]# kubectl create -f poststart-pod.yaml
pod/poststart-pod created
[root@spark32 manifests]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client-69fd89d767-95nqt 1/1 Running 1 6d22h
liveness-httpget-pod 1/1 Running 1 134m
myapp-5bc569c47d-qq8lb 1/1 Running 0 7d1h
myapp-5bc569c47d-stvj9 1/1 Running 0 7d1h
myapp-5bc569c47d-tzlsf 1/1 Running 0 7d1h
nginx-deploy-55d8d67cf-wf28j 1/1 Running 0 7d2h
poststart-pod 1/1 Running 0 6s
readiness-httpget-pod 1/1 Running 0 100m
[root@spark32 manifests]# kubectl exec -it poststart-pod -- /bin/sh
/ # ls /data/web/html/
/ # ls /data/
web