登录
首页 >  Golang >  Go问答

如何优雅地关闭 Kubernetes 上运行的 Go 服务

来源:stackoverflow

时间:2024-03-13 09:48:26 481浏览 收藏

大家好,我们又见面了啊~本文《如何优雅地关闭 Kubernetes 上运行的 Go 服务》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

我有一个用 Go 编写的 API,已进行 Docker 化并在 GKE 上的 Kubernetes 集群中运行。

目前,我的 API 服务器无法处理任何关闭场景,例如 Pod 死亡或被故意关闭。

我应该捕获哪组 UNIX 信号来正常关闭服务器以及什么情况会触发它们?例如崩溃、K8s 关闭等。


解决方案


kubernetes 发送 sigterm 信号。所以优雅的关闭可能看起来像这样:

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    var srv http.server

    idleconnsclosed := make(chan struct{})
    go func() {
        sigint := make(chan os.signal, 1)

        // interrupt signal sent from terminal
        signal.notify(sigint, os.interrupt)
        // sigterm signal sent from kubernetes
        signal.notify(sigint, syscall.sigterm)

        <-sigint

        // we received an interrupt signal, shut down.
        if err := srv.shutdown(context.background()); err != nil {
            // error from closing listeners, or context timeout:
            log.printf("http server shutdown: %v", err)
        }
        close(idleconnsclosed)
    }()

    if err := srv.listenandserve(); err != http.errserverclosed {
        // error starting or closing listener:
        log.printf("http server listenandserve: %v", err)
    }

    <-idleconnsclosed
}

此外,您还应该将 liveness 和 readiness 探针添加到您的 pod 中:

livenessprobe:
  httpget:
    path: /health
    port: 80
readinessprobe:
  httpget:
    path: /health
    port: 80

回答 https://stackoverflow.com/a/54239385/12641885 仅部分正确。 当 kubernetes 发送 sigterm 信号时,流量仍然可以路由到 pod,因为从端点集中删除 pod 和 sigterm 信号是异步的 - 如果 pod 在 sigterm 端点之后,端点可能没有时间更新。 sigterm 只是礼貌地要求开始结束,但不要立即停止接受新请求。

您可以在 <-sigint 之后将 sleep 添加到您的代码中,或者添加到您的 deployment 中

lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]

更详细信息https://github.com/kubernetes/kubernetes/issues/86280#issuecomment-583173036

到这里,我们也就讲完了《如何优雅地关闭 Kubernetes 上运行的 Go 服务》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>