关于Kubernetes探针第一次探测的问题

关于k8s的两种探针,想必你们都参考过(https://kubernetes.io/docs/ta...),根据上面的解释,k8s的这两种探针都有initialDelaySeconds属性,它的做用是决定container启动后进行第一次探测的时间,因为服务启动是须要时间的,若是这个属性设置很差,则这个服务的状态极可能就是错误的,设置时间过短可能致使探针屡次探测失败从而使服务失效,设置时间太长,则k8s要花很长时间才认为服务进入“ready”状态。所以,设置initialDelaySeconds必须慎之又慎,同时咱们还常常让periodSecondsfailureThreshold配合其使用,例如:git

readinessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3

上面的配置好理解,探针在容器启动5s后开始探测,而且以后每5s检测一次,若是检测失败的次数大于3,则放弃,认为服务“Unready”(对于liveness探针,则会在放弃后从新启动pod)。
这个配置在periodSeconds较小时,是比较符合预期的,可是当你将periodSeconds配置较大数值时,会发现,初次探针探测的时间也变长了,不是原有的5s,颇有可能几分钟以后才进行第一次探测,这对于有的服务来讲是不可接受的:明明我几秒就启动成功了,能够提供服务了,为何k8s要几分钟后才认为我ready呢?有关这个问题的讨论,能够参考https://github.com/kubernetes...,最终经过查看k8s源码(https://github.com/kubernetes...),你会发现下面这段代码:github

// run periodically probes the container.
func (w *worker) run() {
    probeTickerPeriod := time.Duration(w.spec.PeriodSeconds) * time.Second

    // If kubelet restarted the probes could be started in rapid succession.
    // Let the worker wait for a random portion of tickerPeriod before probing.
    time.Sleep(time.Duration(rand.Float64() * float64(probeTickerPeriod)))

    probeTicker := time.NewTicker(probeTickerPeriod)

    defer func() {
        // Clean up.
        probeTicker.Stop()
        if !w.containerID.IsEmpty() {
            w.resultsManager.Remove(w.containerID)
        }

        w.probeManager.removeWorker(w.pod.UID, w.container.Name, w.probeType)
        ProberResults.Delete(w.proberResultsMetricLabels)
    }()

probeLoop:
    for w.doProbe() {
        // Wait for next probe tick.
        select {
        case <-w.stopCh:
            break probeLoop
        case <-probeTicker.C:
            // continue
        }
    }
}

请特别注意time.Sleep()那段,正是因为那段代码,第一次探针进行探测的时间是initialDelaySeconds + random(periodSeconds),所以periodSeconds的值设得越大,探针第一次探测的时间就越长,服务处于“unready”的状态就越长,若是你要一次性从新部署多个服务,而且依赖于其余服务的话,这一个看似小小的隐患颇有可能形成一连串所依赖的服务探针检测失败(由于有的探针是要对其余服务作healthcheck,其余服务因为从新部署,致使k8s第一次去检测状态是否ready的时间拖延过久,而此期间服务可能早已经ready,但k8s因为还没进行第一次检测,因此认为服务“unready”,引发其余探针探测失败),从而引起整个服务不可用,所以,这点你们在配置时要特别注意。api

相关文章
相关标签/搜索