docker client 使用不當(dāng)造成 too many open files

dockerd 造成 too many open files

一臺(tái)運(yùn)行時(shí)長約5天的機(jī)器扔亥,被發(fā)現(xiàn) docker 無法使用,且其他操作報(bào)錯(cuò) too many open files寸莫。

docker version: 19.03

排查

  • docker client 報(bào)錯(cuò) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
  • lsof 查看蛮放,沒有輸出... 為文件描述符過多。數(shù)分鐘后有輸出其中包含大量 “/var/run/docker.dock” 推測為 docker 客戶端使用不當(dāng)造成愿卸。一般為連接使用后未關(guān)閉埠啃。
  • lsof /var/run/docker.sock 查看該文件FD持有者發(fā)現(xiàn)為 dockerd ,遂進(jìn)入dockerd查找問題瑟由。
  • 查看 dockerd 日志济竹,日志顯示是由于連接不上 docker-libnetwork plugin痕檬,發(fā)現(xiàn)該插件服務(wù)處于停止?fàn)顟B(tài),理論上將其啟動(dòng)即可送浊,但治標(biāo)不治本梦谜,到底為什么這種情況會(huì)導(dǎo)致如此多的FD占用。
# journalctl -xe -u docker.service -f
5月 06 10:57:23 node-2-76 dockerd[5082]: time="2020-05-06T10:57:23.395950238+08:00" level=error msg="1484f4ee9031a4e560c55ed4fdbc68689a668209f4b18b92350e3830969026ec cleanup: failed to delete container from containerd: no such container"
5月 06 10:57:24 node-2-76 dockerd[5082]: time="2020-05-06T10:57:24.387829239+08:00" level=warning msg="Unable to locate plugin: calico-ipam, retrying in 2s"
5月 06 10:57:26 node-2-76 dockerd[5082]: time="2020-05-06T10:57:26.388193568+08:00" level=warning msg="Unable to locate plugin: calico-ipam, retrying in 4s"
5月 06 10:57:30 node-2-76 dockerd[5082]: time="2020-05-06T10:57:30.388593845+08:00" level=warning msg="Unable to locate plugin: calico-ipam, retrying in 8s"
  • 繼續(xù)查看 dockerd trace袭景,docker 開啟了 pprof 端點(diǎn)唁桩。
 curl --unix-socket /var/run/docker.sock "http://./debug/pprof/goroutine?debug=2" > docker.trace

發(fā)現(xiàn)其中有許多goroutine處于 semacquire 狀態(tài),該狀態(tài)是在等待鎖浴讯,且有時(shí)長最大高達(dá) 8355 分鐘的。

goroutine 2195141 [semacquire, 5306 minutes]:
sync.runtime_SemacquireMutex(0xc0004aa704, 0xc00c3cd700)
    /usr/local/go/src/runtime/sema.go:71 +0x3f
sync.(*Mutex).Lock(0xc0004aa700)
    /usr/local/go/src/sync/mutex.go:134 +0x10b
github.com/docker/docker/daemon.(*Daemon).ContainerStart.func1(0x0, 0x0)
    /root/rpmbuild/BUILD/src/engine/.gopath/src/github.com/docker/docker/daemon/start.go:29 +0x45
  • 查看源碼 github.com/docker/docker/daemon/start.go:29 確實(shí)在等鎖蔼啦,如果是在等鎖榆纽。則是由于有地方長期未釋放鎖。注意查找使用 container.Lock() 的地方捏肢。

    // https://github.com/moby/moby/blob/19.03/daemon/start.go#L29
    28  validateState := func() error {
    29      container.Lock()
    30      defer container.Unlock()
    
  • 鑒于上述發(fā)現(xiàn)的 network plugin 不可用基礎(chǔ)上奈籽,一番尋找后發(fā)現(xiàn):

    //https://github.com/moby/moby/blob/master/daemon/container_operations.go#L1065
    1061 func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
    1062    if endpointConfig == nil {
    1063        endpointConfig = &networktypes.EndpointSettings{}
    1064    }
    1065    container.Lock()
    1066    defer container.Unlock()
    
  • 該部分執(zhí)行了所有關(guān)于 docker網(wǎng)絡(luò)相關(guān)的操作,最終追蹤到這里鸵赫,該處會(huì)不同的嘗試調(diào)用相關(guān)插件衣屏,直到插件可用,才會(huì)繼續(xù)執(zhí)行辩棒。

    // https://github.com/moby/moby/blob/master/pkg/plugins/plugins.go#L208
    func loadWithRetry(name string, retry bool) (*Plugin, error) {
    ...
    208 for {
            pl, err := registry.Plugin(name)
            if err != nil {
                if !retry {
                    return nil, err
                }
    
                timeOff := backoff(retries)
                if abort(start, timeOff) {
                    return nil, err
                }
                retries++
    220         logrus.Warnf("Unable to locate plugin: %s, retrying in %v", name, timeOff)
                time.Sleep(timeOff)
                continue
            }
    ...
    241     return pl, err
        }
    }
    
  • 似乎已經(jīng)知道了狼忱,在 network-plugin 不可用的狀態(tài)下膨疏,所有依賴plugin的操作均會(huì)阻塞。我們繼續(xù)使用 docker start [container] 驗(yàn)證它钻弄,果然佃却,使用了 network plugin 的容器無法啟動(dòng),也無法被刪除窘俺。

  • 查看 FD lsof /var/run/docker.sock | wc -l 會(huì)發(fā)現(xiàn)饲帅,每次 docker start 并 ctrl-c 后,F(xiàn)D 計(jì)數(shù)會(huì) +1 瘤泪。因 start 操作發(fā)送給 dockerd 后dockerd會(huì)阻塞該請(qǐng)求直到插件可用灶泵。

  • 在程序中,docker start 基于 context timeout对途,如果超時(shí)赦邻,則取消start 請(qǐng)求,等待數(shù)秒后在此start掀宋,如此深纲,在很長一段時(shí)間后FD逐漸超標(biāo)。直至達(dá)到限制劲妙。

解決方案

  • 改變 calico-libnetwork-plugin 重啟方式
  • 改變調(diào)用 docker client 方式湃鹊,不實(shí)用超時(shí)context,一個(gè)請(qǐng)求阻塞直到 dockerd 返回镣奋。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末币呵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侨颈,更是在濱河造成了極大的恐慌余赢,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哈垢,死亡現(xiàn)場離奇詭異妻柒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)耘分,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門举塔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人求泰,你說我怎么就攤上這事央渣。” “怎么了渴频?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵芽丹,是天一觀的道長。 經(jīng)常有香客問我卜朗,道長拔第,這世上最難降的妖魔是什么咕村? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮楼肪,結(jié)果婚禮上培廓,老公的妹妹穿的比我還像新娘。我一直安慰自己春叫,他們只是感情好肩钠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暂殖,像睡著了一般价匠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呛每,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天踩窖,我揣著相機(jī)與錄音,去河邊找鬼晨横。 笑死洋腮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的手形。 我是一名探鬼主播啥供,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼库糠!你這毒婦竟也來了伙狐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤瞬欧,失蹤者是張志新(化名)和其女友劉穎贷屎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艘虎,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唉侄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了野建。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片属划。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贬墩,靈堂內(nèi)的尸體忽然破棺而出榴嗅,到底是詐尸還是另有隱情妄呕,我是刑警寧澤陶舞,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站绪励,受9級(jí)特大地震影響肿孵,放射性物質(zhì)發(fā)生泄漏唠粥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一停做、第九天 我趴在偏房一處隱蔽的房頂上張望晤愧。 院中可真熱鬧,春花似錦蛉腌、人聲如沸官份。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舅巷。三九已至,卻和暖如春河咽,著一層夾襖步出監(jiān)牢的瞬間钠右,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國打工忘蟹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留飒房,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓媚值,卻偏偏與公主長得像狠毯,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子杂腰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344