当前位置:   article > 正文

Kubernetes中Pod的生命周期、重启策略_kubectl 重启pod

kubectl 重启pod

Kubernetes中Pod的生命周期、重启策略

1、Pod生命周期和重启策略

Pod 在整个生命周期中被系统定义为各种状态,熟悉 Pod 的各种状态对于理解如何设置 Pod 的调度策略、重启策

略是很有必要的,Pod 的状态如表所示。

在这里插入图片描述

Pod的重启策略(RestartPolicy)应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和

重启操作。当某个容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 的设置来进行相应的操作。

Pod的重启策略包括 AlwaysOnFailureNever,默认值为 Always

  • Always:当容器失效时,由 kubelet 自动重启该容器。

  • OnFailure:当容器终止运行且退出码不为0时,由 kubelet 自动重启该容器。

  • Never:不论容器运行状态如何,kubelet 都不会重启该容器。

kubelet 重启失效容器的时间间隔以 sync-frequency 乘以 2n 来计算,例如1、2、4、8倍等,最长延时 5min,

并且在成功重启后的 10min 后重置该时间。

Pod 的重启策略与控制方式息息相关,当前可用于管理 Pod 的控制器包括 ReplicationController、Job、

DaemonSet 及直接通过 kubelet 管理(静态Pod)。每种控制器对 Pod 的重启策略要求如下。

  • RC和DaemonSet:必须设置为 Always,需要保证该容器持续运行。

  • Job:OnFailure 或 Never,确保容器执行完成后不再重启。

  • kubelet:在 Pod 失效时自动重启它,不论将 RestartPolicy 设置为什么值,也不会对 Pod 进行健康检查。

结合 Pod 的状态和重启策略,下表列出一些常见的状态转换场景。

在这里插入图片描述

2、Pod健康检查和服务可用性检查

Kubernetes 对 Pod 的健康状态可以通过两类探针来检查:LivenessProbe 和 ReadinessProbe,kubelet 定期

执行这两类探针来诊断容器的健康状况。

(1)LivenessProbe 探针:用于判断容器是否存活(Running状态),如果 LivenessProbe 探针探测到容器不健

康,则 kubelet 将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含 LivenessProbe 探

针,那么 kubelet 认为该容器的 LivenessProbe 探针返回的值永远是 Success

(2)ReadinessProbe 探针:用于判断容器服务是否可用(Ready状态),达到 Ready 状态的 Pod 才可以接收请

求。对于被 Service 管理的 Pod,Service 与 Pod Endpoint 的关联关系也将基于 Pod 是否 Ready 进行设置。如

果在运行过程中 Ready 状态变为 False,则系统自动将其从 Service 的后端 Endpoint 列表中隔离出去,后续再把

恢复到 Ready 状态的 Pod 加回后端 Endpoint 列表。这样就能保证客户端在访问 Service 时不会被转发到服务不

可用的 Pod 实例上。

LivenessProbe 和 ReadinessProbe 均可配置以下三种实现方式。

(1)ExecAction:在容器内部执行一个命令,如果该命令的返回码为0,则表明容器健康。

在下面的例子中,通过执行 cat /tmp/health 命令来判断一个容器运行是否正常。在该 Pod 运行后,将在创建

/tmp/health 文件 10s 后删除该文件,而 LivenessProbe 健康检查的初始探测时间(initialDelaySeconds)为

15s,探测结果是 Fail,将导致 kubelet 杀掉该容器并重启它。

配置文件 013-livenessprobe-exec.yaml 的内容为:

# exec
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/health
      initialDelaySeconds: 15
      timeoutSeconds: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
[root@master cha3]# kubectl create -f 013-livenessprobe-exec.yaml
pod/liveness-exec created
  • 1
  • 2
[root@master cha3]# kubectl get pod liveness-exec
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   0          28s
  • 1
  • 2
  • 3

发现进行了重启,因为初始探测时健康检测文件已经被删除,所以检测到的状态是不正常的,所以会进行重启,再

次查看发现会不断进行重启:

[root@master cha3]# kubectl get pod liveness-exec
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   1          2m59s
  • 1
  • 2
  • 3
[root@master cha3]# kubectl get pod liveness-exec
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   5          7m27s
  • 1
  • 2
  • 3

(2)TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检查,如果能够建立 TCP 连接,则表明容器健

康。

在下面的例子中,通过与容器内的 localhost:80 建立 TCP 连接进行健康检查。

配置文件 014-livenessprobe-tcpsocket.yaml 的文件内容为:

# tcpsocket
apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcpsocket
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 30
      timeoutSeconds: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
[root@master cha3]# kubectl create -f 014-livenessprobe-tcpsocket.yaml
pod/liveness-tcpsocket created
  • 1
  • 2
[root@master cha3]# kubectl get pod liveness-tcpsocket
NAME                 READY   STATUS    RESTARTS   AGE
liveness-tcpsocket   1/1     Running   0          23s
  • 1
  • 2
  • 3

(3)HTTPGetAction:通过容器的 IP 地址、端口号及路径调用 HTTP Get 方法,如果响应的状态码大于等于200

且小于 400,则认为容器健康。

在下面的例子中,kubelet 定时发送 HTTP 请求到 localhost:80/_status/healthz来进行容器应用的健康检

查。

配置文件 015-livenessprobe-http.yaml 的内容为:

# http
apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /_status/healthz
        port: 80
      initialDelaySeconds: 30
      timeoutSeconds: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
[root@master cha3]# kubectl create -f 015-livenessprobe-http.yaml
pod/liveness-http created
  • 1
  • 2
[root@master cha3]# kubectl get pod liveness-http
NAME            READY   STATUS    RESTARTS   AGE
liveness-http   1/1     Running   0          19s
  • 1
  • 2
  • 3

由于该 HTTP 请求返回有问题,所以 pod 也会一直重启:

[root@master cha3]# kubectl get pod liveness-http
NAME            READY   STATUS    RESTARTS   AGE
liveness-http   1/1     Running   3          4m21s
  • 1
  • 2
  • 3

对于每种探测方式,都需要设置 initialDelaySecondstimeoutSeconds 两个参数,它们的含义分别如下。

  • initialDelaySeconds:启动容器后进行首次健康检查的等待时间,单位为s。

  • timeoutSeconds:健康检查发送请求后等待响应的超时时间,单位为s。当超时发生时,kubelet 会认为容

    器已经无法提供服务,将会重启该容器。

Kubernetes 的 ReadinessProbe 机制可能无法满足某些复杂应用对容器内服务可用状态的判断,所以

Kubernetes 从 1.11 版本开始,引入Pod Ready++ 特性对 Readiness 探测机制进行扩展,在 1.14 版本时达到

GA稳定版,称其为 Pod Readiness Gates

通过Pod Readiness Gates机制,用户可以将自定义的 ReadinessProbe 探测方式设置在 Pod 上,辅助

Kubernetes 设置 Pod 何时达到服务可用状态(Ready)。为了使自定义的 ReadinessProbe 生效,用户需要提供一

个外部的控制器(Controller)来设置相应的 Condition 状态。

Pod的 Readiness Gates 在 Pod 定义中的 ReadinessGate 字段进行设置。下面的例子设置了一个类型为

www.example.com/feature-1 的新 Readiness Gate

kind: Pod
......
spec:
  readinessGates:
    - conditionType: "www.example.com/feature-1"
status:
  conditions:
    # Kubernetes系统内置的名为Ready的Condition
    - type: Ready
      status: "True"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
    # 用户自定义Condition
    - type: "www.example.com/feature-1"
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2019-03-01T00:00:00Z
  containerStatuses:
    - containerID: docker://abcd...
      ready: true
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

新增的自定义 Condition 的状态 status 将由用户自定义的外部控制器设置,默认值为 False。Kubernetes将在判

断全部 readinessGates 条件都为 True 时,才设置 Pod 为服务可用状态(Ready为True)。

用法示例:

如下设置了一个类型为 www.example.com/feature-1 的新 Readiness Gates

配置文件 016-readinessgates.yaml 的内容为:

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: centos
  name: centos
  namespace: default
spec:
  containers:
  - args:
    - sleep
    - 10d
    image: centos
    imagePullPolicy: Always
    name: centos
  readinessGates:
    - conditionType: "www.example.com/feature-1"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
[root@master cha3]# kubectl create -f 016-readinessgates.yaml
pod/centos created
  • 1
  • 2
# READINESS GATES 为 0/1
[root@master cha3]# kubectl get pods centos -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
centos   1/1     Running   0          21s   10.244.140.203   slave1   <none>           0/1
  • 1
  • 2
  • 3
  • 4
[root@master cha3]# kubectl get pod centos -o json | jq .status.conditions
[
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:25Z",
    "status": "True",
    "type": "Initialized"
  },
  # readinessGates
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:25Z",
    "message": "corresponding condition of pod readiness gate \"www.example.com/feature-1\" does not exist.",
    "reason": "ReadinessGatesNotReady",
    "status": "False",
    "type": "Ready"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:43Z",
    "status": "True",
    "type": "ContainersReady"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:25Z",
    "status": "True",
    "type": "PodScheduled"
  }
]
  • 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

apply 后查看 Ready condition 是 false,如果设置有 endpoint,也不会出现在 endpoint 列表里。如果要想容器

正常提供服务,就需要将对应的 conditionType 设置为 true。

通俗的来讲就是设置 readinessGates 字段,然后将对应的 condition 通过 patch 操作设置为 true。

注意 kubectl 是无法通过 patch 更改 status 里面的字段的。

由于状态字段不能通过 kubectl 命令进行修改,所以只能使用 API 的方式修改。

[root@master ~]# kubectl proxy
Starting to serve on 127.0.0.1:8001
# 或者
[root@master ~]# kubectl proxy --accept-hosts=".*" --address=0.0.0.0
Starting to serve on [::]:8001
  • 1
  • 2
  • 3
  • 4
  • 5
# curl 直接调用
[root@master ~]# curl http://localhost:8001/api/v1/namespaces/default/pods/centos/status -X PATCH -H "Content-Type: application/json-patch+json" -d '[{"op": "add", "path": "/status/conditions/-", "value": {"type": "www.example.com/feature-1", "status": "True", "lastProbeTime": null}}]'
  • 1
  • 2
# 查看执行结果
kubectl get pods centos -o json | jq .status.conditions
[ 
  # readinessGates
  {
    "lastProbeTime": null,
    "lastTransitionTime": null,
    "status": "True",
    "type": "www.example.com/feature-1"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:25Z",
    "status": "True",
    "type": "Initialized"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:32:48Z",
    "status": "True",
    "type": "Ready"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:43Z",
    "status": "True",
    "type": "ContainersReady"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2023-07-02T10:31:25Z",
    "status": "True",
    "type": "PodScheduled"
  }
]
  • 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
# READINESS GATES 为 1/1
[root@master cha3]# kubectl get pods centos -o wide                                                        NAME     READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
centos   1/1     Running   0          2m    10.244.140.203   slave1   <none>           1/1
  • 1
  • 2
  • 3

可以看到此时容器状态已经正常了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/652531
推荐阅读
  

闽ICP备14008679号