当前位置:   article > 正文

K8S的pod探针_pod 所在节点上的 kubelet httpget connet out

pod 所在节点上的 kubelet httpget connet out

事件背景

因为 k8s 中采用大量的异步机制、以及多种对象关系设计上的解耦,当应用实例数 增加/删除、或者应用版本发生变化触发滚动升级时,系统并不能保证应用相关的 service、ingress 配置总是及时能完成刷新。在一些情况下,往往只是新的 Pod 完成自身初始化,系统尚未完成 Endpoint、负载均衡器等外部可达的访问信息刷新,老得 Pod 就立即被删除,最终造成服务短暂的额不可用,这对于生产来说是不可接受的,所以 k8s 就加入了一些存活性探针:StartupProbe、LivenessProbe、ReadinessProbe。

技术探索

Pod 常见的状态

  • Pending:挂起,我们在请求创建 pod 时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件。已经创建了但是没有适合它运行的节点叫做挂起,这其中也包含集群为容器创建网络,或者下载镜像的过程。
  • Running:Pod 内所有的容器都已经被创建,且至少一个容器正在处于运行状态、正在启动状态或者重启状态。
  • Succeeded:Pod 中所以容器都执行成功后退出,并且没有处于重启的容器。
  • Failed:Pod 中所以容器都已退出,但是至少还有一个容器退出时为失败状态。
  • Unknown:未知状态,所谓 pod 是什么状态是 apiserver 和运行在 pod 节点的 kubelet 进行通信获取状态信息的,如果节点之上的 kubelet 本身出故障,那么 apiserver 就连不上 kubelet,得不到信息了,就会看 Unknown

Pod 重启策略

  • Always: 只要容器失效退出就重新启动容器。
  • OnFailure: 当容器以非正常(异常)退出后才自动重新启动容器。
  • Never: 无论容器状态如何,都不重新启动容器。

探针简介

1、kubelet的探测方式

在K8S集群中,为了测试pod是否正常运行,可以通过kubelet定期对pod进行健康检查,从而保证服务正常运行。

kubelet的检查机制:

  • exec: 在容器内执行指定命令,当返回码为0表示检测成功。在 Kubernetes 1.20 版本之前,exec 探针会忽略 timeoutSeconds: 探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。
  • grpc:使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。gRPC 探针是一个 alpha 特性,只有在你启用了"GRPCContainerProbe" 特性门控时才能使用。
  • httpGet:对容器的IP和URL进行HTTP的GET请求,当响应码为大于等于200且小于400,表示容器正常运行。
  • tcpSocket:对容器内的端口或socket进行TCP检查,如果端口成功打开,证明容器正常运行。

探针的返回结果:

  • Success(成功):容器通过了诊断。
  • Failure(失败):容器未通过诊断。
  • Unknown(未知):诊断失败,因此不会采取任何行动。

探针的类型:

livenessProbe(存活探针):判断容器是否正常运行。如果存活探测失败,那么kubelet就会把老的容器删除,然后根据重启策略对容器做操作。如果容器没有存活探针,默认状态为Success。


readinessProbe(就绪探针):判断容器的是否就绪。比如:应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。在这种情况下,既不想杀死应用,也不想给它发送请求。这个时候就需要用到这个探针。
当就绪探测失败,端点控制器将从与 Pod匹配的所有服务的端点列表中删除该 Pod 的 IP 地址(如果是用nodeport映射端口到外网,这个时候就不能访问网站了,但是容器不会被删除),初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。


startupProbe(启动探针):指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet 将删除容器,而容器依其重启策略进行重启。如果容器没有提供启动探测,则默认状态为 Success。
 

探针主要字段解析:

(initialDelaySeconds: 5):初始化延迟时间,主要是告诉kubelet,容器启动需要的时间,当过了这个时间再进行探测,要不然容器可能还没启动就会删除了。
(periodSeconds: 5):探测周期间隔时间,主要是指定kubelet对容器进行探针的时间周期,也就是第一次探测结束后,等待多少时间后对容器进行探测。默认值为10秒,最小值为1秒。
(timeoutSeconds: 5):单次探测超时时间,指定kubelet对容器探测的最大时间,超过这个时间证明容器探测失败。默认为1秒,最小为1秒。
(successThreshold: 5):探测失败到成功的重试次数,当kubelet对某个容器第一次探测失败后,重新进行探测的次数,比如指定为1,那么就会直接将容器删除。如果使用的探针是livenessProbe,那么只能配置为1,最小值为1次。
(failureThreshold: 5):探测成功到失败的重试次数,当kubelet对某个容器进行探测过程中,允许失败的次数,当用于readinessProbe探针,默认是3次,最小值为1次。也就是说当3次探测失败后,容器会被删除。当用于startupProbe探针,如果还设置了periodSeconds时间,那么等待容器启动的时间为failureThreshold的时间乘以periodSeconds时间的值,在这段时间内,容器没有启动,那么就会删除容器。
 

2、livenessProbe探针
2.1 livenessProbe和kubelet-exec

首先我们定义一个nginx的deployment:

kubectl apply -f nginx-exec.yaml

pod正常运行以后,我们查下探针里的目录文件是否存在,显然是正常返回的

kubectl exec -it nginx-deployment-5546c765b7-zt6cc -- ls /usr/share/nginx/html/index.html


我们修改index.html为index.html.bak,看看pod的探测无法获取到index.html后,可以看到RESTARTS变成了1,证明容器重启过了,可以看到文件又存在了,证明容器被重建了。

2.2、livenessProbe和kubelet-httpGet

master创建容器

删除文件,这样探针就会被触发,可以看到RESTARTS变成了1,证明容器重启过了

可以看到文件又存在了,证明容器被重建了

2.3、livenessProbe和kubelet-tcpSocket

3、readinessProbe探针

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: nginx
  6. name: nginx
  7. namespace: default
  8. spec:
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. app: nginx
  13. template:
  14. metadata:
  15. labels:
  16. app: nginx
  17. spec:
  18. containers:
  19. - name: nginx
  20. image: nginx
  21. ports:
  22. - containerPort: 80
  23. readinessProbe: #指定探针
  24. exec: #指定探针探测方式
  25. command:
  26. - cat
  27. - /usr/share/nginx/html/index.html
  28. initialDelaySeconds: 5
  29. periodSeconds: 5
  30. ---
  31. apiVersion: v1
  32. kind: Service
  33. metadata:
  34. labels:
  35. svc: nginx-svc-nodeport
  36. name: nginx-svc-nodeport
  37. spec:
  38. type: NodePort
  39. ports:
  40. - port: 80
  41. targetPort: 80
  42. nodePort: 30080
  43. selector:
  44. app: nginx

 

kubectl get pod -A -o wide     查看容器名字,可以看到原本READY是1/1
kubectl exec -it nginx-677665d5db-fct77 /bin/sh  连接容器

cd /usr/share/nginx/html/   修改探针指定探测的文件名字,让探针触发
mv index.html index1.html 
exit

kubectl get pod -A -o wide  可以看到READY变成了0/1,证明探针被触发了,容器没有被删除,也没有重建
curl -I http://192.168.2.10:30080  可以看到网站访问不了
kubectl describe svc nginx-svc-nodeport  可以看到Endpoints没有值,证明探针把service和pod解除绑定了

 3.2、readinessProbe和kubelet-httpGet

  1. [root@k8s-master readliness]# cat readliness-httpGet.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6. app: nginx
  7. name: nginx
  8. namespace: default
  9. spec:
  10. replicas: 1
  11. selector:
  12. matchLabels:
  13. app: nginx
  14. template:
  15. metadata:
  16. labels:
  17. app: nginx
  18. spec:
  19. containers:
  20. - name: nginx
  21. image: nginx
  22. ports:
  23. - containerPort: 80
  24. readinessProbe: #指定探针
  25. httpGet: #指定探针方式
  26. path: /index.html
  27. port: 80
  28. initialDelaySeconds: 5
  29. periodSeconds: 5
  30. ---
  31. apiVersion: v1
  32. kind: Service
  33. metadata:
  34. labels:
  35. svc: nginx-svc-nodeport
  36. name: nginx-svc-nodeport
  37. spec:
  38. type: NodePort
  39. ports:
  40. - port: 80
  41. targetPort: 80
  42. nodePort: 30080
  43. selector:
  44. app: nginx
  45. [root@k8s-master readliness]# kubectl apply -f readliness-httpGet.yaml
  46. deployment.apps/nginx created
  47. service/nginx-svc-nodeport created
  48. [root@k8s-master readliness]# kubectl get pod -o wide
  49. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  50. nginx-5865d7c55c-9p4cv 1/1 Running 0 60s 10.244.2.33 k8s-node2 <none> <none>
  51. [root@k8s-master readliness]# kubectl describe svc nginx-svc-nodeport
  52. Name: nginx-svc-nodeport
  53. Namespace: default
  54. Labels: svc=nginx-svc-nodeport
  55. Annotations: <none>
  56. Selector: app=nginx
  57. Type: NodePort
  58. IP: 10.99.244.94
  59. Port: <unset> 80/TCP
  60. TargetPort: 80/TCP
  61. NodePort: <unset> 30080/TCP
  62. Endpoints: 10.244.2.33:80
  63. Session Affinity: None
  64. External Traffic Policy: Cluster
  65. Events: <none>
  66. [root@k8s-master readliness]# kubectl get pod -o wide
  67. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  68. nginx-5865d7c55c-9p4cv 1/1 Running 0 60s 10.244.2.33 k8s-node2 <none> <none>
  69. [root@k8s-node1 ~]# curl -I http://192.168.2.10:30080 #成功访问svc
  70. HTTP/1.1 200 OK
  71. Server: nginx/1.23.2
  72. Date: Mon, 07 Nov 2022 13:56:35 GMT
  73. Content-Type: text/html
  74. Content-Length: 615
  75. Last-Modified: Wed, 19 Oct 2022 07:56:21 GMT
  76. Connection: keep-alive
  77. ETag: "634fada5-267"
  78. Accept-Ranges: bytes
  79. [root@k8s-master readliness]# kubectl exec -it nginx-5865d7c55c-9p4cv bash
  80. kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
  81. root@nginx-5865d7c55c-9p4cv:/# cd /usr/share/nginx/html/
  82. root@nginx-5865d7c55c-9p4cv:/usr/share/nginx/html# mv index.html index.html1
  83. root@nginx-5865d7c55c-9p4cv:/usr/share/nginx/html# exit
  84. exit
  85. [root@k8s-master readliness]# #移动index.html出发探针失败
  86. #宿主机已经无法访问,流量无法进入
  87. [root@k8s-node1 ~]# curl -I http://192.168.2.10:30080
  88. HTTP/1.1 403 Forbidden
  89. Server: nginx/1.23.2
  90. Date: Mon, 07 Nov 2022 13:57:45 GMT
  91. Content-Type: text/html
  92. Content-Length: 153
  93. Connection: keep-alive
  94. [root@k8s-master readliness]# kubectl describe svc nginx-svc-nodeport
  95. Name: nginx-svc-nodeport
  96. Namespace: default
  97. Labels: svc=nginx-svc-nodeport
  98. Annotations: <none>
  99. Selector: app=nginx
  100. Type: NodePort
  101. IP: 10.99.244.94
  102. Port: <unset> 80/TCP
  103. TargetPort: 80/TCP
  104. NodePort: <unset> 30080/TCP
  105. Endpoints: #service没有与pod进行绑定
  106. Session Affinity: None
  107. External Traffic Policy: Cluster
  108. Events: <none>
  109. # pod虽然处于running状态,但不ready,不会作为service的endpoint提供服务
  110. [root@k8s-master readliness]# kubectl get pod
  111. NAME READY STATUS RESTARTS AGE
  112. nginx-5865d7c55c-9p4cv 0/1 Running 0 6m8s

3.3、readinessProbe和kubelet-tcpSocket

  1. [root@k8s-master readliness]# cat readliness-tcp.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. labels:
  6. app: nginx
  7. name: nginx
  8. namespace: default
  9. spec:
  10. replicas: 1
  11. selector:
  12. matchLabels:
  13. app: nginx
  14. template:
  15. metadata:
  16. labels:
  17. app: nginx
  18. spec:
  19. containers:
  20. - name: nginx
  21. image: nginx
  22. ports:
  23. - containerPort: 80
  24. readinessProbe: #指定探针
  25. tcpSocket: #指定探测方式
  26. port: 80
  27. initialDelaySeconds: 5
  28. periodSeconds: 5
  29. ---
  30. apiVersion: v1
  31. kind: Service
  32. metadata:
  33. labels:
  34. svc: nginx-svc-nodeport
  35. name: nginx-svc-nodeport
  36. spec:
  37. type: NodePort
  38. ports:
  39. - port: 80
  40. targetPort: 80
  41. nodePort: 30080
  42. selector:
  43. app: nginx
  44. [root@k8s-master readliness]# kubectl apply -f readliness-tcp.yaml
  45. deployment.apps/nginx created
  46. service/nginx-svc-nodeport created
  47. [root@k8s-master readliness]# kubectl get svc
  48. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  49. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18d
  50. nginx-svc-nodeport NodePort 10.99.24.165 <none> 80:30080/TCP 17s
  51. [root@k8s-master readliness]# kubectl get pod
  52. NAME READY STATUS RESTARTS AGE
  53. nginx-7464f54778-tbwtf 1/1 Running 0 39s
  54. [root@k8s-master readliness]# kubectl describe svc nginx-svc-nodeport
  55. Name: nginx-svc-nodeport
  56. Namespace: default
  57. Labels: svc=nginx-svc-nodeport
  58. Annotations: <none>
  59. Selector: app=nginx
  60. Type: NodePort
  61. IP: 10.99.24.165
  62. Port: <unset> 80/TCP
  63. TargetPort: 80/TCP
  64. NodePort: <unset> 30080/TCP
  65. Endpoints: 10.244.2.34:80
  66. Session Affinity: None
  67. External Traffic Policy: Cluster
  68. Events: <none>
  69. #########svc可以正常访问
  70. [root@k8s-node1 ~]# curl -I http://192.168.2.10:30080
  71. HTTP/1.1 200 OK
  72. Server: nginx/1.23.2
  73. Date: Mon, 07 Nov 2022 14:05:53 GMT
  74. Content-Type: text/html
  75. Content-Length: 615
  76. Last-Modified: Wed, 19 Oct 2022 07:56:21 GMT
  77. Connection: keep-alive
  78. ETag: "634fada5-267"
  79. Accept-Ranges: bytes
  80. [root@k8s-master readliness]# kubectl exec -it nginx-7464f54778-tbwtf bash
  81. kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
  82. root@nginx-7464f54778-tbwtf:/# sed -i 's/80/8000/g' /etc/nginx/conf.d/default.conf
  83. root@nginx-7464f54778-tbwtf:/# nginx -s reload
  84. 2022/11/07 14:07:29 [notice] 37#37: signal process started
  85. root@nginx-7464f54778-tbwtf:/#
  86. [root@k8s-master readliness]# kubectl describe svc nginx-svc-nodeport
  87. Name: nginx-svc-nodeport
  88. Namespace: default
  89. Labels: svc=nginx-svc-nodeport
  90. Annotations: <none>
  91. Selector: app=nginx
  92. Type: NodePort
  93. IP: 10.99.24.165
  94. Port: <unset> 80/TCP
  95. TargetPort: 80/TCP
  96. NodePort: <unset> 30080/TCP
  97. Endpoints:
  98. Session Affinity: None
  99. External Traffic Policy: Cluster
  100. Events: <none>
  101. [root@k8s-node1 ~]# curl -I http://192.168.2.10:30080
  102. curl: (7) Failed connect to 192.168.2.10:30080; Connection refused

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

闽ICP备14008679号