blue7wings

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

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

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

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

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

    我们的日志服务就是这么做的,从未丢过数据
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2547 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 14:15 · PVG 22:15 · LAX 06:15 · JFK 09:15
    ♥ Do have faith in what you're doing.