Pod重启策略和健康检查

使用Kubernetes的主要好处之一是它具有管理和维护集群中容器的能力,几乎可以提供服务零停机时间的保障。在创建一个Pod资源后,Kubernetes会为它选择worker节点,然后将其调度到节点上运行Pod里的容器。Kubernetes强大的功能可使应用程序的容器保持连续运行,还可以根据需求的增长自动扩展系统。除此之外在Pod或容器出现故障时Kubernetes还可以让系统实现"自愈"。在本文中,我们将介绍如何使用Kubernetes内置的livenessProbe和readinessProbe来管理和控制应用程序的运行状况。

Pod的重启策略

Kubernetes自身的系统修复能力有一部分是需要依托Pod的重启策略的, 重启策略也叫restartPolicy。它是Pod 的Spec部分的一个标准字段(pod.spec.restartPolicy),默认值是Always,即:任何时候这个容器发生了异常,它一定会被重新创建。

可以通过设置 restartPolicy,改变 Pod 的恢复策略。除了 Always,它还有 OnFailure 和 Never 两种情况。

  • Always:在任何情况下,只要容器不在运行状态,就自动重启容器;
  • OnFailure: 只在容器 异常时才自动重启容器;
  • Never: 从来不重启容器。

在实际使用时,我们需要根据应用运行的特性,合理设置这三种恢复策略。

对于包含多个容器的 Pod,只有它里面所有的容器都进入异常状态后,Pod 才会进入 Failed 状态。在此之前,Pod 都是 Running 状态。此时,Pod 的 READY 字段会显示正常容器的个数,比如:

$ kubectl get pod test-liveness-exec
NAME           READY     STATUS    RESTARTS   AGE
liveness-exec   0/1       Running   1          1m

如果一个 Pod 里只有一个容器,然后这个容器异常退出了。那么,只有当 restartPolicy=Never 时,这个 Pod 才会进入 Failed 状态。而其他情况下,由于 Kubernetes 都可以重启这个容器,所以 Pod 的状态保持Running 不变,RESTARTS信息统计了Pod的重启次数。需要注意的是:虽然是重启,但背后其实是Kubernetes用重新创建的容器替换了旧容器。

Pod怎么实现自我修复?

将Pod调度到某个节点后,该节点上的Kubelet将运行其中的容器,并在Pod的生命周期内保持它们的运行。如果容器的主进程崩溃,kubelet将重新启动容器。但是,如果容器内的应用程序抛出错误导致其不断重启,则Kubernetes可以通过使用正确的诊断程序并遵循Pod的重启策略来对其进行修复。

Kubernetes可以对两种健康检查做出应对:

  • Liveness:活性检查,kubelet使用活性探针(livenessProbe)的返回状态作为重新启动容器的依据。一个Liveness探针用于在应用运行时检测容器的问题。容器进入此状态后,Pod所在节点的kubelet可以通过Pod策略来重启容器。

  • Readiness:就绪检查,这种类型的探测(readinessProbe)用于检测容器是否准备好接受流量。你可以使用这种探针来管理哪些Pod会被用作服务的后端。如果Pod尚未准备就绪,则将其从服务的后端列表中删除。

Kubernetes把放在Pod里的健康检查处理程序叫做探针(Probe),比喻成医学手术上探测病变的探针,还是很形象的。

探针处理程序

为了使健康检查能够对Pod的运行状况进行诊断,kubelet会调用容器中为探针实现的处理程序,这些处理程序分为三大类:

  • Exec:在容器内执行命令。
  • TCPSocket:对指定端口上,容器的IP地址执行TCP检查。
  • HTTPGet:在容器的IP上执行HTTP GET请求。

处理程序的返回状态也分为三种:

  • Success:容器通过诊断。
    Failed:容器无法通过诊断。
    Unknown:诊断失败,状态不确定,将不采取任何措施。
    聊完了探针程序的种类和返回值接下来我们来了解一下这两种探针的使用案例。

使用案例
活性和就绪探针都在Pod的YAML文件中配置。每种类型都有不同的用例。

livenessProbe

如前所述,活性探针用于诊断不健康的容器。他们可以在服务无法继续进行时检测到服务中的问题,并会根据其重启策略重启有问题的容器,期望通过这种方式来解决服务的问题。

例如,在容器内包含一个Exec活性探针,以检测应用程序何时转换为Broken状态。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

这个YAML定义一个单容器的Pod。它表示kubelet在容器启动完成后5秒进行第一次健康检查(initialDelaySeconds:5),之后每5秒都会执行一次检查(periodSeconds: 5)。kubelet在容器中执行命令"cat/tmp/healthy",如果成功,则返回0,指示它是健康的。如果返回非零值,则kubelet将kill掉该容器并重新启动它。

这个例子是官方教程里给的,除了在容器中执行命令外,发起 HTTP 或者 TCP 请求的livenessProbe,教程里也给出了示例:

    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
...
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

在官方教程里可以找到更多示例,链接:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

readinessProbe

就绪探针与活性探针(GET请求,TCP连接和命令执行)进行相同类型的检查。但是,纠正措施有所不同。它不会重启未通过检查的容器的Pod,而是从Service上摘除Pod,暂时将其与流量隔离。

比如,有一个Pod可能正在做大量计算或正在进行繁重的操作,从而增加了服务的响应延迟。让我们定义一个就绪探针,通过探针的timeoutSeconds参数定义超过两秒响应GET请求的Pod的状态为非健康状态

apiVersion: v1
kind: Pod
metadata:
 name: nodedelayed
spec:
 containers:
   - image: k8s.gcr.io/liveness
     name: liveness
     ports:
       - containerPort: 8080
         protocol: TCP
     readinessProbe:
       httpGet:
         path: /
         port: 8080
       timeoutSeconds: 2

当探测响应时间超过两秒钟时,kubelet不会重新启动Pod,而是将流量路由到其他健康的Pod上。等到Pod不再过载后,kubelet会将Pod重新加回到原来的Service中。

总结

默认情况下,Kubernetes提供两种健康检查:readinessProbe 和 livenessProbe。它们都使用相同类型的探针处理程序(HTTP GET请求,TCP连接和命令执行)。他们对未通过检查的Pod做出的纠错措施有所不同。livenessProbe将重新启动容器,预期重启后错误不再发生。readinessProbe会将Pod与流量隔离,直到故障原因消失。

通过在同一个Pod中使用这两种健康检查,可以确保流量不会到达尚未准备就绪的Pod,并且确保Pod在发生故障时能重新启动。

良好的应用程序设计应同时记录足够的信息,尤其是在引发异常时。它还应公开必要的API端点,这些端点将会传达重要的运行状况和状态指标,以供监控系统(如Prometheus)使用。

参考链接:
kubernetes-best-practices-health-probes[1]

liveness-and-readiness-probes-in-kubernetes[2]

参考资料

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容