docker發展到這麼久,涌現了很是多的延伸工具,有的甚至自成一套系統。相信你們都對各種編排工具備所瞭解。而各種監控方案也都應運而生。linux內核以及cgroup技術其實已經爲監控的技術可行性提供了全部的基礎。這裏咱們列舉一些監控工具:node
docker 提供了command方法(docker stats CID)和API: http://$dockerip:2375/containers/$containerid/stats 其本質是讀文件,提供了CPU,內存,BIO,NIO的監控,想探究其實現的同窗能夠去查閱開源項目libcontainer,或閱讀淺談k8s+docker 資源監控瞭解詳細的技術內容。linux
cAdvisor是一個被k8s集成的監控agent(谷歌自家用),與docker原生監控同樣採用了libcontainer的接口。cadvisor還增長了對宿主機的監控,包括CPU,內存,網卡和磁盤設備,甚至還調用了docker的api,去整合了容器的基本信息如labels,resource limits等。能夠說cadvisor的監控已經比較全面了,然而容易引人吐槽的是:至今cadvisor尚未推出一個穩定的大版本,最新版本是0.24.1,可它的API版本已經出到2.1版了。這裏列出幾個cadvisor的關鍵API(只採用最新的v2.1 api):nginx
1. http://localhost:4194/api/v2.1/stats/:containerid 查看容器的資源數據
2. http://localhost:4194/api/v2.1/machine 查看機器的信息
3. http://localhost:4194/api/v2.1/machinestats 查看機器的資源數據,包括磁盤的讀寫數據
4. http://localhost:4194/api/v2.1/spec/:containerid 查看容器的基礎信息
5. http://localhost:4194/api/v2.1/summary:containerid 查看容器在幾個時間片的各項指標狀態分佈值
6. http://localhost:4194/api/v2.1/storage/:containerid 查看容器中的磁盤掛載狀況
須要注意的是,此處的containerid由podID和container ID,以必定規則,按照不一樣的QoS命名,如: /kubepods/burstable/pode0f6a540-90af-11e8-8ae8-fa163edcbbdb/2bb0179713a20d3f96c85d7fcd1354277270c413f7970b7b6c0db8363bbf892b 表示一個沒有定義容器resources.requests 和resources.limits 的pod(pod的uuid:e0f6a540-90af-11e8-8ae8-fa163edcbbdb)中的容器(容器id:2bb0179713a20d3f96c85d7fcd1354277270c413f7970b7b6c0db8363bbf892b ) /kubepods/podc3b4fc59-9462-11e8-9fcd-fa163edcbbdb/282755d06a51d84c1dc0d3153b1bf4604cc37ae2ccb26c69b3855176894da50c 表示一個定義了容器resources.requests 和resources.limits 的pod中的容器。git
以上幾個接口其實看名字就能大概知道是什麼意思,有興趣的同窗不妨在本身的機器上部署kubernetes,而後在計算節點運行這幾個api試試。 cadvisor默認監聽咋在4194端口,而kubelet其實也代理了cadvisor的監控,因此,咱們除了上述的接口,還能夠經過訪問kubelet(10255端口)來獲取監控數據。github
這裏還要再提一下heapster,cadvisor+heapster能夠很好的實現kubernetes容器集羣的資源監控。heapster在發佈穩定版本(1.0)後,增長了對pause容器的識別,能夠更直觀地經過heapster的API查看到Pod級別的網絡IO。數據存儲用elasticsearch/influxDB/hawkular等各類存儲均可以(heapster支持用戶以storage driver plugin的形式將抓取的metrics sink 自由整合並推送給存儲服務)數據展現使用grafana,這就打造了一套基本完整的的數據監控服務。而使用k8s能夠將三個組件(heapster+influxdb+grafana)一鍵部署。 *k8s1.9後heapster已經被社區廢棄。社區將使用metrics-server進行基礎的集羣性能監控,並使用prometheus來支持更細緻的指標監控。docker
Zabbix更面向裸機和IaaS虛擬機,容器監控是他的軟肋,而openfalcon則被許多企業或docker團隊選型爲容器集羣監控的方案。openfalcon有完整的監控項,增長了郵件告警功能,可自定義的agnet SDK。但整套系統模塊繁多,學習成本大。要想用好,還須要針對容器/kubernetes進行二次開發。segmentfault
prometheus是一套很是成熟的監控,它能夠監控不少細節的性能指標,好比http請求次數,磁盤讀寫io和延遲,cpu負載等,同時prometheus友好地支持自定義指標的採集,用戶能夠以此爲基礎設計本身服務的QPS監控、訪問延遲監控、業務處理速度監控等。目前prometheus已經被不少廠商用於生產環境,也所以它已經順利從CNCF項目中畢業。api
metrics-server嚴格來講是heapster的替代品,它做爲kubernetes的「周邊」,在集羣中以deployment方式部署,metrics-server會註冊一套用於監控的api,監控數據則是從當前集羣的全部node中拉取(也就是上文提到的kubelet代理的監控接口)。在集羣中部署好metrics-server後,過一分鐘咱們能夠經過執行kubectl top node *** 查看一個node節點的cpu和內存使用狀況。 metrics-server主要應用在社區的HPA(horizontal pod autoscaler)功能中。緩存
在linux中,一切都是文件,因此基於LXC技術的虛擬化方案中,對資源的監控其實也是文件,咱們知道docker依賴cgroup作資源的限制,而實際上cgroup也記錄了資源的使用狀況。咱們在容器宿主機的/sys/fs/cgroup/目錄下能夠看到諸如cpu,memory,blkio的子目錄,他們分別存放了對機器上某些進程的資源限制和使用狀況。好比: /sys/fs/cgroup/blkio/docker/1c04cedf48560c37cbac695809f8d50d632faa6b1aaeaf40d269756eb912597b/blkio.throttle.io_service_bytes 記錄了某個容器的塊設備IO字節數。 而容器的網絡設備流量,咱們能夠在/sys/class/net/目錄下根據對應的網卡設備名,找到統計數據文件: /sys/class/net/vethc56160e/statistics/tx_bytes 記錄了某個網卡的發出字節數。 (更多知識能夠學習cgroup的資源限制)服務器
可見,監控數據的抓取並非難事,真正困難的是將這些數據以容器維度,甚至k8s的Pod,RC維度整合。
網易雲計算基礎服務在自研的雲監控服務的基礎上,結合開源組件cadvisor二次開發,實現了雲計算基礎服務的監控系統。
實際上,咱們不創造監控,咱們是監控的搬運工。網易雲平臺已經有成熟的自研監控系統(NMS)爲咱們提供了監控數據的存儲,整理和展現。開源組件cadvisor也提供了cpu,內存,網絡等指標的監控支持和數據緩存(保證監控數據的可讀性)。 本着實用性和可用性的原則,咱們還作了以下設計:
經過一個獨立的agent模塊,去收集cadvisor採集的數據,並推送給雲監控。咱們這麼設計的初衷,最主要爲了不對cadvisor作侵入式開發,避免後續cadvisor的版本更新帶來的大範圍代碼改動。cadvisor自己是一個pull server,不是一個push agent,強行加入push 模塊會增長kubelet的複雜性和性能負擔,也會提升整個系統的耦合度;二是雲監控有本身一套API,對數據的維度和監控的demision都有其規範,好比,咱們將每次push給雲監控的CPU使用率以Namespace#Service#Pod#Container爲標識,確保該監控數據能匹配到制定的容器,從而實現頁面上的展現。而引入這套規範到cadvisor中也會提升整個系統的耦合度。
在agent的部署上咱們直接利用了kubernetes的DaemonSet特性。
咱們知道,k8s最經常使用的兩個資源是pod和replication,daemonset是一個剛趨於穩定的特性,和deployment相似,然而十分的實用。使用daemonset會保證這個agent Pod會在每個計算節點上啓動並保持一個實例。agent調用cadvisor的接口收集數據,根據雲計算基礎服務產品的需求,對數據作過濾和加工,最後推送給雲監控。agent既是kubernetes集羣監控的組件,也是k8s-DaemonSet的應用範例。
雲計算基礎服務實現了有狀態服務的部署,並支持掛載雲硬盤,針對用戶的反饋,咱們瞭解到必須增長對容器的系統盤、數據盤使用率的監控(後續還會提供inode,IOPS,BPS這些指標),提出閾值預警,避免用戶的誤操做致使的不良影響進一步擴大。cadvisor的幾個接口(下文會列出)會分別提供一部分磁盤的監控數據,可是並無作好整合(能夠看到容器stats API中Filesystem字段的內容並非咱們想要的數據).
基於cadvisor的接口和對linux底層的認識,咱們是這麼實現對磁盤的監控的:
1.爲了避免破壞cadvisor原來的代碼結構,在v2.1中新增一個API,提供維度爲一個/多個容器的全部掛載設備的監控信息。監控信息包括:容器名、負載名、容器掛載的雲盤類型、掛載目錄、雲盤uuid等。這裏掛載路徑能夠經過容器的描述文件(或直接docker inspect)獲得。
2.經過原生接口/api/v2.1/stats/machinestats,咱們能看到容器掛載的全部磁盤設備的IOPS和BPS(JSON中的io_serviced字段和io_service_bytes字段記錄了累計值,經過計算能夠求出IOPS和BPS)。結合步驟1的數據,整合出一個容器掛載的全部雲盤的使用率、inode使用率、IOPS和BPS;
3.結合咱們在kubernetes使用過程當中的規範,區分確認系統盤(容器系統盤通常掛載在容器的/目錄下)和數據盤(來自網易雲存儲NBS提供的卷信息),按不一樣維度推送給雲監控。好比cloud#deployment:netease#nginx#ng1 維度,表示cloud namespace、deployment:netease、pod:nginx,容器名:ng1 。
4.雲監控處理監控數據時,根據維度進行數據聚合,以此提供多視角(容器視角、pod視角、負載視角)的監控展現。
若是讀者們閱讀過cadvisor的代碼,會發現裏面對機器的描述信息、文件系統的描述信息,是全局的(感興趣的能夠在源碼中閱讀如下machineInfo、fsInfo兩個變量),且在一個cadvisor Manager對象初始化後就不會再被修改。這致使咱們在測試環境發現:動態掛載一個雲盤到宿主機上,並掛載做爲容器的數據盤時,cadvisor沒法讀取新掛的磁盤的數據,除非重啓kubelet(至關於從新初始化cadvisor中的fsInfo)。咱們在cadvisor的代碼中增長了自檢邏輯,當檢查到機器上有新掛載的雲盤時,對machineInfo、fsInfo作更新(需加鎖,不然會引入竟態)。但這個更改沒有被社區採納。
網易雲容器服務爲用戶提供了無服務器容器,讓企業可以快速部署業務,輕鬆運維服務。容器服務支持彈性伸縮、垂直擴容、灰度升級、服務發現、服務編排、錯誤恢復及性能監測等功能,點擊可免費試用。
網易雲新用戶大禮包:https://www.163yun.com/gift
本文來自網易實踐者社區,經做者黃揚受權發佈。