如何告知K8s未完成初始化的Pod暂不参与负载均衡?
核心是利用Kubernetes的就绪探针(Readiness Probe),它会持续检查Pod内的服务是否真正可用——只有当探针检测通过时,K8s才会把这个Pod加入到Service的端点列表,负载均衡流量才会转发过来。另外因为你的Tomcat启动时间长达40-45秒,建议配合启动探针(Startup Probe),避免就绪探针过早失败导致Pod被误重启。
1. 配置就绪探针
针对Tomcat,有几种实用的探针配置方式:
方式一:HTTP GET探针(推荐,需对应健康检查路径)
如果你的Tomcat已经配置了健康检查接口(比如Spring Boot的/actuator/health,或者Tomcat自带的管理路径),可以用HTTP探针直接验证服务状态:
apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deployment spec: replicas: 2 selector: matchLabels: app: tomcat template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: your-custom-tomcat-image ports: - containerPort: 8080 readinessProbe: httpGet: path: /actuator/health # 替换成你的实际健康检查路径,无特殊配置可尝试根路径/ port: 8080 initialDelaySeconds: 30 # 启动后30秒开始第一次检查 periodSeconds: 5 # 每5秒重复检查一次 failureThreshold: 3 # 连续3次失败就标记Pod为未就绪
方式二:TCP Socket探针
如果不需要验证具体路径,只需要确认Tomcat的8080端口已正常监听,可以用TCP探针:
readinessProbe: tcpSocket: port: 8080 initialDelaySeconds: 35 periodSeconds: 5 failureThreshold: 2
方式三:Exec命令探针
如果Tomcat启动完成后会生成特定标识文件(比如/tmp/tomcat-ready),可以用exec命令检查文件是否存在:
readinessProbe: exec: command: - cat - /tmp/tomcat-ready initialDelaySeconds: 30 periodSeconds: 5
2. 配合启动探针处理长启动时间
由于Tomcat启动耗时久,就绪探针的初始延迟如果设置过短,可能在启动过程中多次失败,导致Pod被K8s重启。添加启动探针后,它会在Pod启动阶段持续检查,直到服务完全就绪,之后才交给就绪探针接管:
startupProbe: httpGet: path: /actuator/health port: 8080 failureThreshold: 10 # 最多重试10次 periodSeconds: 5 # 每5秒检查一次 # 10*5=50秒,足够覆盖Tomcat的40-45秒启动周期
3. 确认Service关联逻辑
确保你的Nginx负载均衡是通过Kubernetes Service转发流量(而非硬编码Pod IP)。当Pod未通过就绪探针时,K8s会自动将它从Service的端点列表中移除,Nginx通过Service访问时就不会把流量分发到这个未就绪的Pod。
如果是自定义Nginx配置,建议使用nginx-ingress-controller或基于K8s的Endpoint资源动态获取可用Pod的IP,避免手动配置固定Pod地址。
内容的提问来源于stack exchange,提问作者Xagih

