關(guān)于k8s的兩種探針,想必大家都參考過(https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)嗜暴,根據(jù)上面的解釋,k8s的這兩種探針都有initialDelaySeconds
屬性误窖,它的作用是決定container啟動后進(jìn)行第一次探測的時間薪缆,由于服務(wù)啟動是需要時間的,如果這個屬性設(shè)置不好馏段,則這個服務(wù)的狀態(tài)很可能就是錯誤的柜砾,設(shè)置時間太短可能導(dǎo)致探針多次探測失敗從而使服務(wù)失效湃望,設(shè)置時間太長,則k8s要花很長時間才認(rèn)為服務(wù)進(jìn)入“ready”狀態(tài)痰驱。因此喜爷,設(shè)置initialDelaySeconds
必須慎之又慎,同時我們還經(jīng)常讓periodSeconds
和failureThreshold
配合其使用萄唇,例如:
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
上面的配置好理解檩帐,探針在容器啟動5s后開始探測,并且之后每5s檢測一次另萤,如果檢測失敗的次數(shù)大于3湃密,則放棄,認(rèn)為服務(wù)“Unready”(對于liveness探針四敞,則會在放棄后重新啟動pod)泛源。
這個配置在periodSeconds
較小時,是比較符合預(yù)期的忿危,但是當(dāng)你將periodSeconds
配置較大數(shù)值時达箍,會發(fā)現(xiàn),初次探針探測的時間也變長了铺厨,不是原有的5s缎玫,很有可能幾分鐘之后才進(jìn)行第一次探測硬纤,這對于有的服務(wù)來說是不可接受的:明明我?guī)酌刖蛦映晒α耍梢蕴峁┓?wù)了赃磨,為什么k8s要幾分鐘后才認(rèn)為我ready呢筝家?有關(guān)這個問題的討論,可以參考https://github.com/kubernetes/kubernetes/issues/62036邻辉,最終通過查看k8s源碼(https://github.com/kubernetes/kubernetes/blob/b8ab2891b36baa3bbb4e81011e39d5d23a8d46e9/pkg/kubelet/prober/worker.go#L118)溪王,你會發(fā)現(xiàn)下面這段代碼:
// 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
}
}
}
請?zhí)貏e注意time.Sleep()
那段,正是由于那段代碼值骇,第一次探針進(jìn)行探測的時間是initialDelaySeconds + random(periodSeconds)
莹菱,因此periodSeconds
的值設(shè)得越大,探針第一次探測的時間就越長吱瘩,服務(wù)處于“unready”的狀態(tài)就越長芒珠,如果你要一次性重新部署多個服務(wù),并且依賴于其他服務(wù)的話搅裙,這一個看似小小的隱患很有可能造成一連串所依賴的服務(wù)探針檢測失敗(因?yàn)橛械奶结樖且獙ζ渌?wù)做healthcheck裹芝,其他服務(wù)由于重新部署部逮,導(dǎo)致k8s第一次去檢測狀態(tài)是否ready的時間拖延太久,而此期間服務(wù)可能早已經(jīng)ready嫂易,但k8s由于還沒進(jìn)行第一次檢測兄朋,所以認(rèn)為服務(wù)“unready”,引起其他探針探測失斄怠)颅和,從而引發(fā)整個服務(wù)不可用,因此缕允,這點(diǎn)大家在配置時要特別注意峡扩。