k8s+rancher配置滚动发布更新时服务不可用

问题

配置完了k8s优雅下线后,发现配置了滚动发布后,两个服务同时在running状态,其中旧服务开始下线会导致有三四秒的时间调用该服务的接口会负载均衡到该服务,接口调用就会报错服务异常。

经排查,具体原因是服务虽然会到终止状态,但是nacos上有缓存,导致会调用到旧服务。

滚动发布配置:

负载到已下线pod效果:

依赖

需要健康检查和prometheus的支持

xml 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
            <scope>runtime</scope>
        </dependency>

bootstrap.yaml

加入 actuator 独立的端口配置,避免通过gateway能直接访问

yaml 复制代码
# 优雅下线配置
management:
  server:
    port: 9081
  endpoints:
    web:
      exposure:
        include: '*' #对外公开 health,info,shutdown 端点,默认只会公开前两个

bootstrap-xx.yaml

对应环境的配置文件也需要单独配置,全都配置到bootstrap会失效。暴露对应端点才能使后面k8s配置检查成功

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: 'refresh,info,health,logfile,loggers,heapdump,threaddump,metrics,prometheus,mappings,env' #暴露所有端点
      base-path: /actuator

对应服务需要添加下线端点 NacosDeRegistryEndpoint

优化是可以做到公司的common包里,就不必每个服务都重复引入一遍。

java 复制代码
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.registry.NacosRegistration;
import com.alibaba.cloud.nacos.registry.NacosServiceRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Endpoint(id = "nacos-deregister")
public class NacosDeRegistryEndpoint {

    private final NacosRegistration nacosRegistration;
    private final NacosServiceRegistry nacosServiceRegistry;
    private final NacosDiscoveryProperties nacosDiscoveryProperties;

    public NacosDeRegistryEndpoint(NacosRegistration nacosRegistration, NacosServiceRegistry nacosServiceRegistry, NacosDiscoveryProperties nacosDiscoveryProperties) {
        this.nacosRegistration = nacosRegistration;
        this.nacosServiceRegistry = nacosServiceRegistry;
        this.nacosDiscoveryProperties = nacosDiscoveryProperties;
    }

    /**
     * 从 nacos 中主动下线,用于 k8s 滚动更新时,提前下线分流流量
     */
    @WriteOperation
    public String endpoint() {
        String serviceName = nacosDiscoveryProperties.getService();
        String groupName = nacosDiscoveryProperties.getGroup();
        String clusterName = nacosDiscoveryProperties.getClusterName();
        String ip = nacosDiscoveryProperties.getIp();
        int port = nacosDiscoveryProperties.getPort();

        log.info("deregister from nacos, serviceName:{}, groupName:{}, clusterName:{}, ip:{}, port:{}", serviceName, groupName, clusterName, ip, port);

        // 设置服务下线
        nacosServiceRegistry.setStatus(nacosRegistration, "DOWN");
        return "success";
    }
}

rancher修改服务配置

主要是设置一个停止服务前的钩子,钩子会执行设置好的命令。这条命令是用配置好的端口9081,以及添加的服务端点 nacos-deregister,做到调用nacos下线接口的操作,避免缓存问题能被负载到。

commonlisp 复制代码
/bin/sh -c 'curl -X POST 'http://127.0.0.1:9081/actuator/nacos-deregister' && sleep 40'

可视化改容易出问题,也可以通过yaml改:

yaml 复制代码
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - curl -X POST 'http://127.0.0.1:9081/actuator/nacos-deregister' &&
                sleep 40

最终效果是

相关推荐
evans在进步28 分钟前
LeetCode 17:电话号码的字母组合——Java DFS 回溯法详解
java·leetcode·深度优先
2401_8504811732 分钟前
UVA10391
java
UQR38 分钟前
一、Java基础高频面试题
java·开发语言
AC赳赳老秦39 分钟前
网页公开附件自动采集:OpenClaw 批量下载页面内嵌 Word/Excel 附件,统一格式后结构化入库
java·python·word·php·excel·deepseek·openclaw
上海云盾商务经理杨杨1 小时前
Tomcat 弱配置漏洞渗透实战!批量 getshell 高频漏洞
java·web安全·tomcat
10mAh1 小时前
【Linux】error while loading shared libraries 怎么解决?——ldd、RPATH 与动态链接排错
java·linux·前端
深念Y1 小时前
stable-diffusion.cpp 的 FLUX.2 Klein 9B 分步
java·前端·数据库
阿pin1 小时前
Java随笔-红黑树
java·python·算法·红黑树
我命由我123451 小时前
Jetpack Compose - @Preview 注解
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
为美好的生活献上中指1 小时前
Spring AI Advisor 深度实战:构建严谨的 AI Agent 拦截链
java·人工智能·spring·advisor·aiagent