真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何避免container頻繁地restart?-創(chuàng)新互聯(lián)

如何避免container頻繁地restart?相信大部分人都還沒學會這個技能,為了讓大家學會,給大家總結(jié)了以下內(nèi)容,話不多說,一起往下看吧。

站在用戶的角度思考問題,與客戶深入溝通,找到余姚網(wǎng)站設計與余姚網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設計、網(wǎng)站建設、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、主機域名、網(wǎng)站空間、企業(yè)郵箱。業(yè)務覆蓋余姚地區(qū)。

分析:

  1. 在 Pod 中 restart container 的時候(具體時機是,周期性執(zhí)行 SyncPod() 的時候),Pod 會通過自身的 Status 結(jié)構(gòu)找到當前這個 container(因為 Pod 中可能有多個 container)上一次退出的時間,記為 ts
  2. 如果是第一次 restart,那么直接重啟 container,并且在 Kubelet 的 backOff.perItemBackoff (一個 map 結(jié)構(gòu),key 是根據(jù) container 和所在 pod 對象計算出來的 id)中記錄下次 backoff 的時間(初始值為 10s,然后按照指數(shù)增長,大 5min)
  3. 如果不是第一次 restart,即 Kubelet 的 backOff.perItemBackoff 中已經(jīng)有這個 container 的 backOff 記錄,計為 backoff,那么
    • 如果 now() - ts < backoff,表明等待的時間還不夠,拋出 CrashLoopBackOff Event(然后等到下一個 SyncPod 的周期到的時候,重新比較這個值)
    • 否則,說明已經(jīng)等待 backoff 時間了,可以 restart 了,此時執(zhí)行 backOff.Next(),將該容器對應的 backoff 翻倍,然后執(zhí)行 restart 操作
  4. 在步驟 3 中計算 backoff 的過程中,還會去檢查當前時間距離上一次 container 退出時的間隔,如果大于 2 * MaxContainerBackOff = 10 minutes,那么會將這個 container 對應的 backoff 重置為初始值 10s

源碼細節(jié)

  1. kubernetes/pkg/kubelet/kubelet.go
    通過源碼發(fā)現(xiàn),kubernetes/pkg/kubelet/kubelet.go 文件中有兩個常量:

    MaxContainerBackOff = 300 * time.Second
    backOffPeriod = time.Second * 10

使用這兩個變量構(gòu)造了一個 BackOff 對象,這個是 kubelet 的屬性,對該 node 上所有 pod 都適用

   klet.backOff = flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff)

BackOff 結(jié)構(gòu)如下

type Backoff struct {
     sync.Mutex
     Clock      clock.Clock
     defaultDuration time.Duration
     maxDuration   time.Duration
     perItemBackoff  map[string]*backoffEntry
}

然后在 SyncPod 方法中使用這個對象

// Call the container runtime's SyncPod callback
result := kl.containerRuntime.SyncPod(pod, apiPodStatus, podStatus, pullSecrets, kl.backOff)
  1. kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go

SyncPod 具體做的事有:

// SyncPod syncs the running pod into the desired pod by executing following steps:
//
//  1. Compute sandbox and container changes.
//  2. Kill pod sandbox if necessary.
//  3. Kill any containers that should not be running.
//  4. Create sandbox if necessary.
//  5. Create init containers.
//  6. Create normal containers.
func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) (result kubecontainer.PodSyncResult) {

同樣在這個文件中,有一個關(guān)鍵的函數(shù)

// If a container is still in backoff, the function will return a brief backoff error and
// a detailed error message.
   func (m *kubeGenericRuntimeManager) doBackOff(pod *v1.Pod, container *v1.Container, podStatus *kubecontainer.PodStatus, backOff *flowcontrol.Backoff) (bool, string, error) {
     var cStatus *kubecontainer.ContainerStatus
     for _, c := range podStatus.ContainerStatuses {
         if c.Name == container.Name && c.State == kubecontainer.ContainerStateExited {
             cStatus = c
             break
         }
     }

     if cStatus == nil {
         return false, "", nil
     }

     glog.Infof("checking backoff for container %q in pod %q", container.Name, format.Pod(pod))
     // Use the finished time of the latest exited container as the start point to calculate whether to do back-off.
     ts := cStatus.FinishedAt
     // backOff requires a unique key to identify the container.
     key := getStableKey(pod, container)
     if backOff.IsInBackOffSince(key, ts) {
         if ref, err := kubecontainer.GenerateContainerRef(pod, container); err == nil {
             m.recorder.Eventf(ref, v1.EventTypeWarning, events.BackOffStartContainer, "Back-off restarting failed container")
         }
         err := fmt.Errorf("Back-off %s restarting failed container=%s pod=%s", backOff.Get(key), container.Name, format.Pod(pod))
         glog.Infof("%s", err.Error())
         return true, err.Error(), kubecontainer.ErrCrashLoopBackOff
     }

     backOff.Next(key, ts)
     return false, "", nil
}

其中 backOff.Next 函數(shù)定義如下

// move backoff to the next mark, capping at maxDuration
func (p *Backoff) Next(id string, eventTime time.Time) {
     p.Lock()
     defer p.Unlock()
     entry, ok := p.perItemBackoff[id]
     if !ok || hasExpired(eventTime, entry.lastUpdate, p.maxDuration) {
         entry = p.initEntryUnsafe(id)
     } else {
         delay := entry.backoff * 2 // exponential
         entry.backoff = time.Duration(integer.Int64Min(int64(delay), int64(p.maxDuration)))
     }
     entry.lastUpdate = p.Clock.Now()
}

看完上述內(nèi)容,你們掌握避免container頻繁地restart的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


分享文章:如何避免container頻繁地restart?-創(chuàng)新互聯(lián)
標題路徑:http://weahome.cn/article/gpcgh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部