Kubernetes 深入Pod


Pod声明周期和重启策略

Pod在整个生命周期过程中被系统定义为各种状态

状态值 描 述
Pending API Server已经创建该Pod,但Pod内还有一个或多个容器的镜像没有创建成功,包括正在下载的镜像的过程
Running Pod内所有容器均已创建,且至少有一个容器处于运行状态、正在启动或正在重启状态
Succeeded Pod内所有容器均已成功执行退出,且不会再重启
Failed Pod内所有容器均已退出,但至少有一个容器退出为失败状态
Unknown 由于某种原因无法获取该Pod的状态,可能由于网络通信不畅导致

Pod重启策略 Pod重启策略RestartPolicy应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某个容器异常退出或者健康检查失败时,kubelet将根据RestartPolicy的设置来进行相应的操作。

Pod的重启策略包括Always、OnFailure和Never,默认值为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进行健康检查

常见状态转换 -w726

Pod 健康检查

对Pod的健康状态检查可以通过两类探针来检查:LivenessProbeReadinessProbe

1.LivenessProbe探针

用于判断容器是否存活(Running状态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含你LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是 "Success"

2.ReadinessProbe探针

用于判断容器是否完成(Ready状态),可以接收请求。如果ReadinessProbe探针检测到失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在的Pod的Endpoint

探针配置参数说明

探针参数 说明
initialDelaySeconds 启动活动或准备就绪探测之前容器启动后的秒数
periodSeconds 执行探测的频率(以秒为单位)。默认为10秒。最小值为1
timeoutSeconds 探测超时的秒数。默认为1秒。最小值为1
successThreshold 失败后探测成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。
failureThreshold Pod启动并且探测器失败时,Kubernetes会failureThreshold在放弃之前尝试一次。在活动探测的情况下放弃意味着重新启动Pod。如果准备好探测,Pod将被标记为未准备好。默认为3.最小值为1

Http探针配置

Http Get 说明
host 要连接的主机名,默认为pod IP。您可能希望在httpHeaders中设置“主机”
scheme 用于连接主机(HTTP或HTTPS)的方案。默认为HTTP
path HTTP服务器上的访问路径
httpHeaders 要在请求中设置的自定义标头。HTTP允许重复标头
port 容器上要访问的端口的名称或编号。数字必须在1到65535的范围内

对于HTTP探测,kubelet将HTTP请求发送到指定的路径和端口以执行检查。kubelet将探测器发送到pod的IP地址,除非地址被可选host字段覆盖httpGet。如果 scheme字段设置为HTTPS,则kubelet会发送跳过证书验证的HTTPS请求。在大多数情况下,您不希望设置该host字段。这是您设置它的一个场景。假设Container侦听127.0.0.1并且Pod的hostNetwork字段为true。然后host,在httpGet,应设置为127.0.0.1。如果你的pod依赖虚拟主机,这可能是更常见的情况,你不应该使用host,而是设置Host标头httpHeaders

详情请参考官方文档

kubelet定期执行LivenessProbe探针来诊断容器的健康状况。LivenessProbe有以下三种方式

(1) ExecAction

在容器内执行一个命令,如果该命令的返回码为0,则表示容器健康

案例
通过执行"cat /tmp/health" 命令来判断一个容器运行是否正常。而该pod运行之后,在创建/tmp/health文件的10s之后将删除该文件,而LivenessProbe健康检查的初始探测时间(initialDelaySeconds)为15s,探测结果将是Fail,将导致kubelet杀掉该容器并重启它

[root@master test]# cat abcdocker_pod.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: abcdocker-nginx-docker
        image: daocloud.io/library/nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        command: ["/bin/sh", "-c", "echo ok >/tmp/health; sleep 60;rm -rf /tmp/health; sleep 600"]
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/health
          initialDelaySeconds: 15
          timeoutSeconds: 1


=======================分割线======================

initialDelaySeconds   #执行第一次探测之前等待15秒
periodSeconds       #每5秒执行一次活跃度探测

结果演示

kubelet将cat /tmp/healthy在Container中执行命令。如果命令成功,则返回0,并且kubelet认为Container是活动且健康的。如果该命令返回非零值,则kubelet会终止Container并重新启动它。

当Container启动时,它会执行以下命令:

/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600" 对于Container的生命的前30秒,有一个/tmp/healthy文件。因此,在前30秒内,该命令cat /tmp/healthy返回成功代码。30秒后,cat /tmp/healthy返回失败代码。kubelet会将容器杀死并重新创建

-w1100

(2) TCPSocketAction

通过容器的IP地址和端口号执行TCP检查,如果能联立TCP连接,则表示容器健康

TCP检查的配置与HTTP检查非常相似。在容器启动10秒后,kubelet将发送第一个就绪探测器。这将尝试连接到容器端口80上的容器。如果探测成功,则该pod将标记为就绪。kubelet将每10秒继续运行此检查。如果重启探测失败将会新建容器并重新启动

[root@master test]# cat abcdocker_pod.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: abcdocker-nginx-docker
        image: daocloud.io/library/nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        livenessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 1

#参数解释请往上翻阅

测试 因为使用tomcat镜像,默认端口8080,所以80一直无法探测成功 -w1100

(3) HTTPGetAction

通过容器的IP地址、端口号及路径调用HTTP Get方法,如果影响的状态码大于等于200且小于400,则认为容器状态健康。

为了执行探测,kubelet向在Container中运行的服务器发送HTTP GET请求并侦听端口80.如果服务器abcdicjer路径的处理程序返回成功代码,则kubelet认为Container是活动且健康的。如果处理程序返回失败代码,则kubelet会终止Container并重新启动它。

任何大于或等于200且小于400的代码表示成功。任何其他代码表示失败

[root@master test]# cat abcdocker_pod.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: abcdocker-nginx-docker
        image: daocloud.io/library/nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /abcdocker/
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 1

因为请求的abcdocker路径不存在,所以容器报错404并进行重启 -w1100

Pod 调度

在Kubernetes系统中,Pod在大部分场景下都只是容器的载体而已,通常需要Deployment、DaemonSet、RC、Job等对象来完成一组Pod的调度和自动控制功能

1.Deployment/RC:全自动调度

Deployment或RC的主要功能之一就是自动部署一个容器应用的多个副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量

下面是创建一个Deployment配置的例子,使用这个配置文件创建一个ReplicaSet,ReplicasSet (与Replication Controller同名)会创建3个nginx应用的pod

[root@master test]# cat abcdocker_pod.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: abcdocker-nginx-docker
        image: daocloud.io/library/nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

创建流程 由于过于简单,前面也演示过了,这里只看执行结果 -w1100

从调度策略来说,这三个nginx Pod由系统全自动完成调度,它们各自最终运行在哪个节点上,完全由master的schedulet经过一系列的算法得出,用户无法干预调度过程和结果。

除了使用系统自动调度算法完成一组Pod的部署,Kubernetes也提供了丰富的调度策略,用户只需要在Pod的定义中使用NodeSelector NodeAffinity PodAffinity Pod 驱逐等更加细粒的调度策略设置,就能完成对Pod的精准调度。

2.NodeSelector:定向调度

Kubernetes Master上的Scheduler服务(kube-scheduler进程) 负责实现Pod的调度,这个调度过程通过一系列复杂的算法,最终为每个Pod计算出一个最佳的目标节点,这一过程是自动完成的,通常我们无法指定Pod最终会被调度在哪个节点上,在实际强开中,也可以需要将pod调度到指定的一些Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到目的。

(1) 首先通过kubectl label命令给目标Node打赏一些标签
kubectl label nodes [node-name] <label-key>=<label-value>

这里我们使用node节点打上一个abcdocker=aaa的标签
[root@master test]# kubectl label nodes node abcdocker=aaa

上述命令操作也可以通过修改资源定义文件的方式,并执行kubectl replace -f xxx.yaml命令来完成

(2)需要在Pod中定义nodeSelector的配置,我们以Nginx为例

[root@master test]# cat abcdocker_pod.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: abcdocker-nginx-docker
        image: daocloud.io/library/nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
      nodeSelector:
        abcdocker: aaa

###nodeSelector是配置绑定node
abcdocker:aaa 是我们之前创建的标签

我们可以看到现在所有的Pod都在对应的node节点上 -w1096

如果我们给多个Node都定义了相同的标签(例如:abcdocker=aaa),则scheduler将会根据调度算法从这组Node中挑选一个可用的Node进行pod调度

Copyright © i4t.com 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-11-21 16:29:38

results matching ""

    No results matching ""