如何确保kubernetes的优雅缩放?

时间:2015-07-22 21:10:02

标签: go docker kubernetes

作为在kubernetes中扩展pod的一部分,我想确保在关闭之前优雅地为我的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!")
}

这会查找docker SIGTERM并在提供现有请求后正常关闭。当我在kubernetes中使用10个实例运行此容器时,我可以无故障地扩展和缩小,只要我不缩小到单个实例。当我缩放到单个实例时,我看到一小组http错误,然后所有看起来都很好。

我发现它很奇怪,因为在扩展中我会假设代理先被更新,然后容器被关闭,上面的代码将允许请求被提供。

在我目前的设置中,我正在运行2个节点,可能问题是当缩放比例低于节点数时,etcd更新会出现某种时序问题?任何洞察这里发生的事情都会非常有用

2 个答案:

答案 0 :(得分:5)

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

将Pod转换为&#34;未准备好&#34;收到SIGTERM后

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

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

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

https://kubernetes-v1-4.github.io/docs/user-guide/production-pods/#lifecycle-hooks-and-termination-notice

答案 1 :(得分:1)

有一个小窗口,在此窗口中正在删除但仍处于活动状态的窗格将成为负载平衡集的一部分。正如布兰登刚刚说的那样(他几秒钟就打败了我),准备检查应该完全由你控制。