AKS中被驱逐Pod仍保留领导权问题求助
核心原因分析
Pod被驱逐时未触发优雅关闭,导致Camel ClusterService的领导权释放逻辑未执行;或者集群租约超时设置过长,集群无法及时检测到旧主节点下线,进而引发脑裂。
具体解决措施
配置Pod优雅关闭与预停止钩子
在Deployment的Pod模板中设置terminationGracePeriodSeconds(建议30-60秒),确保应用有足够时间执行关闭逻辑。同时添加preStop钩子触发Spring Boot应用优雅关闭:spec: terminationGracePeriodSeconds: 30 containers: - name: your-app lifecycle: preStop: exec: command: ["curl", "-XPOST", "http://localhost:8080/actuator/shutdown"]同时在
ApplicationListener中监听ContextClosedEvent,主动调用Camel集群服务的释放方法:@Component public class ClusterLeaderCleanupListener implements ApplicationListener<ContextClosedEvent> { @Autowired private ClusterService clusterService; @Override public void onApplicationEvent(ContextClosedEvent event) { if (clusterService != null && clusterService.isLeader()) { clusterService.forcedLeave(); } } }注意需开启Spring Boot Actuator的shutdown端点(在
application.yml中配置management.endpoints.web.exposure.include=shutdown)。调整Camel ClusterService租约超时配置
如果使用Camel Kubernetes集群组件,缩短租约有效期与续约间隔,让集群更快检测到节点下线。在application.yml中添加:camel: cluster: kubernetes: lease-duration: 15s renew-deadline: 10s retry-period: 2s namespace: ${spring.cloud.kubernetes.namespace:default}主动检测Pod终止状态
在应用中定期检查自身Pod是否处于Terminating状态,若检测到则主动释放领导权。可通过读取Kubernetes环境变量(POD_NAME、POD_NAMESPACE)调用K8s API或读取本地文件(/proc/1/cgroup)判断:@Scheduled(fixedRate = 5000) public void checkPodTermination() { // 示例:读取cgroup文件判断Pod是否在终止中 try { String cgroup = Files.readString(Paths.get("/proc/1/cgroup")); if (cgroup.contains("termination")) { if (clusterService.isLeader()) { clusterService.forcedLeave(); } } } catch (IOException e) { // 日志记录 } }启用Camel集群故障转移策略
确保Camel ClusterService配置了自动故障转移,开启领导权自动回收:camel: cluster: service: enabled: true failover: enabled: true delay: 2000
排查步骤
- 查看被驱逐Pod的日志,确认是否有
ContextClosedEvent触发记录,以及领导权释放的日志输出 - 检查Kubernetes集群中的Lease资源(执行
kubectl get leases -n <your-namespace>),查看对应Camel集群租约的过期时间 - 验证Camel集群配置参数是否已正确加载到应用中
内容的提问来源于stack exchange,提问作者gromyk

