斌哥的 Docker 進階指南

OneAPM官方技術部落格發表於2016-04-29

過去的一年中,關於 Docker 的話題從未斷過,而如今,從嘗試 Docker 到最終決定使用 Docker 的轉化率依然在逐步升高,關於 Docker 的討論更是有增無減。另一方面,大家的注意力也漸漸從 “Docker 是什麼”轉移到“實踐 Docker”與“監控 Docker”上。

本文轉自劉斌博文「如何選擇 Docker 監控方案 」,文中劉斌從技術的角度深入解釋了 Docker 監控的資料採集原理,介紹了現有開源的監控方案,以及能夠對 Docker 進行監控功能的主流 SaaS 服務工具。

斌哥是誰?

劉斌,擁有 10 多年程式設計經驗,曾參與翻譯過「第一本 Docker 書」、「GitHub 入門與實踐」、「Web 應用安全權威指南」等多本技術書籍,主講過「Docker入門與實踐 」課程的 Cloud Insight 後臺工程師。

為什麼監控,監控什麼內容?

作為一名工程師,我們要對自己系統的執行狀態瞭如指掌,有問題及時發現,而不是讓使用者先發現系統不能使用,打電話找客服,再反映到開發。這個過程很長,而且對工程師來說,是一件比較沒面子的事情。

當領導問我們這個月的 MySQL 併發什麼情況?slowsql 處於什麼水平,平均響應時間超過 200ms 的佔比有百分之多少的時候,回答不出來這個問題很尷尬。儘管你工作很辛苦,但是卻沒有拿得出來的成果。不能因為暫時沒出問題就掉以輕心,換位想想,站在領導的角度,領導什麼都不幹,你提案,他簽字,出了誰背鍋?

監控目的

  1. 減少當機時間

  2. 擴充套件和效能管理

  3. 資源計劃

  4. 識別異常事件

  5. 故障排除、分析

為什麼需要監控我們的服務?其中有一些顯而易見的原因,比如需要監控工具來提醒服務故障,比如通過監控服務的負載來決定擴容或縮容。如果機器普遍負載不高,則可以考慮縮減一下機器規模,如果資料庫連線經常維持在一個高位水平,則可以考慮一下是否可以進行拆庫處理,優化一下架構。

Docker監控面臨的挑戰

  • Docker特點

    • 像host但不是host
    • 量大
    • 生命週期短 監控盲點(斷層)
  • 微服務 叢集

  • 全方位

    • Host(VM) + Services + Containers + Apps

容器為我們的開發和運維帶來了更多的方向和可能性,我們也需要一種現代的監控方案來應對這種變化。

隨著不可變基礎設施概念的普及,雲原生應用的興起,雲端計算元件已經越來越像搭建玩具的積木塊。很多基礎設施生命週期變短,不光容器如此,雲主機、VM也是。

在雲端計算出現之前,一臺機器可能使用3、5年甚至更長都不需要重灌,主機名也不會變,而現在,可能升級一個版本,就要重建一個雲主機或重新啟動一個容器。監控物件動態變化,而且非常頻繁。即使全部實現自動化,也會在負載和複雜度方面帶來不利影響。

監控還有助於進行內部統制,尤其是對安全比較敏感的行業,比如證券、銀行等。比如伺服器受到攻擊時,我們需要分析事件,找到根本原因,識別類似攻擊,發現未知的被攻擊系統,甚至完成取證等工作。

叢集的出現,使應用的拓撲結構也變得複雜,不同應用的指標和日誌格式也不統一,再加上要考慮應對多租戶的問題,這些都給監控帶來了新挑戰。

傳統的監控內包括對主機、網路和應用的監控,但是Docker出現之後,容器這一層很容易被忽略,成為三不管地區,即監控的盲點。

有人說,容器不就是個普通的OS麼?裝個Zabbix的探針不就行了麼?Docker host和Docker 容器都要裝 Zabbix探針……其實問題很多。

除了容器內部看到的cpu記憶體情況不準之外,而且容器生命週期短,重啟之後host名,ip地址都會變,所以最好在Docker host上安裝Zabbix agent。

如果每個容器都像OS那樣監控,則metric數量將會非常巨大,而且這些資料很可能幾分鐘之後就無效率了(容器已經停止)。容器生命週期短暫,一旦容器結束執行,之前收集的資料將不再有任何意義。

主要的解決方式就是以App或者Service為單位進行監控(通過Tag等方式)。

Docker 監控技術基礎

  • docker stats

  • Remote API

  • 偽檔案系統

我們可以通過 docker stats 命令或者Remote API以及Linux的偽檔案系統來獲取容器的效能指標。

使用API的話需要注意一下,那就是不要給Docker daemon帶來效能負擔。如果你一臺主機有200個容器,如果非常頻繁的採集系統效能可能會大量佔據CPU時間。

最好的方式應該就是使用偽檔案系統。如果你只是想通過shell來採集效能資料,則 docker stats 可能是最簡單的方式了。

docker stats 命令

斌哥的 Docker 進階指南 OneAPM 技術公開課 第1張

該命令預設以流式方式輸出,如果想列印出最新的資料並立即退出,可以使用 no-stream=true 引數。

  • 偽檔案系統
  • CPU、記憶體、磁碟
  • 網路

檔案位置大概在(跟系統有關,這是 Systemd 的例子):

此處輸入圖片的描述

Docker各個版本對這三種方式的支援程度不同,取得metric的方式和詳細程度也不同,其中網路metric是在1.6.1之後才能從偽檔案系統得到。

Memory

記憶體的很多效能指標都來自於 memory.stat 檔案:

斌哥的 Docker 進階指南 OneAPM 技術公開課 第3張

前面的不帶total的指標,表示的是該cgroup中的process所使用的、不包括子cgroup在內的記憶體量,而total開頭的指標則包含了這些程式使用的包括子cgroup資料。這裡我們看到的資料都是一樣的,由於這裡並沒有子cgroup。

兩個比較重要的指標:

  • RSS: resident set size

程式的所有資料堆、棧和memory map等。rss可以進一步分類為active和inactive(activeanon and inactiveanon)。在記憶體不夠需要swap一部分到磁碟的時候,會選擇inactive 的rss進行swap 。

  • cache memory

快取到記憶體中的硬碟檔案的大小。比如你讀寫檔案的時候,或者使用mapped file的時候,這個記憶體都會增加。這類記憶體也可以再細分為active和inactive的cache,即activefile和inactivefile。如果系統需要更多記憶體,則inactive的cache會被優先重用。

CPU

  • cpuacct.stat檔案
  • docker.cpu.system
  • docker.cpu.user

但是比較遺憾,Docker 不會報告nice,idle和iowait等事件。

System也叫kernel時間,主要是系統呼叫所耗費的部分,而user則指自己程式的耗費CPU,如果User時間高,則需要好好檢查下自己的程式是否有問題,可能需要進行優化。

Blkio

優先從CFQ(Completely Fair Queuing 完全公平的排隊)拿資料,拿不到從這兩個檔案拿: · blkio.throttle.ioservicebytes,讀寫位元組數 · blkio.throttle.io_serviced,讀寫次數

Throttle這個單純可能有誤導,實際這些都不是限制值,而是實際值。每個檔案的第一個欄位是 major:minor 這樣格式的device ID。

網路資料

  • iptables
  • 偽檔案系統
  • 網路裝置介面
  • Virtual Ethernet

針網路的監控要精確到介面級別,即網路卡級別。每個容器在host上都有一個對應的virtual Ethernet,我們可以從這個裝置獲得tx和rx資訊。

不過找到容器在主機上對應的虛擬網路卡比較麻煩。這時候可以在宿主機上通過 ip netns 命令從容器內部取得網路資料。

為了在容器所在網路名稱空間中執行 ip netns 命令,我們首先需要找到這個容器程式的PID。

斌哥的 Docker 進階指南 OneAPM 技術公開課 第4張

或者:

斌哥的 Docker 進階指南 OneAPM 技術公開課 第5張

實際上Docker的實現也是從偽檔案系統中讀取網路metric的:

斌哥的 Docker 進階指南 OneAPM 技術公開課 第6張

以上,是不是意猶未盡呢? 下一部分,斌哥將為大家介紹: 《Docker 監控方案的實現》

超好用的監控軟體 Cloud Insight 不僅能監控 Docker,還能對 Nagios 進行更好的視覺化哦~

閱讀更多技術文章,請訪問 OneAPM 官方部落格本文轉自 OneAPM 官方部落格

相關文章