V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
blue7wings
V2EX  ›  Kubernetes

k8s 滚动更新,如何避免替换掉正在处理任务的 pod?

  •  
  •   blue7wings · 14 天前 · 1935 次点击
    因为 pod 是消耗队列,所以不希望滚动更新的时候,这个 pod 被替换掉,如何保证这个 pod 处理完队列的数据,然后再被自动更新呢? k8s 小白,希望大家能给点建议,谢谢啦
    21 条回复    2021-06-10 14:33:38 +08:00
    Tinet
        1
    Tinet   14 天前
    把 pod 的优雅退出时间设置长一点?当然,你的应用要能捕获到退出信息,以便尽快结束当前正在处理的任务
    kakach
        2
    kakach   14 天前
    不知道 k8s 终止一个 pod 前会不会停止处理新请求并等待一段时间,蹲一个大佬的解答
    mooyo
        3
    mooyo   14 天前
    这个没法保证,因为要保证 pod 处理完再退出就需要从内向外的控制。但是可以调整你的程序来适配 k8s 的一系列信号来尽量避免这个问题。
    首先需要调整退出等待期,调长一点,给程序留一定的周转空间。 然后 k8s 可以给 pod 设置一个退出时执行的命令,通过这个命令告知你的服务赶紧结束掉手上的工作,结束不掉的部分持久化存起来,下一个 pod 拉出来接着做。
    thet
        4
    thet   14 天前 via iPhone
    差不多就是一楼说的,主要你的程序要能捕获退出信号,然后处理完当前任务就退出。可以根据任务最大执行时间设置一下优雅退出时间,优雅退出时间到了后,不管容器内程序怎么样,容器都会被 kubelet 干掉。
    mindsucker
        5
    mindsucker   14 天前
    可以看看优雅停机的相关资料,停机前会给 pid 为 1 的进程发送 TERM signal 命令,但是你的任务要有退出处理机制
    crclz
        6
    crclz   14 天前   ❤️ 1
    换一种思路。一个健壮的程序应当能够完美应对以下情况:

    在断电 /断网后,数据库的完整性依然能够保证。

    这就要求你在处理任务的时候充分发挥事务和幂等性的作用。
    libook
        7
    libook   14 天前
    可以设计成可恢复(或回滚重做)的事务,即便不主动杀 pod 也可能会存在程序崩溃的问题,这时候新运行的程序能够继续做完之前没做完的任务就行了。
    GopherDaily
        8
    GopherDaily   14 天前
    graceful shutdown?
    jim9606
        9
    jim9606   14 天前   ❤️ 5
    为了支持 graceful shutdown,你的程序应当捕获 SIGTERM 信号,在捕获该信号后开启 shutdown 工作,停止接受新任务。无论你是不是用容器都应当做到这点。

    k8s 默认也是这样的,delete 动作后向容器进程发送 SIGTERM,等待 ShutdownGracePeriod (可适当调大些)后仍未退出就会发送 SIGKILL (不可捕获)杀死进程
    defunct9
        10
    defunct9   14 天前
    lifecycle:
    preStop:
    exec:
    command: ["/bin/sh", "-c", "sleep 20"]
    shiny
        11
    shiny   14 天前
    哪怕不用 k8s,Docker 容器也需要考虑退出时的信号,但很多 Dockerfile 都没有考虑到这一点,以至于框架不能捕获 SIGTERM 信号做优雅退出
    heart4lor
        12
    heart4lor   14 天前
    graceful shutdown 是一点,应用尽量做到无状态也很重要,现在其实很少有应用是完全无状态的
    NUT
        13
    NUT   14 天前
    没法保证完全保证。需要做计算与存储分离。
    把队列信息放到 zk 或 etcd 或者 redis mysql 上线。然后做一个分布式调度 就行了。
    xuzhzzz
        14
    xuzhzzz   14 天前
    这跟 k8s 无关,你的程序跑在哪里都得做到 graceful shutdown 啊
    fitmewell
        15
    fitmewell   14 天前 via Android
    先停掉消费队列,然后监控完成后再调用 stop
    vhwwls
        16
    vhwwls   13 天前
    楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
    Rwing
        17
    Rwing   13 天前
    楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
    coderxy
        18
    coderxy   13 天前
    优雅退出,k8s 在关闭某个 pod 前会发出一个 sigterm 的信号,服务接收到这个信号后自行优雅退出,如果发出指定后一段时间(好像默认是 10s ),服务还是在运行就会被 k8s 强制 kill
    jingslunt
        19
    jingslunt   13 天前
    前面将的 lifecycle 生命周期其实就是 pod hook,滚动的时候加一个钩子,只有钩子执行完成才会执行容器的内容
    PiersSoCool
        20
    PiersSoCool   13 天前
    1 、listen term signal
    2 、close http server
    3 、handle rest data

    我们的日志服务就是这么做的,从未丢过数据
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1528 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 17:09 · PVG 01:09 · LAX 10:09 · JFK 13:09
    ♥ Do have faith in what you're doing.