kubernetes Pod 控制器器应用进阶

实现容器探测的几种方式:   探针类型有三种:    ExecAtion     TCPSocketAction    HTTPGetAction   

那么探针针对于存活性来做的话,就是存活性探针,针对就绪来做,就是就绪性探针 

那么 livenessProbe 是做存活性探测 ,存活未必就绪

  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-probes

readinessProbe 是做就绪性探测的 

 readinessProbe    <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.

[root@server1 ~]# kubectl explain pods.spec.containers.livenessProbe

下面是三种定义的探针,那么我们每次定义的时候都定义三种中的一种就可以了

   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

这个字段的意思是,探针在探测的过程中,并不是一开始探测的时候,探测到失败就认为是失败的,那么只有探测3次以上才认为它是失败的。

   failureThreshold    <integer>
     Minimum consecutive failures for the probe to be considered failed after
     having succeeded. Defaults to 3. Minimum value is 1.

这个字段表示探测的生命周期,也就是间隔多长时间进行探测一次 ,默认是10秒探测一次

   periodSeconds    <integer>
     How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
     value is 1.

那么在探测的时候始终没有响应应该等多久,默认是等待的1秒钟

 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

因为容器在启动的时候是需要进行初始化的,因此在初始化期间是不能被探测的,那么在初始化的这个时间段,我们延迟探测的时间,因此我们要定义这个时间段在容器初始化完成后进行探测,那么如果不定义的话,那么默认的情况下是容器一启动就会进行探测,那么容器启动并不代表主进程可以对外服务了 

   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

那么下来写一个探测性的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:  <none>
Node:               server3/172.25.254.3
Start Time:         Sun, 05 May 2019 12:51:52 +0800
Labels:             <none>
Annotations:        <none>
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:    <none>

.................

做了livenessProbe的探测之后,就会发现pod对象会被重启,当探测不到或者失败时默认使用的重启策略会将pod内的容器重启,但是重启时候并不总是重启,第一次重启可能是立即的第二次可能就是10s后第三次可能就是30s。。。

那么上述的探测就是exec的探测方式,在exec探测的时候就是使用相应的命令在容器内进行探测

下来我们看一下如何对一个web的服务器做探测,探测器中的服务的请求等等之类的 ,下面演示使用tcpSocket做探测

[root@server1 ~]# kubectl explain pods.spec.containers.livenessProbe.tcpSocket
KIND:     Pod
VERSION:  v1

RESOURCE: tcpSocket <Object>

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    <string>
     Optional: Host name to connect to, defaults to the pod IP.

   port    <string> -required-
     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 <Object>

DESCRIPTION:
     HTTPGet specifies the http request to perform.

     HTTPGetAction describes an action based on HTTP Get requests.

FIELDS:
   host    <string>       向哪个主机发请求,默认就是容器的IP
     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>    << url >>     向哪个url发请求 
     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.

那么下面演示一下基于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:    <none>

那么下来我们手动的将器中的/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:    <none>

那么交互进入以后就会发现文件被重新恢复了 

[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 <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. 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


那么对于启动前的我们可以看到其方式 :  支持三种方式 

[root@server1 ~]# 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

那么对于preStop 也存在一些的方式和方法

[root@server1 ~]# kubectl explain pods.spec.containers.lifecycle.preStop
KIND:     Pod
VERSION:  v1

RESOURCE: preStop <Object>

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    <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

那么下来我么演示一下怎么定义一个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"]
 

猜你喜欢

转载自blog.csdn.net/qq_42339633/article/details/89841737