我如何确保kubernetes的优雅缩放?

作为kubernetes中缩放荚的一部分,我希望确保在closures之前我优雅地服务于我的http连接。 就这点而言,我已经在go中实现了这个代码:

package main import ( "fmt" "io" "net/http" "os" "os/signal" "syscall" "github.com/braintree/manners" ) func main() { shutdown := make(chan int) //create a notification channel to shutdown sigChan := make(chan os.Signal, 1) //start the http server http.HandleFunc("/", hello) server := manners.NewWithServer(&http.Server{Addr: ":80", Handler: nil}) go func() { server.ListenAndServe() shutdown <- 1 }() //register for interupt (Ctrl+C) and SIGTERM (docker) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) go func() { <-sigChan fmt.Println("Shutting down...") server.Close() }() <-shutdown } func hello(w http.ResponseWriter, r *http.Request) { // time.Sleep(3000 * time.Millisecond) io.WriteString(w, "Hello world!") } 

这看起来dockerSIGTERM和优雅地closures后,现有的请求已经送达。 当我用10个实例在kubernetes中运行这个容器时,只要我不缩小到一个实例,我就可以放大或缩小。 当我缩放到一个单一的实例,我看到一个短的一组HTTP错误,然后一切再次看起来不错。

我觉得这很奇怪,因为在扩展我会假设代理更新第一,然后容器被closures,上面的代码将允许请求被提供出来。

在我当前的设置中,我正在运行2个节点,可能问题是缩放比节点数量less,并且etcd更新有某种时序问题? 任何对这里发生的事情的了解都将非常有用

您应该使用准备就绪检查( http://kubernetes.io/v1.0/docs/user-guide/production-pods.html#liveness-and-readiness-probes-aka-health-checks

在收到SIGTERM后,将Pod转换为“未准备就绪”

一旦发生这种情况,服务将在删除之前从服务中删除Pod。

(没有准备就绪检查服务根本不知道该吊舱不存在,直到它实际上被删除)

您可能还想使用PreStop挂钩,将准备就绪设置为false,然后耗尽所有现有请求。 PreStop钩子在Pod被删除之前被同步调用,在这里描述它们:

http://kubernetes.io/v1.0/docs/user-guide/production-pods.html#lifecycle-hooks-and-termination-notice

有一个小窗口,在这个窗口中,一个正在被移除但仍然活着的容器将成为负载均衡集合的一部分。 正如布伦丹刚才所说的(他几秒钟就打败了我),一个准备就绪检查应该完全在你的掌控之下。