k8s-探针(四)

k8s-探针(四)

存活探针 (liveness probe)

k8s 可以通过存活探针 (liveness probe) 检查容器是否还在运行。 可以为 pod 中的每个容器单独指定存活探针。如果探测失败, k8s 将定期执行探针并重新启动容器。

三种探测容器的机制

HTTPGET探针对容器的 IP 地址(你指定的端口和路径)执行 HTTP GET 请求。
如果探测器收到响应,并且响应状态码不代表错误(换句话说,如果HTTP响应状态码是2xx或3xx), 则认为探测成功。
如果服务器返回错误响应状态码或者根本没有响应,那么探测就被认为是失败的,容器将被重新启动。

TCP套接字探针尝试与容器指定端口建立TCP连接。如果连接成功建立,则探测成功。否则,容器重新启动。

Exec探针在容器内执行任意命令,并检查命令的退出状态码。如果状态码是0, 则探测成功。所有其他状态码都被认为失败

HTTPGET探针

准备工作

修改app.js程序,让其可以产生连续3次的错误响应

// app.js
const http = require('http');
const os = require('os');

console.log("Kubia server starting...");
var x = 0;
var tmp = 0;
var handler = function(request, response) {
  console.log("Received request from " + request.connection.remoteAddress);
  response.writeHead(200);
        x++;
        tmp = x % 10;
        if (tmp % 7 == 0 || tmp % 8 ==0 || tmp % 9 == 0) {
          response.writeHead(400);
          console.log("error 400");
          response.end();
        } else {
          response.end("You've hit " + os.hostname() + "\n");
        }
};
var www = http.createServer(handler);
www.listen(8080);

使用这个app.js构建出对应的镜像.

[root@node1 kubia-err]# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
kubia-err400               latest              f6427314b863        2 weeks ago         64.6MB
[root@node1 kubia-err]# 

yaml定义

apiVersion: v1
kind: Pod
metadata:
  name: kubia-err400
spec:
  containers:
  - name: kubia-err400
    image: kubia-err400:latest
    imagePullPolicy: Never
    ports:
    - containerPort: 8080
    livenessProbe:                ## 存活探针
      httpGet:
        path: /                   ## 路径
        port: 8080                ## 端口
      initialDelaySeconds: 15     ## 探测延时,容器在启动initialDelaySeconds时长后,开始探测

探针是针对Pod的,所以只需要在Pod上, template.pec处配置,这里测试使用ReplicaSet来测试,用下面的yaml.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kubia-err400
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kubia-err400
  template:
    metadata:
      name: kubia-err400
      labels:
        app: kubia-err400
    spec:
      containers:
      - name: kubia-err400
        image: kubia-err400:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
        livenessProbe:               
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 15

演示

[root@master1 kubeyaml]# vi kubia-err-liveness.yaml 
[root@master1 kubeyaml]# kubectl apply -f kubia-err-liveness.yaml
replicaset.apps/kubia-err400 created
[root@master1 kubeyaml]# kubectl get rs kubia-err400
NAME           DESIRED   CURRENT   READY   AGE
kubia-err400   1         1         1       21m
[root@master1 kubeyaml]#

查看rs的状态

[root@master1 kubeyaml]# kubectl get rs kubia-err400
NAME           DESIRED   CURRENT   READY   AGE
kubia-err400   1         1         0       21m
[root@master1 kubeyaml]# kubectl describe rs kubia-err400
Name:         kubia-err400
Namespace:    default
Selector:     app=kubia-err400
Labels:       <none>
Annotations:  <none>
Replicas:     1 current / 1 desired
Pods Status:  1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=kubia-err400
  Containers:
   kubia-err400:
    Image:        kubia-err400:latest
    Port:         8080/TCP
    Host Port:    0/TCP
    Liveness:     http-get http://:8080/ delay=15s timeout=1s period=10s #success=1 #failure=3
...

除了明确指定的存活探针选项,还可以看到其他属性,例如delay(延迟)、 timeout(超时)、period(周期)等。delay=15s显示在容器启动15s后开始探测。timeout仅设置为1秒,因此容器必须在1秒内进行响应, 不然这次 探测记作失败。每10秒探测一次容器(period=10s), 并在探测连续三次失败 (#failure= 3)后重启容器。

过段时间后再去查看pod

## 容器已经重启了8次,因为我们的app.js有个连续三次失败的逻辑
[root@master1 kubeyaml]# kubectl get po
NAME                 READY   STATUS    RESTARTS   AGE
kubia-err400-q4sr9   1/1     Running   8          26m
[root@master1 kubeyaml]#

查看容器失败原因

[root@master1 kubeyaml]# kubectl describe po kubia-err400-q4sr9
Name:         kubia-err400-q4sr9
Namespace:    default
Priority:     0
Node:         node1.wt.com/192.168.2.15
Start Time:   Mon, 05 Jul 2021 13:59:20 +0800
Labels:       app=kubia-err400
Annotations:  cni.projectcalico.org/podIP: 100.109.35.224/32
Status:       Running
IP:           100.109.35.224
IPs:
  IP:           100.109.35.224
Controlled By:  ReplicaSet/kubia-err400
Containers:
  kubia-err400:
    Container ID:   docker://ee51eba377b5d55f3e060526385c5cdd6f40645f3b68444ad9af384d8ea54480
    Image:          kubia-err400:latest
    Image ID:       docker://sha256:f6427314b863d764356d554660b6fcd0febc9de608b2498cd7e547cff9c90777
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 05 Jul 2021 14:26:41 +0800
    Last State:     Terminated
      Reason:       Error
      Exit Code:    137
      Started:      Mon, 05 Jul 2021 14:24:27 +0800
      Finished:     Mon, 05 Jul 2021 14:26:41 +0800
    Ready:          True
    Restart Count:  9
    Liveness:       http-get http://:8080/ delay=15s timeout=1s period=10s #success=1 #failure=3
...
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
...
[root@master1 kubeyaml]# 

Last State这一栏及后面信息,可以看到,上次终止,Reason=Error,Exit Code=137.这个退出码128+x, 137=128+9(SIGKILL).9的原因是因为我们容器是好的,但是探针探测到之后,需要重启容器,所以直接杀死进程(kill -9)

就绪探针(readiness probe)

Pod可能需要时间来加载配置或数据,或者可能需要执行预热过程以防止第一个用户请求时间太长影响了用户体验。在这种情况下,不希望该Pod立即开始接收请求,尤其是在运行的示例可以正确快速的处理请求的情况下。不要讲请求转发到正在启动的Pod中,直到完全准备就绪。

这个准备就绪的概念显然是每个容器特有的东西。k8s只能检查咋容器中运行的应用程序是否响应一个简单的GET请求,或者他可以响应特定的URL路径(该URL导致应用程序执行一系列检查已确定它是否准备就绪)。

就绪探针类型

像存活探针一样,就绪探针也有三种类型

Exec 探针,执行进程的地方。容器的状态由进程的退出状态代码确定。

HTTP GET 探针,向容器发送 HTTP GET 请求,通过响应的 HTTP 状态代码判断容器是否准备好

TCP socket 探针,它打开一个TCP连接到容器的指定端口。如果连接已建立,则认为容器已准备就绪

介绍

启动容器时,可以为k8s配置一个等待时间,经过等待时间后才可以执行第一次准备就绪检查。之后,它会周期性的调用探针,并根据就绪探针的结果采取行动。如果某个Pod报告它尚未准备就绪,则会从该服务中删除该Pod。如果Pod再次准备就绪,则重新添加Pod。

与存活探针不同,如果容器未通过准备检查,则不会 被终止或重新启动。这是存活探针与就绪探针之间的重要区别。存活探针通过杀死异常的容器,并用新的正常容器替代他们来保持Pod正常工作,而就绪探针确保只有准备好处理请求的Pod才可以接收请求。

如果一个容器的就绪探测失败,则将该Pod从endpoints中移除

jiuxu_pod.png

Exec探针

yaml定义

apiVersion: v1
kind: Pod
metadata:
  name: kubia-err400
spec:
  containers:
  - name: kubia-err400
    image: kubia-err400:latest
    imagePullPolicy: Never
    ports:
    - containerPort: 8080
    readinessProbe:           ## 每个容器都会有一个就绪探针
      exec:
        command:              ## 通过执行命令来检查容器是否正常,便于测试
        - ls
        - /var/ready

就绪探针将定期在容器内执行ls /var/ready命令。如果文件存在, 则ls命令返回退出码 0, 否则返回非0的退出码。如果文件存在,则就绪探针将成功,否则,它会失败。

测试

同样通过rs来测试,如下yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kubia-readiness
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kubia-readiness
  template:
    metadata:
      name: kubia-readiness
      labels:
        app: kubia-readiness
    spec:
      containers:
      - name: kubia-readiness
        image: kubia:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
        readinessProbe:
          exec:
            command:
            - ls
            - /var/ready

查看Pod,因为还没有/var/ready文件,所以探针失败,所有pod处于NotReady状态(0/1).

[root@master1 kubeyaml]# kubectl apply -f kubia-readiness.yaml
replicaset.apps/kubia-readiness created
[root@master1 kubeyaml]# kubectl get po
NAME                    READY   STATUS    RESTARTS   AGE
kubia-readiness-d7nfm   0/1     Running   0          29s
kubia-readiness-nmnbx   0/1     Running   0          5s
kubia-readiness-zf5gc   0/1     Running   0          5s
[root@master1 kubeyaml]#

给pod创建service

apiVersion: v1
kind: Service
metadata:
  name: kubia-readiness
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: kubia-readiness

查看endpoints

[root@master1 kubeyaml]# kubectl apply -f kubia-service-readiness.yaml
service/kubia-readiness created
[root@master1 kubeyaml]# kubectl get svc
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                ClusterIP   10.96.0.1        <none>        443/TCP        14d
kubia-readiness           ClusterIP   10.110.17.61     <none>        80/TCP         9s
[root@master1 kubeyaml]# kubectl get endpoints
NAME                      ENDPOINTS                                                AGE
kubernetes                192.168.2.14:6443                                        14d
kubia-readiness                                                                    22s
[root@master1 kubeyaml]#

可以看到,因为Pod全都是未就绪,所以endpoints一个ip都没有。

给第一个容器创建/var/ready,等待10秒(默认10秒探测一次)

[root@master1 kubeyaml]# kubectl exec kubia-readiness-d7nfm -- touch /var/ready
[root@master1 kubeyaml]# kubectl get po
NAME                    READY   STATUS    RESTARTS   AGE
kubia-readiness-d7nfm   1/1     Running   0          12m
kubia-readiness-nmnbx   0/1     Running   0          11m
kubia-readiness-zf5gc   0/1     Running   0          11m
[root@master1 kubeyaml]# kubectl get endpoints
NAME                      ENDPOINTS                                                     AGE
kubernetes                192.168.2.14:6443                                             14d
kubia-readiness           100.109.35.244:8080                                           7m54s
[root@master1 kubeyaml]# kubectl get svc
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                ClusterIP   10.96.0.1        <none>        443/TCP        14d
kubia-readiness           ClusterIP   10.110.17.61     <none>        80/TCP         8m59s
[root@master1 kubeyaml]# curl 10.110.17.61
You've hit kubia-readiness-d7nfm
[root@master1 kubeyaml]# curl 10.110.17.61
You've hit kubia-readiness-d7nfm
[root@master1 kubeyaml]#

可以看到第一个容器已经ready了,并且endpoints中也已经加入了对应的Pod的IP,访问也正常,且只有这一个Pod响应请求。

未就绪的Pod

其实Pod是已经启动了的,只是因为就绪探针探测失败,所以是NotReady状态(0/1).我们可以尝试访问一下另外的未就绪的容器。

[root@master1 kubeyaml]# kubectl get po 
NAME                    READY   STATUS    RESTARTS   AGE
kubia-err400-q4sr9      1/1     Running   28         120m
kubia-m982c             1/1     Running   3          10d
kubia-n6sgn             1/1     Running   3          10d
kubia-readiness-d7nfm   1/1     Running   0          18m
kubia-readiness-nmnbx   0/1     Running   0          18m
kubia-readiness-zf5gc   0/1     Running   0          18m
kubia-sx7wp             1/1     Running   3          10d
[root@master1 kubeyaml]# kubectl describe po kubia-readiness-nmnbx
Name:         kubia-readiness-nmnbx
Namespace:    default
Priority:     0
Node:         node1.wt.com/192.168.2.15
Start Time:   Mon, 05 Jul 2021 15:41:30 +0800
Labels:       app=kubia-readiness
Annotations:  cni.projectcalico.org/podIP: 100.109.35.235/32
Status:       Running
IP:           100.109.35.235
IPs:
  IP:           100.109.35.235
Controlled By:  ReplicaSet/kubia-readiness
...
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
...
already present on machine
  Normal   Created    18m                   kubelet, node1.wt.com  Created container kubia-readiness
  Normal   Started    18m                   kubelet, node1.wt.com  Started container kubia-readiness
  Warning  Unhealthy  3m41s (x91 over 18m)  kubelet, node1.wt.com  Readiness probe failed: ls: /var/ready: No such file or directory
[root@master1 kubeyaml]# curl 100.109.35.235:8080
You've hit kubia-readiness-nmnbx
[root@master1 kubeyaml]# 

可以看到,容器其实是在运行的,只是探针一直未就绪而已,就绪探针不会杀死容器(和存活探针的区别),curl直接访问Pod的IP也是可以正常接收请求的。

可以看到未就绪状态部分描述。

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

推荐阅读更多精彩内容