K8S POD 启动探针 startupProbe 的使用

在这里插入图片描述

当我们启动一个POD 时, 当k8s detect 里面的容器启动成功时, 就会认为这个POD 启动完成了, 通常就会在状态里表示 ready 1/1 …

例如

root@k8s-master:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
bq-api-demo   1/1     Running   0          34m

至于K8S 是怎么判断pod 是否启动完成的:

对于容器内没有设置探测规则的情况,默认的探测规则如下:

启动完成检测:Kubernetes将监视容器的启动状态。如果容器的进程启动并且不处于终止状态(例如,未崩溃),Kubernetes将认为该容器已启动完成。

就绪状态检测:在没有设置就绪探针的情况下,默认情况下,Kubernetes将假定容器处于就绪状态。这意味着在Pod调度到节点后,Kubernetes将立即将流量转发到该容器。

需要注意的是,这些默认规则可能不足以确保应用程序完全启动和可用。因此,强烈建议在Pod的配置文件(YAML)中设置适当的启动探针(startupProbe)和就绪探针(readinessProbe),以便更精确地确定Pod是否已启动完成和就绪,从而确保应用程序的可靠性和稳定性。

所以在生产环境上 我们有必要设置 startupProbe 来让k8s 正确判断pod 已经启动完成, 置于readinessProbe 不在本文讨论范围内。



构建2个api 判断程序是否启动完成

这里作为例子, 我们创建了两个api, 1个模拟成功, 1个模拟失败

模拟成功的api 我们直接用 /actuator/info

@Component
@Slf4j
public class AppVersionInfo implements InfoContributor {@Autowiredprivate Environment environment;@Value("${pom.version}") // https://stackoverflow.com/questions/3697449/retrieve-version-from-maven-pom-xml-in-codeprivate String appVersion;@Overridepublic void contribute(Info.Builder builder) {log.info("AppVersionInfo: contribute ...");builder.withDetail("app", "Sales API").withDetail("version", appVersion).withDetail("description", "This is a simple Spring Boot application to demonstrate the use of BigQuery in GCP.");}
}

模拟失败的api 我们自己写1个 /test/hello/fail

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {@GetMapping("/hello/fail")public ResponseEntity<ApiResponse<String>> getSalesDetails() {log.error("/test/hello/fail ... this api will already return 500 error");ApiResponse<String> response = new ApiResponse<>();response.setReturnCode(-1);response.setReturnMsg("this api will already return 500 error");return ResponseEntity.status(500).body(response);}
}



编辑pod yaml file

请留意startupProde 那一段的具体解释

apiVersion: v1 # api version
kind: Pod # type of this resource e.g. Pod/Deployment ..
metadata: name: bq-api-demolabels: pod-type: app # custom key valuepod-version: v1.0.1namespace: 'default'
spec: # detail descriptioncontainers: # key point- name: bq-api-service # custom nameimage: europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.1.1imagePullPolicy: IfNotPresent # try to use local image first, if no, then pull image from remotestartupProbe:httpGet: # Responses within the range of 200 to 399 code will be considered successfulpath: /actuator/infoport: 8080initialDelaySeconds: 20 # prode 20 seconds to the service before check the statup statusfailureThreshold: 3 # Only when there are three consecutive failed attempts, it is considered a startup failureperiodSeconds: 5 # Retry every 5 seconds (after a failure).timeoutSeconds: 5 # If the API does not return within 5 seconds, it is considered a failureports:- name: http8080containerPort: 8080 # the port used by the container serviceprotocol: TCPenv:- name: JVM_OPTSvalue: '-Xms128m -Xmx2048m'resources:requests: # at least need cpu: 1000m # 1000m = 1 corememory: 1000Mi limits: # at max can usecpu: 2000m memory: 2000MirestartPolicy: OnFailure



重新部署

pod_name=bq-api-demo
yaml_filename=bq-api-service-startup-probe.yaml
namespace=default# 删除指定 Pod
kubectl delete pod $pod_name -n $namespace# 等待 Pod 被删除并重新创建
echo "Waiting for the pod to be deleted..."
kubectl wait pod $pod_name --for=delete -n $namespace# 使用指定的 YAML 文件重新创建 Pod
kubectl create -f $yaml_filename -n $namespace

可以见到K8s 仍然可以detect pod 启动成功

root@k8s-master:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
bq-api-demo   1/1     Running   0          34m

describe 一下:
的确描述了启动规则

root@k8s-master:~# kubectl describe pod bq-api-demo
...
Containers:bq-api-service:Container ID:   docker://15c666bd6e22e174d54ccf8757838a26d89a26562a21edca9174f8bcdb03fa90Image:          europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.1.1Image ID:       docker-pullable://europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service@sha256:30fb2cebd2bf82863608037ce41048114c061acbf1182261a748dadefff2372fPort:           8080/TCPHost Port:      0/TCPState:          RunningStarted:      Sun, 17 Mar 2024 19:00:14 +0000Ready:          TrueRestart Count:  0Limits:cpu:     2memory:  2000MiRequests:cpu:     1memory:  1000MiStartup:   http-get http://:8080/actuator/info delay=20s timeout=5s period=5s #success=1 #failure=3Environment:JVM_OPTS:  -Xms128m -Xmx2048mMounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-j2bpc (ro)
...

看下log, 的确可以看出appVersionInfo的接口被调用了

root@k8s-master:~# kubectl logs bq-api-demo.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::               (v2.7.18)2024-03-17 19:00:15.371  INFO 1 --- [           main] com.home.Application                     : Starting Application v1.1.1 using Java 11.0.16 on bq-api-demo with PID 1 (/app/app.jar started by root in /app)
2024-03-17 19:00:15.375  INFO 1 --- [           main] com.home.Application                     : No active profile set, falling back to 1 default profile: "default"
2024-03-17 19:00:16.601  INFO 1 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2024-03-17 19:00:16.618  INFO 1 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2024-03-17 19:00:17.151  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-03-17 19:00:17.160  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-03-17 19:00:17.160  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.83]
2024-03-17 19:00:17.238  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-03-17 19:00:17.238  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1759 ms
2024-03-17 19:00:17.587  INFO 1 --- [           main] o.s.c.g.a.c.GcpContextAutoConfiguration  : The default project ID is jason-hsbc
2024-03-17 19:00:17.609  INFO 1 --- [           main] o.s.c.g.core.DefaultCredentialsProvider  : Default credentials provider for Google Compute Engine.
2024-03-17 19:00:17.609  INFO 1 --- [           main] o.s.c.g.core.DefaultCredentialsProvider  : Scopes in use by default credentials: [https://www.googleapis.com/auth/pubsub, https://www.googleapis.com/auth/spanner.admin, https://www.googleapis.com/auth/spanner.data, https://www.googleapis.com/auth/datastore, https://www.googleapis.com/auth/sqlservice.admin, https://www.googleapis.com/auth/devstorage.read_only, https://www.googleapis.com/auth/devstorage.read_write, https://www.googleapis.com/auth/cloudruntimeconfig, https://www.googleapis.com/auth/trace.append, https://www.googleapis.com/auth/cloud-platform, https://www.googleapis.com/auth/cloud-vision, https://www.googleapis.com/auth/bigquery, https://www.googleapis.com/auth/monitoring.write]
2024-03-17 19:00:17.704  INFO 1 --- [           main] com.home.api.config.MyInitializer        : Application started...
2024-03-17 19:00:17.705  INFO 1 --- [           main] com.home.api.config.MyInitializer        : https.proxyHost: null
2024-03-17 19:00:17.705  INFO 1 --- [           main] com.home.api.config.MyInitializer        : https.proxyPort: null
2024-03-17 19:00:18.370  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 4 endpoint(s) beneath base path '/actuator'
2024-03-17 19:00:18.510  INFO 1 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2024-03-17 19:00:18.510  INFO 1 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 1 subscriber(s).
2024-03-17 19:00:18.511  INFO 1 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started bean '_org.springframework.integration.errorLogger'
2024-03-17 19:00:18.547  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2024-03-17 19:00:18.562  INFO 1 --- [           main] com.home.Application                     : Started Application in 3.869 seconds (JVM running for 4.353)
2024-03-17 19:00:18.598  INFO 1 --- [           main] com.home.Application                     : customParam: null
2024-03-17 19:00:38.644  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-03-17 19:00:38.644  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2024-03-17 19:00:38.646  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
2024-03-17 19:00:38.681  INFO 1 --- [nio-8080-exec-1] c.h.api.monitor.endpoint.AppVersionInfo  : AppVersionInfo: contribute ...



模拟失败的case

首先创建1个新的yaml file, 规则接口选择/test/hello/fail 这个接口的return code 永远是500

    startupProbe:httpGet: # Responses within the range of 200 to 399 code will be considered successfulpath: /test/hello/fail # alway return 500..port: 8080initialDelaySeconds: 20 # prode 20 seconds to the service before check the statup statusfailureThreshold: 3 # Only when there are three consecutive failed attempts, it is considered a startup failureperiodSeconds: 5 # Retry every 5 seconds (after a failure).timeoutSeconds: 5 # If the API does not return within 5 seconds, it is considered a failure

然后重新部署

root@k8s-master:~/k8s-s/pods# bash redeployPod.sh bq-api-demo bq-api-service-startup-probe-fail.yaml 
pod "bq-api-demo" deleted
Waiting for the pod to be deleted...
pod/bq-api-demo created

这次启动失败了 , 重试了3次

root@k8s-master:~# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS     AGE   IP            NODE        NOMINATED NODE   READINESS GATES
bq-api-demo   0/1     Running   3 (1s ago)   96s   10.244.3.16   k8s-node3   <none>           <none>

从下面的信息也知道是因为startup 接口return 了500

root@k8s-master:~# kubectl describe pod bq-api-demo
Name:         bq-api-demo
Namespace:    default
Priority:     0
Node:         k8s-node3/192.168.0.45
Start Time:   Sun, 17 Mar 2024 20:11:49 +0000
Labels:       pod-type=apppod-version=v1.0.1
Annotations:  <none>
Status:       Running
IP:           10.244.3.16
IPs:IP:  10.244.3.16
Containers:bq-api-service:Container ID:   docker://9a95ed5837917f3b527c8f65ec85cec17661ffa5e4ef4e4a6161b2c4cc2dc329Image:          europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.1.1Image ID:       docker-pullable://europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service@sha256:30fb2cebd2bf82863608037ce41048114c061acbf1182261a748dadefff2372fPort:           8080/TCPHost Port:      0/TCPState:          RunningStarted:      Sun, 17 Mar 2024 20:11:50 +0000Ready:          FalseRestart Count:  0Limits:cpu:     2memory:  2000MiRequests:cpu:     1memory:  1000MiStartup:   http-get http://:8080/test/hello/fail delay=20s timeout=5s period=5s #success=1 #failure=3Environment:JVM_OPTS:  -Xms128m -Xmx2048mMounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xf7gx (ro)
Conditions:Type              StatusInitialized       True Ready             False ContainersReady   False PodScheduled      True 
Volumes:kube-api-access-xf7gx:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type     Reason     Age               From               Message----     ------     ----              ----               -------Normal   Scheduled  35s               default-scheduler  Successfully assigned default/bq-api-demo to k8s-node3Normal   Pulled     34s               kubelet            Container image "europe-west2-docker.pkg.dev/jason-hsbc/my-docker-repo/bq-api-service:1.1.1" already present on machineNormal   Created    34s               kubelet            Created container bq-api-serviceNormal   Started    34s               kubelet            Started container bq-api-serviceWarning  Unhealthy  5s (x2 over 10s)  kubelet            Startup probe failed: HTTP probe failed with statuscode: 500

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/277995.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有来团队后台项目-解析7

sass 安装 因为在使用vite 创建项目的时候&#xff0c;已经安装了sass&#xff0c;所以不需要安装。 如果要安装&#xff0c;那么就执行 npm i -D sass 创建文件 src 目录下创建文件 目录结构如图所示&#xff1a; reset.scss *, ::before, ::after {box-sizing: border-…

矩阵中移动的最大次数

文章目录 所属专栏:BFS算法 题目链接 思路如下&#xff1a; 1.首先我们需要从第一列开始遍历&#xff0c;寻找每一个都能够满足条件的位置&#xff0c;将它插入到数组里面 2.第一列遍历完了后我们先判断第一列的数是否都满足条件插入到数组里面&#xff0c;如果数组为空&#…

电脑充电器能充手机吗?如何给手机充电?

电脑充电器可以给手机充电吗&#xff1f; 电脑充电器可以给手机充电&#xff0c;但前提是电脑充电器的功率输出与手机的功率匹配且接口匹配。 假设电脑充电器的输出功率为5V/2A&#xff0c;手机也支持5V/2A的输入功率。 只要接口匹配&#xff0c;就可以使用电脑充电器给手机充…

Spring Boot Starter: 快速简明地创建Spring应用

Spring Boot Starter是Spring Boot的核心功能之一&#xff0c;它帮助开发人员快速简明地创建、配置和运行Spring应用。在本文中&#xff0c;我们将详细介绍Spring Boot Starter以及如何使用它创建一个Spring Boot应用。 文章目录 什么是Spring Boot Starter?为何使用Spring B…

Jenkins通知目标服务器拉取Harbor镜像部署

1.告诉目标服务器拉取哪个镜像 2.判断当前有没有正在运行此容器&#xff0c;有就删除 3.接着查看拉取的镜像目标服务器上是否已存在&#xff0c;有就删除 4.拉取Harbor镜像 5.运行容器 目标服务器编写脚本 创建个部署脚本 vim deploy.sh告诉目标服务器Harbor地址、仓库、镜像…

文字弹性跳动CSS3代码

文字弹性跳动CSS3代码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 下载地址 文字弹性跳动CSS3代码

Python入门(四)

选择结构 if结构 if和else同时存在&#xff1a;如果if条件不成立&#xff0c;则执行else语句。只存在if&#xff0c;不存在else&#xff1a;没有else&#xff0c;实际上与空的else 等价。如果if后的条件不成立&#xff0c;那么计算机什么都不用执行。 强制缩进 Python与C语…

Qt文件以及文件夹相关类(QDir、QFile、QFileInfo)的使用

关于Qt相关文件读写操作以及文件夹的一些知识&#xff0c;之前也写过一些博客&#xff1a; Qt关于路径的处理&#xff08;绝对路径、相对路径、路径拼接、工作目录、运行目录&#xff09;_qt 相对路径-CSDN博客 C/Qt 读写文件_qt c 读取文本文件-CSDN博客 C/Qt读写ini文件_…

webgl canvas系列——快速加背景、抠图、加水印并下载图片

文章目录 ⭐前言⭐canvas绘制图片&#x1f496;绘制csdn图片&#x1f496;给png图片加背景&#x1f496;cavans下载图片&#x1f496;cavans上传图片并抠图&#x1f496;cavans添加文字水印&#x1f496;inscode 完整代码块 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#x…

Java中的内存溢出与内存泄漏深度解析

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起进步&am…

Hadoop学习3:问题解决

文章目录 问题解决1. ERROR: but there is no HDFS_NAMENODE_USER defined2. JAVA_HOME is not set and could not be found.3. Hadoop-DFS页面访问不了4. namenode格式化失败&#xff0c;或者dfs页面打开失败5. ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Ab…

RabbitMQ——死信队列和延迟队列

文章目录 RabbitMQ——死信队列和延迟队列1、死信队列2、基于插件的延迟队列2.1、安装延迟队列插件2.2、代码实例 RabbitMQ——死信队列和延迟队列 1、死信队列 死信队列&#xff08;Dead Letter Queue&#xff0c;DLQ&#xff09;是 RabbitMQ 中的一种重要特性&#xff0c;用…

npm包、全局数据共享、分包

使用 npm 包 小程序对 npm 的支持与限制 目前&#xff0c;小程序中已经支持使用 npm 安装第三方包&#xff0c;从而来提高小程序的开发效率。但是&#xff0c;在小程序中使用npm 包有如下 3 个限制&#xff1a; ① 不支持依赖于 Node.js 内置库的包 ② 不支持依赖于浏览器内置…

C#配置连接数据库字段

在Web.config文件中 添加如下配置 <!--连接数据库字段--><connectionStrings><add name"sql" connectionString"server.;uidsa;pwd8888;databaseArticleWebSite" /></connectionStrings>

Day67:WEB攻防-Java安全JNDIRMILDAP五大不安全组件RCE执行不出网

知识点&#xff1a; 1、Java安全-RCE执行-5大类函数调用 2、Java安全-JNDI注入-RMI&LDAP&高版本 3、Java安全-不安全组件-Shiro&FastJson&JackJson&XStream&Log4j Java安全-RCE执行-5大类函数调用 Java中代码执行的类&#xff1a; GroovyRuntimeExecPr…

【基于HTML5的网页设计及应用】——改变文字和背景颜色

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

JavaWeb:vue、AJax、ELement、maven、SpringBoot、、Http、Tomcat、请求响应、分层解耦

1 Vue 1.1 Vue介绍 VUE是前端框架&#xff0c;基于MVVM&#xff0c;实现数据双向绑定 框架是半基础软件&#xff0c;可重用的代码模型 1.2 Vue指令 <script src"js/vue.js"></script></head> <body><div id"id"><!--…

机器人路径规划:基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(提供Python代码)

一、深度优先搜索算法介绍 深度优先搜索算法&#xff08;Depth-First-Search&#xff09;的基本思想是沿着树的深度遍历树的节点&#xff0c;尽可能深的搜索树的分支。当节点v的所有边都己被探寻过&#xff0c;搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已…

分布式之Nacos配置中心

Nacos作为配置中心源码分析 1、什么是Naocs配置中心 官方文档&#xff1a; https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config Nacos 提供用于存储配置和其他元数据的 key/value 存储&#xff0c;为分布式系统中的外部化配置提供服务器端和客户端支持。使…

基于springboot+vue的乡政府管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…