简体   繁体   English

如何正确配置 Kube.netes 探测计时(针对 Spring 启动应用程序)

[英]How to properly configure Kubernetes probes timing (for Spring Boot Application)

We have a simple Spring Boot web application which takes less than 30 seconds to start.我们有一个简单的 Spring Boot web 应用程序,启动时间不到 30 秒。 So I configured the probes as follow:所以我按如下方式配置了探测器:

    readinessProbe:
      httpGet:
        path: /actuator/health/readiness
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 1
    livenessProbe:
      httpGet:
        path: /actuator/health/liveness
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 1

My understanding is that readiness probe waits for 30 seconds and then will succeed (if the application is started).我的理解是就绪探测等待 30 秒然后就会成功(如果应用程序已启动)。 And also liveness probe with 30 seconds delay (from the beginning of the deployment) starts and will succeeds almost at the same time readiness probe succeeds (if the application is ready).并且还有 30 秒延迟(从部署开始)的活性探测开始并且几乎在就绪探测成功的同时成功(如果应用程序准备就绪)。 But what I see in logs is that readiness probe waits for 30 seconds and then succeeds, but after that there's another 30 seconds waiting time and then the old pod gets shut down:但是我在日志中看到的是就绪探测等待 30 秒然后成功,但在那之后还有 30 秒的等待时间,然后旧的 pod 被关闭:

develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:07.378Z","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","level":"INFO","thread":"main","message":"Tomcat started on port(s): 8080 (http) with context path ''"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:07.387Z","logger":"org.springframework.data.repository.config.DeferredRepositoryInitializationListener","level":"INFO","thread":"main","message":"Triggering deferred initialization of Spring Data repositories…"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:09.441Z","logger":"org.springframework.data.repository.config.DeferredRepositoryInitializationListener","level":"INFO","thread":"main","message":"Spring Data repositories initialized!"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:09.469Z","logger":"com.example.Application","level":"INFO","thread":"main","message":"Started Application in 23.918 seconds (JVM running for 25.343)"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:14.251Z","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","level":"INFO","thread":"http-nio-8080-exec-1","message":"Initializing Spring DispatcherServlet 'dispatcherServlet'"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:14.258Z","logger":"org.springframework.web.servlet.DispatcherServlet","level":"INFO","thread":"http-nio-8080-exec-1","message":"Initializing Servlet 'dispatcherServlet'"}
develop/demo-57c8984866-6v5sl[demo]: {"ts":"2020-10-08T17:33:14.292Z","logger":"org.springframework.web.servlet.DispatcherServlet","level":"INFO","thread":"http-nio-8080-exec-1","message":"Completed initialization in 30 ms"}
develop/demo-79cc9bc757-xlg6z[demo]: 2020-10-08T17:33:44.590172 Shutting down...
develop/demo-79cc9bc757-xlg6z[demo]: {"ts":"2020-10-08T17:33:44.658Z","logger":"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean","level":"INFO","thread":"SpringContextShutdownHook","message":"Closing JPA EntityManagerFactory for persistence unit 'default'"}
develop/demo-79cc9bc757-xlg6z[demo]: {"ts":"2020-10-08T17:33:44.664Z","logger":"org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor","level":"INFO","thread":"SpringContextShutdownHook","message":"Shutting down ExecutorService 'applicationTaskExecutor'"}
develop/demo-79cc9bc757-xlg6z[demo]: {"ts":"2020-10-08T17:33:44.667Z","logger":"com.zaxxer.hikari.HikariDataSource","level":"INFO","thread":"SpringContextShutdownHook","message":"HikariPool-1 - Shutdown initiated..."}
develop/demo-79cc9bc757-xlg6z[demo]: {"ts":"2020-10-08T17:33:44.680Z","logger":"com.zaxxer.hikari.HikariDataSource","level":"INFO","thread":"SpringContextShutdownHook","message":"HikariPool-1 - Shutdown completed."}

What's the reason for the 2nd 30-second waiting time (see the first "Shutting down...")?第二次30秒的等待时间是什么原因(见第一个“正在关机……”)? For the record, there's not SIGTERM problem (the application responds properly to SIGTERM).作为记录,没有 SIGTERM 问题(应用程序正确响应 SIGTERM)。

MORE INFO更多信息
Correct me if I'm wrong about how these probes work: The container starts, at this moment the timer for readiness initial delay also starts.如果我对这些探测器的工作方式有误,请纠正我:容器启动,此时准备初始延迟的计时器也启动。 25 sec later the app is ready. 25 秒后,应用程序准备就绪。 5 more sec later, the readiness probe starts hitting the app/container and it succeeds, thus the app is ready (right?). 5 秒后,就绪探测器开始命中应用程序/容器并成功,因此应用程序已准备就绪(对吗?)。 At this point I expect k8s send the sigterm to the old pod, asking it to shut down.在这一点上,我希望 k8s 将 sigterm 发送到旧的 pod,要求它关闭。 But as shown in the logs, after the new container is ready, the old pod is still running for 30 more sec.但如日志所示,在新容器准备就绪后,旧 pod 仍运行了 30 秒。
Maybe, rephrasing the question helps.也许,改写这个问题会有所帮助。 I'd like to shut down old pod right after the app is ready.我想在应用准备就绪后立即关闭旧 pod。 And the app is ready in less than 30 sec.该应用程序可在不到 30 秒的时间内准备就绪。 In other words I need the whole deployment to take only 30 sec (considering the startup is less than 30 sec and shutdown is less than one sec).换句话说,我需要整个部署只需要 30 秒(考虑到启动时间少于 30 秒,关闭时间少于 1 秒)。 Why the above configuration doesn't do that?为什么上面的配置不这样做? Thanks.谢谢。

OK, it turned out the tool ( kubecfg ) and library we use to manage our k8s manifests has a different default value for minReadySeconds property (30 seconds).好的,事实证明我们用来管理 k8s 清单的工具 ( kubecfg ) 和库对minReadySeconds属性(30 秒)具有不同的默认值。 I changed that and everything is working as expected.我改变了它,一切都按预期工作。

From your description you are doing everything alright.从你的描述来看,你做的一切都很好。

What we observe is that a different pod is shutting down, than the one that first logged the startup information.我们观察到与第一个记录启动信息的 pod 不同的 pod 正在关闭。 Without more information this looks like a rolling update that waits to shutdown old pods until new pods become available and healthy.没有更多信息,这看起来像是一个滚动更新,等待关闭旧 pod,直到新 pod 可用且健康。

You can tell by looking at the log messages: The pod name is in front of each line.您可以通过查看日志消息来判断:pod 名称在每一行的前面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Spring Boot 和 AWS Keyspaces 配置一致性级别? - How do I configure consistency level with Spring Boot and AWS Keyspaces? 如何在 Spring Boot 中不使用 .json 文件配置 Firestore? - How to configure Firestore without using .json file in Spring Boot? 如何在 Spring Boot 应用程序中启用 DynamoDB 查询日志记录? - How to enable logging of DynamoDB queries in the Spring Boot application? 如何将 AWS Secret Manager 与 Spring 启动应用程序集成 - How to integrate AWS Secret Manager with Spring Boot Application 如何将 spring 启动应用程序部署到 GCP 云功能? - How to deploy spring boot application to GCP cloud functions? 如何将 Spring 启动应用程序的数据输入 Amazon Kinesis? - How to enter data from Spring Boot Application into Amazon Kinesis? 如何在 GCP App Engine 上同时部署 Spring 启动和 React 应用程序? - How to deploy Spring boot and React application together on GCP App Engine? 如何在 EKS 中配置私有注册表 (1.24 kube.netes) - How to configure private registries in EKS (1.24 kubernetes) 如何正确配置我的 iOS 应用程序以使用 Firebase Local Emulator Suite? - How do I properly configure my iOS application to use the Firebase Local Emulator Suite? Spring 启动 & kubernetes JVM 不能 Z34D1F91FB2E514B8576FAB1A75A89AB6 CPU - Spring Boot & kubernetes JVM can not go over 1 CPU
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM