K8s之Pod的健康检查

前言

Pod的探测用于检测容器中的应用实例是否可以正常的工作。如果不能正常工作应该去重启,或者不将流量引入该实例。K8s给我们提供了三种探测方式。

LivenessProbe,ReadinessProbe,StartupProbe

可以通过官网查看 https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#container-probes

Pod的重启策略

在讲解探针之前先了解下Pod的重启策略。Pod的重启策略包括三种,Always,OnFailure和 Never 默认就是 Always

  • Always: 当容器不能正常工作时,kubelet会自动重启该容器
  • OnFailure: 当容器终止运行且退出码不为0时,由kubelet自动启动该容器。
  • Never: 不论容器运行状态如何,都不重启。

如果容器重启之后还是不可用需要继续重启。为了不频繁重启,K8s给重启时间间隔设置了规律,每次间隔时间乘以2,最长达到五分钟。成功重启后的十分钟后重置时间间隔

重启策略与Pod控制器关系

重启策略跟Pod控制器有着莫大的关联

  • 对于RC、RS、Deployment、DaemonSet 就得设置 Always
  • 对于 Job 设置为OnFailure或者Never,确保容器执行完成后不再重启
  • Kubelet:与重启策略无关。Pod失效自动重启。

探针的检查机制

常用的检查方式有三种

  • exec 通过命令执行的方式检测,我们知道linux的一条命令执行成功返回的状态是 0,exec 也是根据命令执行返回的状态码是不是0来表示服务是否存活
  • httpGet 通过一个http请求访问,如果响应的状态码大于等于 200 且小于 400 ,表示服务正常
  • tcpSocket 对容器指定的端口进行Tcp检查,如果端口能打开,表示成功。

LivenessProbe

探测容器是否正在运行(Running),如果探测失败,Kubelet将会杀死该容器,然后根据容器的重启策略判断是否需要重启,如果没有提供该类探针,默认返回Success

下面使用 exec 来演示LivenessProbe的使用(每种检查机制都可以使用),创建 kube-nginx.yml 内容如下

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent  #用于设置镜像拉取策略
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      exec: # exec方式
        command:
        - cat
        - /root/livenessProbe.txt
      initialDelaySeconds: 10 # 容器启动后多长时间开始探测
      timeoutSeconds: 1 # 探测超时时间
      failureThreshold: 1 # 连续出现多少次失败后认为是不可用,默认3
      periodSeconds: 1 # 1秒钟探测一次,默认10

启动,观察Pod状态

[root@master probe]# kubectl apply -f kube-nginx.yml 
pod/nginx created
# 查看Pod
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          9s
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   1 (1s ago)   11s
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   2 (2s ago)   22s
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   3 (1s ago)   31s
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS             RESTARTS     AGE
nginx   0/1     CrashLoopBackOff   3 (1s ago)   41s

# 查看nginx的创建过程
[root@master probe]# kubectl describe  pod nginx|grep -A 100 Events
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  14s               default-scheduler  Successfully assigned default/nginx to node01
  Normal   Pulled     2s (x2 over 13s)  kubelet            Container image "nginx" already present on machine
  Normal   Created    2s (x2 over 13s)  kubelet            Created container nginx
  Normal   Started    2s (x2 over 13s)  kubelet            Started container nginx
  Warning  Unhealthy  2s                kubelet            Liveness probe failed: cat: /root/livenessProbe.txt: No such file or directory
  Normal   Killing    2s                kubelet            Container nginx failed liveness probe, will be restarted
分析

从上面查看Pod的情况来看, Liveness probe failed 原因是文件不存在,然后接着就是重启nginx

Container nginx failed liveness probe, will be restarted

观察Pod RESTARTS的时间,由于我们都是设置的1,容器启动后10秒中开始探测,立马探测失败于是重启。所以大概每10秒钟就会看到重启一次,重启三次后状态变为 CrashLoopBackOff

CrashLoopBackOff 本身并不是一个错误 ,只是说由于我们循环重启造成的,等待一段时间,容器又会变为Running

解决

既然是没有找到这个文件造成的,那么我们手动创建一个。delete该容器,重新启动。10秒后我们手动创建文件 /root/livenessProbe.txt 再次观察容器状态。

[root@master probe]# kubectl create -f kube-nginx.yml              
pod/nginx created
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS     AGE
nginx   1/1     Running   1 (2s ago)   13s
[root@master probe]# kubectl exec nginx -- touch /root/livenessProbe.txt
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS      AGE
nginx   1/1     Running   1 (14s ago)   25s
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS      AGE
nginx   1/1     Running   1 (76s ago)   87s

从上面结果可以看出,刚开始由于没有该文件探测失败,造成RESTARTS,后面手动创建后就再也没RESTARTS了

ReadinessProbe

表示服务是否已经是就绪状态(Ready),可不可以对外提供服务。一样的如果没有配置永远返回Success,上面例子我们没有配置,可以看到READY立马就是1/1 。

下面使用tcpSocket方式(每种检查机制都可以使用)来应用 readinessProbe,修改 kube-nginx.yml 内容如下

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent  #用于设置镜像拉取策略
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    readinessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 20 # 容器启动后多长时间开始探测
      timeoutSeconds: 1 # 探测超时时间

启动

[root@master probe]# kubectl apply -f kube-nginx.yml
pod/nginx created
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   0/1     Running   0          12s
[root@master probe]# kubectl get pod nginx                         
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          34s

与LivenessProbe不同的是 ReadinessProbe 对Pod 的处置方式不同 LivenessProbe 探测失败希望的是重启Pod,ReadinessProbe失败后 kube-proxy 就不会把流量引入此Pod并且从对应的 EndPoint 列表中删除,如果Pod恢复为Ready,再重新添加回来,生产上一般两者都配置,探测可以一样。

StartupProbe

在1.6版本之后加入的,主要是解决上面两种探测存在的问题,比如一个服务启动需要六十秒,那么上面的探测就会失败很多次导致重启,重启还是需要60秒才能起好,然后又是探测失败,这样就陷入了循环,虽然可以使用initialDelaySeconds来表示容器启动后多久才开始探测,但是万一下次启动需要100秒呢。那么你的initialDelaySeconds timeoutSeconds periodSeconds又该怎么设计呢。而且ReadinessProbe是一直需要探测的,最好这些参数不要设置的过大,不然服务宕掉了不能及时发现。

总之使用前面两种探测,经过调试其实也可以满足需求。只是复杂程序中没那么好用。

所以K8s就设计出了StartupProbe。

三个探针都存在时先执行StartupProbe,其它两个为禁用状态 直到StartupProbe成功,其他两个探测才开始。StartupProbe满足一次后便不再执行。

下面我们来使用一下StartupProbe,相信你会体会到它的好处 修改kube-nginx.yml内容如下

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent  #用于设置镜像拉取策略
    ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP
    livenessProbe:
      httpGet:
        path: /data.html
        port: 80
      timeoutSeconds: 1 # 探测超时时间
      failureThreshold: 1 # 连续出现多少次古装后认为是失败,默认3
      periodSeconds: 1 # 1秒钟探测一次,默认10
    readinessProbe:
      httpGet:
        path: /data.html
        port: 80
      timeoutSeconds: 1 # 探测超时时间
      failureThreshold: 1 # 连续出现多少次古装后认为是失败,默认3
      periodSeconds: 1 # 1秒钟探测一次,默认10
    startupProbe:
      httpGet:
        path: /data.html
        port: 80
      failureThreshold: 300 # 连续出现多少次失败后认为是不可用,默认3
      periodSeconds: 2 # 2秒钟探测一次,默认10

这里我们可以将连续失败数设置大一点但是探测间隔设置小一点,那么只要服务启动成功就会立马探测到,从而启用readinessProbe与livenessProbe。如果说换做是livenessProbe配置这样的参数,那服务挂了都探测不出来。

下面启动该Pod,观察状态。

[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   0/1     Running   0          34s
[root@master probe]# kubectl exec nginx -- touch /usr/share/nginx/html/data.html
[root@master probe]# kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          37s

从上面可以看出,34秒时还是失败,我们立马创建请求需要的文件data.html,再次查看发现服务已经正常了。也体现出来服务一旦启用成功会立刻执行readinessProbe探测。

Pod的健康检查就介绍到这里。下期介绍Pod的生命周期。


欢迎关注,学习不迷路!

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

推荐阅读更多精彩内容