關於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

相關文章
相關標籤/搜索