实现容器探测的几种方式: 探针类型有三种: ExecAtion TCPSocketAction HTTPGetAction
那么探针针对于存活性来做的话,就是存活性探针,针对就绪来做,就是就绪性探针
那么 livenessProbe 是做存活性探测 ,存活未必就绪
livenessProbe
readinessProbe 是做就绪性探测的
readinessProbe
lifecycle
[root@server1 ~]# kubectl explain pods.spec.containers.livenessProbe
下面是三种定义的探针,那么我们每次定义的时候都定义三种中的一种就可以了
exec
httpGet
tcpSocket
这个字段的意思是,探针在探测的过程中,并不是一开始探测的时候,探测到失败就认为是失败的,那么只有探测3次以上才认为它是失败的。
failureThreshold
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
这个字段表示探测的生命周期,也就是间隔多长时间进行探测一次 ,默认是10秒探测一次
periodSeconds
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
那么在探测的时候始终没有响应应该等多久,默认是等待的1秒钟
timeoutSeconds
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
因为容器在启动的时候是需要进行初始化的,因此在初始化期间是不能被探测的,那么在初始化的这个时间段,我们延迟探测的时间,因此我们要定义这个时间段在容器初始化完成后进行探测,那么如果不定义的话,那么默认的情况下是容器一启动就会进行探测,那么容器启动并不代表主进程可以对外服务了
initialDelaySeconds
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
那么下来写一个探测性的pod对象的用于检测的exec探针的pod对象
[root@server1 ~]# 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: ["bin/sh","-c","touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 3600"] 在容器内部执行的命令
livenessProbe: 做存活性探测
exec: 使用exec的探针
command: ["test","-e","/tmp/healthy"] exec 默认使用命令做探针 -e 检测创建的文件是否存在
initialDelaySeconds: 1 延迟探测的时间为1s
periodSeconds: 3 周期性探测的时间为3s
[root@server1 ~]# kubectl create -f liveness-exec.yaml
pod/liveness-exec-pod created
[root@server1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client 0/1 Error 0 1d
liveness-exec-pod 1/1 Running 0 9s
myapp-848b5b879b-lj66h 1/1 Running 2 1d
myapp-848b5b879b-tbnjb 1/1 Running 2 1d
myapp-848b5b879b-tl78s 1/1 Running 2 1d
nginx-deploy-5b595999-stvlq 1/1 Running 2 1d
pod-demo 2/2 Running 4 17h
那么我们使用describe查看描述的详细的信息:
[root@server1 ~]# kubectl describe pods liveness-exec-pod
Name: liveness-exec-pod
Namespace: default
Priority: 0
PriorityClassName:
Node: server3/172.25.254.3
Start Time: Sun, 05 May 2019 12:51:52 +0800
Labels:
Annotations:
Status: Running
IP: 10.244.2.22
Containers:
................
Finished: Sun, 05 May 2019 12:53:00 +0800
Ready: True
Restart Count: 1 使用liveness 探测成功的 延迟是1s 周期是3s 成功了 1次 失败了3次
Liveness: exec [test -e /tmp/healthy] delay=1s timeout=1s period=3s #success=1 #failure=3
Environment:
.................
做了livenessProbe的探测之后,就会发现pod对象会被重启,当探测不到或者失败时默认使用的重启策略会将pod内的容器重启,但是重启时候并不总是重启,第一次重启可能是立即的第二次可能就是10s后第三次可能就是30s。。。
那么上述的探测就是exec的探测方式,在exec探测的时候就是使用相应的命令在容器内进行探测
下来我们看一下如何对一个web的服务器做探测,探测器中的服务的请求等等之类的 ,下面演示使用tcpSocket做探测
[root@server1 ~]# kubectl explain pods.spec.containers.livenessProbe.tcpSocket
KIND: Pod
VERSION: v1
RESOURCE: tcpSocket
DESCRIPTION:
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
TCPSocketAction describes an action based on opening a socket
FIELDS:
host
Optional: Host name to connect to, defaults to the pod IP.
port
Number or name of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
那么我么来看一个httpGet的方式探测 :
[root@server1 ~]# kubectl explain pods.spec.containers.livenessProbe.httpGet
KIND: Pod
VERSION: v1
RESOURCE: httpGet
DESCRIPTION:
HTTPGet specifies the http request to perform.
HTTPGetAction describes an action based on HTTP Get requests.
FIELDS:
host
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
Path to access on the HTTP server.
port
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
Scheme to use for connecting to the host. Defaults to HTTP.
那么下面演示一下基于httpGet的探测 :
[root@server1 ~]# 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
periodSeconds: 3
[root@server1 ~]# kubectl create -f liveness-httpget.yaml
pod/liveness-httpget-pod created
[root@server1 ~]# kubectl describe pods liveness-httpget-pod
那么在探测的过程发现并没有重启的记录说明,httpGet的探测中并没有失败
State: Running
Started: Sun, 05 May 2019 13:21:01 +0800
Ready: True
Restart Count: 0
Liveness: http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
Environment:
那么下来我们手动的将器中的/index.html的页面删除,然后进行查看探测有没有问题
[root@server1 ~]# kubectl exec -it liveness-httpget-pod -- /bin/sh
/ # rm -rf /usr/share/nginx/html/index.html
/ #
删除完成以后我们再来查看一下探测的结果 ,那么我们就会发现重启机制已经被重启一次了 ,那么探测性的行为就得到了验证
因为容器被重启了,但是index.html的页面在镜像中是存在的,所以在我们重启之后就会发现这个index的页面,那么容器的机制会恢复正常,并且在重启的时候我们发现刚刚交互的shell界面就会断开了 。
[root@server1 ~]# kubectl describe pods liveness-httpget-pod
Finished: Sun, 05 May 2019 13:26:52 +0800
Ready: True
Restart Count: 1
Liveness: http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
Environment:
那么交互进入以后就会发现文件被重新恢复了
[root@server1 ~]# kubectl exec -it liveness-httpget-pod -- /bin/sh
/ # ls /usr/share/nginx/html/
50x.html index.html
/ # ls /usr/share/nginx/html/
50x.html index.html
下来我们说一下就绪性探测的作用以及如何在参数中参加就绪性探测
在k8s中众多的pod对象会被封装到同一个service中进行统一的访问入口的接入,那么对于service而言,统一的访问入口的接入在于一组pod对象,那么对于新添加的pod对象而言,假如不做就绪性探测,那么用户的请求可能就会被接入器中,但其访问的接口的服务还没有准备好,那么对用户就会返回大量的不可达或者失败的请求,这样对用户的体验极其不好,那么就绪性探测的必要也是很重要的。
就绪性探测类似于存活性探测,只是其参数稍微略有不同 那么下来我们写一下文件:
[root@server1 ~]# 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
periodSeconds: 3
[root@server1 ~]# kubectl create -f readiness-httpget.yaml
pod/readiness-httpget-pod created
[root@server1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client 0/1 Error 0 1d
myapp-848b5b879b-lj66h 1/1 Running 2 1d
myapp-848b5b879b-tbnjb 1/1 Running 2 1d
myapp-848b5b879b-tl78s 1/1 Running 2 1d
nginx-deploy-5b595999-stvlq 1/1 Running 2 1d
pod-demo 2/2 Running 6 18h
readiness-httpget-pod 1/1 Running 0 7s
那么我们采用交互式的方式删除其中的文件查看其是否存在就绪
[root@server1 ~]# kubectl exec -it readiness-httpget-pod -- /bin/sh
/ # ls
bin etc lib mnt root sbin sys usr
dev home media proc run srv tmp var
/ # rm -rf /usr/share/nginx/html/index.html
就会发现这个容器当前并不处于READY的状态,那么在service中就不会被调度
[root@server1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client 0/1 Error 0 1d
myapp-848b5b879b-lj66h 1/1 Running 2 1d
myapp-848b5b879b-tbnjb 1/1 Running 2 1d
myapp-848b5b879b-tl78s 1/1 Running 2 1d
nginx-deploy-5b595999-stvlq 1/1 Running 2 1d
pod-demo 2/2 Running 6 18h
readiness-httpget-pod 0/1 Running 0 2m
那么当我们重新创建一个文件的时候,就会发现就绪的状态会立马得到恢复
/ # echo "hello world " > /usr/share/nginx/html/index.html
[root@server1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client 0/1 Error 0 1d
myapp-848b5b879b-lj66h 1/1 Running 2 1d
myapp-848b5b879b-tbnjb 1/1 Running 2 1d
myapp-848b5b879b-tl78s 1/1 Running 2 1d
nginx-deploy-5b595999-stvlq 1/1 Running 2 1d
pod-demo 2/2 Running 6 18h
readiness-httpget-pod 1/1 Running 0 3m
那么探测性的就到此为止了,现在我们来看一下pod生命周期中的另外的几个行为启动前钩子和终止前钩子
[root@server1 ~]# kubectl explain pods.spec.containers.lifecycle
KIND: Pod
VERSION: v1
RESOURCE: lifecycle
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
preStop
那么对于启动前的我们可以看到其方式 : 支持三种方式
[root@server1 ~]# kubectl explain pods.spec.containers.lifecycle.postStart
KIND: Pod
VERSION: v1
RESOURCE: postStart
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
httpGet
tcpSocket
那么对于preStop 也存在一些的方式和方法
[root@server1 ~]# kubectl explain pods.spec.containers.lifecycle.preStop
KIND: Pod
VERSION: v1
RESOURCE: preStop
DESCRIPTION:
PreStop is called immediately before a container is terminated. The
container is terminated after the handler completes. The reason for
termination is passed to the handler. Regardless of the outcome of the
handler, the container is eventually terminated. 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
httpGet
tcpSocket
那么下来我么演示一下怎么定义一个postStart
apiVersion: v1
kind: Pod
metadata:
name: poststart-pod
namespace: default
spec:
containers:
- name: busybox-httpd
image: busybox:latest
imagePullPolicy: IfNotPresent
lifecycle:
postStart: 注意:command执行的先后顺序,在container内部的话 command 是先执行的然后才在lifcycle中执行
exec: 最开始的cmd没有执行成功,那么在后续就不会执行lifecycle中的cmd
command: ['bin/sh','-c','echo Home_Page >> /tmp/index.html']
command: ["bin/httpd"]
args: ["-f","-h /tmp"]