CentOS系統故障 | 一樁"血案"引發的容器儲存驅動比較
寫在前面: 由於紅帽在Linux界的影響力,相信很多朋友在測試和生產系統用的是RedHat或者CentOS系統,這次我在CentOS系統上遇到了一個很有意思的故障,通過這次故障的原因分析及解決,特意寫了這篇文章分享給大家。
我們在CentOS上部署了一套Docker系統,執行了一段時間後,突然發現所有容器執行異常,同時宿主機核心報磁碟I/O錯誤:
看到問題的第一反映是檢視磁碟狀態和空間使用情況,發現系統的根目錄已經用完:
我們知道,Docker預設的儲存目錄是在/var/lib/docker/下,同時我們也知道,可以通過使用-g, --graph=”/var/lib/docker” 引數修改Docker 預設存放路徑。知道了問題後,我們可以通過掛載一個大硬碟到系統,並將Docker的目錄更改為新掛載到硬碟上:
我將Docker的儲存目錄設定到剛才新增加的/data目錄下,但是原來的映象和容器都找不到了,因為路徑改了。原來的映象是在/var/lib/docker/devicemapper/devicemapper/{data,metadata},轉移檔案後繼續執行Docker服務,這樣我們就有了一個300G的大房子給Docker們用了。
大家以為事情到了這裡就完結了麼?其實我也想,但是我順便折騰了一下,於是又發生了接下來的事情。說我手賤也好,瞎折騰也罷,匯入一堆容器映象和執行一堆容器後,系統又光榮告訴我所有的容器根目錄全部變成了只讀,宿主機核心同樣報磁碟I/O錯誤,一開始我以為data目錄又被寫滿了,但是用df –Th命令檢視後,發現目錄還有很多空間:
但是殘酷的現實是,只用了不到一半的空間後,所有的容器就全部出現異常了,這是我祭出了經典三板斧:重啟容器,重啟Docker服務,重啟伺服器。然並卵,容器還是執行異常。通過在網上爬了一堆資料,在http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/上查到,CentOS預設用的是Device Mapper作為容器的儲存驅動的,大家可以用dockers info命令檢視,Docker服務啟動時預設會在/var/lib/docker/devicemapper/devicemapper/目錄建立一個100G(由於1000和1024換算的關係,系統實際顯示的是107.4G,其他數字亦同)的data檔案,然後啟動的容器的所有變更的資料全部儲存到這個data檔案中;也就是說當容器內產生的相關data資料超過100G後容器就再也沒有多餘的空間可用,從而導致所有容器的根目錄變為只讀!同時它會限制每個容器最大為 10GB。太坑爹了有木有,給了大房子只能用100G!
為了找到根本原因,我們需要了解Device Mapper儲存驅動的原理: Device Mapper儲存驅動是以精簡配置的方式執行的,它實際上是目標塊裝置的快照。 Docker啟動時會設定一個100G的sparse檔案( /var/lib/docker/devicemapper/devicemapper/data,後設資料為/var/lib/docker/devicemapper/devicemapper/metadata ),並將其作為Device Mapper的儲存池,而所有容器都從該儲存池中分配預設10G的儲存空間使用,如下圖所示:
當有實際讀寫後,這些儲存塊將在儲存池中被標記為已使用(或者從池中拿走)。當實際讀寫的塊容量大於池的容量時,容器的執行空間不足,所以報I/O錯誤。
Device Mapper儲存驅動非常方便,你不需要做任何安裝部署便可以使用:如建立額外的分割槽來儲存 Docker 容器,或者建立LVM。然而它也有兩個缺點: • 儲存池會有一個預設 100GB 的容量,滿足不了大儲存的需求。 • 它將會被稀疏檔案所支援(精簡配置,一開始基本不佔用空間,只有當實際需要寫的時候才會使用磁碟的儲存塊)但效能較差。
針對這些問題,有兩個解決方案: 1. 使用更大的檔案/磁碟/邏輯卷建立data檔案:
- 通過Docker啟動引數的--storage-opt選項來限制每個容器初始化的磁碟大小,如-storage-opt dm.basesize=80G 這樣每個容器啟動後,根目錄的總空間就是80G。
但是我總覺得這樣的解決方式不夠優雅,需要多步操作才能滿足需求,同時,容器的空間還是被限制的,只是限制的大小變化而已。那有沒有更好的辦法呢? 讓我們繼續來爬資料,在Docker的官方網站上: (https://docs.docker.com/engine/reference/commandline/dockerd/)
![enter code here][10]
Docker在儲存驅動方面支援 AUFS、Device Mapper、Btrfs、ZFS、 Overlay 、Overlay2等多址方式,現由於AUFS並未併入核心,目前只有Ubuntu系統上能夠使用aufs作為docker的儲存引擎,而在CentOS系統上預設使用Device Mapper,但是幸運的是,在Linux核心3.18.0以上的版本,是可以原生支援Overlay驅動方式的,Overlayfs跟AUFS很像,但是效能比AUFS好,有更好的記憶體利用。
Docker通過-s引數選擇儲存驅動, 通過-s=overlay,我們將儲存驅動器設定為Overlay方式,再重啟Docker應用。
大家可以看到,現在Docker已經是使用了OverlayFS(這裡大家要注意,如果系統有儲存的映象和執行的容器,更改儲存驅動後將都不可用,請先行備份)。
通過修改為OverlayFS,Device Mapper的儲存池容量限制及單個容器執行最大空間限制統統沒有了,同時Overlay的讀寫效能也好於Device Mapper,只需通過-s=overlay一個引數即可優雅的使用更好的檔案系統來執行容器。
至此,容器執行時I/O錯誤的原因已經完美解決,希望這篇文章能幫到在使用過程中遇到相同問題的朋友。
溫馨提示: Docker Live時代●Online Meetup-第二期《容器安全問題及解決之道》開始報名啦!
容器使用愈加廣泛,當前國內外容器安全現狀如何?對於在生產環境中的容器使用需要注意到哪些安全問題?針對這些問題又該如何避免和解決?答案盡在8月17日,Docker Live時代●Online Meetup-第二期《容器安全問題及解決之道》;有容雲首席架構師馬洪喜攜手美女總監雷偉為您揭曉!
活動詳情請點選:《Docker Live時代 | Online Meetup第二期-容器安全問題及解決之道》 活動報名請戳我:http://www.youruncloud.com/videos/meetup.html#start
相關文章
- 一個系統BUG引發的血案 -- FKDownloader
- SwipeRefreshLayout 引發的一場血案
- 容器儲存架構比較:Kubernetes、Docker和MesosCompare架構Docker
- 儲存系統實現-構建自己的儲存系統(一)
- 一個比較不錯的儲存過程分頁儲存過程
- 一個 Handler 面試題引發的血案!!!面試題
- 一個map函式引發的血案函式
- 一道面試題引發的“血案”面試題
- 資料中心儲存系統故障的處理方式
- 一個歷時三年的核心 Bug 引發大量的容器系統出現網路故障
- 儲存結構的種類與比較
- .Net版本引發的血案
- Longhorn 雲原生容器分散式儲存 - 故障排除指南分散式
- 一個ES設定操作引發的“血案”
- 實戰|一個表白牆引發的“血案”
- 一場由postcss-bem引發的血案CSS
- 一個全形空格引發Jquery取值的“血案”jQuery
- 一場 Kafka CRC 異常引發的血案Kafka
- 一個比較複雜的多次拆分字串的儲存過程字串儲存過程
- oracle中發郵件的儲存過程--功能比較強(摘)Oracle儲存過程
- 【原創】一對雙引號引發的goldengate血案Go
- 檔案系統儲存與oracle資料庫儲存對比Oracle資料庫
- RestTemplate超時引發的血案REST
- JDBC亂碼引發的"血案"JDBC
- MySQL 中一個雙引號的錯位引發的血案MySql
- windows 下 asm儲存啟動故障WindowsASM
- 【故障公告】部落格系統升級到 .NET 5.0 引發的故障
- 幾種非易失性儲存器的比較
- 雲端儲存:阿里雲 和 七牛 的比較阿里
- 比較無語的系統
- vue watch陣列引發的血案Vue陣列
- _nop_()函式引發的血案函式
- 解決儲存硬碟故障一則硬碟
- 聊聊 Docker 的儲存驅動 Overlay2Docker
- [WCF]缺少一行程式碼引發的血案行程
- 控制檔案不一致引發的“血案”
- 儲存系統
- 比較 Apache Hadoop 資料儲存格式 - techwellApacheHadoop