Kubernetes主機和容器的監控方案

from: https://www.kubernetes.org.cn/2432.html 

本文是有容雲後端開發工程師 李強 7月27日在微信羣分享內容整理

摘要:隨着Docker容器雲的廣泛應用,大量的業務軟件運行在容器中,這使得對docker容器的監控越來越重要。傳統的監控系統大多數是針對物理機或者虛擬機設計的,而容器的特點不同與傳統的物理機或者虛擬機,如果還是採用傳統的監控系統,則會增加監控複雜程度,那麼如何對容器進行監控呢?

大家晚上好,今天很高興能在這裏和大家一起交流和分享在工作中的一些經驗和總結。都知道監控在運維體系乃至產品的整個生命中期都是重要的一個環節,針對不同的應用場景,監控方案也會有很大的不同。本次就和大家分享一下我在開發我們公司新產品ufleet的監控模塊時的一些技術總結,如果有錯誤的地方,歡迎大家指出。主要內容有:

1.數據的採集方式

2.監控原理

3.容器的監控方案

4.kubernetes上的主機和容器的監控

5.監控工具的對比

一個完整的監控體系包括:採集數據、分析存儲數據、展示數據、告警以及自動化處理、監控工具自身的安全機制,接下來會對數據的採集和監控原理深入講解,其他部分會在一些架構中穿插講解。

一 、數據的採集方式

1.命令行方式。比如在linux系統上使用top,vmstat,netstat寫一些shell腳本進行數據的採集,再把數據存儲在文本文件中進行處理。

2.嵌入式。通過在進程中運行agent的方式獲取應用的狀態。如目前的APM產品都是通過將監控工具嵌入到應用內部進行數據採集。

3.主動輸出。提前在應用中埋點,應用主動上報。比如一些應用系統的業務狀態,可以通過在日誌中主動輸出狀態用於採集。

4.旁路式。通過外部獲取的方式採集數據。比如對網站url的探測,模擬業務的報文 ,對服務器的ping,流量的監控。可以通過在交換機上將流量進行端口複製,將源始流量複製到另一個端口後再進行處理,這樣這業務系統是完全沒有侵入。

5.遠程接入。通過對應用進程接口調用獲取應用的狀態。比如使用JMX的方式連接到java進程中,對進程的狀態進行採集。

6.入侵式。不同於嵌入式,入侵式的agent是獨立運行的進程,而不是運行在進程中。這個目前監控工具比較常用的方式,比如zabbix,在主機上運行一個進程進行相關數據的採集。

二、監控原理

具體監控指標總結如下:

  • 首先是容器本身資源使用情況:cpu,內存,網絡,磁盤
  • 物理機的資源使用情況:cpu,內存,網絡,磁盤
  • 物理機上容器鏡像情況,名字,大小,版本。

1.主機的監控

(1)Cpu數據

使用top命令可以查看當前cpu使用情況,源文件來自/proc/stat

採樣兩個足夠短的時間間隔的Cpu快照,分別記作t1,t2,其中t1、t2的結構均爲:

(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元組;

a) 計算總的Cpu時間片totalCpuTime

  • 把第一次的所有cpu使用情況求和,得到s1;
  • 把第二次的所有cpu使用情況求和,得到s2;
  • s2 – s1得到這個時間間隔內的所有時間片,即totalCpuTime = j2 – j1 ;

b) 計算空閒時間idle

  • idle對應第四列的數據,用第二次的第四列- 第一次的第四列即可
  • idle=第二次的第四列- 第一次的第四列

c) 計算cpu使用率

  • pcpu =100* (total-idle)/total

(2)linux內存監控

使用free命令可以查看當前內存使用情況。

其數據來源是來自/proc/meminfo文件

常用的計算公式:

real_used = used_mem – buffer – cache

real_free = free_mem + buffer + cache

total_mem = used_mem + free_mem

(3) Network數據

/proc/net/dev保存着有關網絡的數據

如計算一段時間sec秒內的網絡平均流量:

infirst=$(awk ‘/’$eth’/{print $1 }’ /proc/net/dev |sed ‘s/’$eth’://’)

outfirst=$(awk ‘/’$eth’/{print $10 }’ /proc/net/dev)

sumfirst=$(($infirst+$outfirst))

sleep $sec”s”

inend=$(awk ‘/’$eth’/{print $1 }’ /proc/net/dev |sed ‘s/’$eth’://’)

outend=$(awk ‘/’$eth’/{print $10 }’ /proc/net/dev)

sumend=$(($inend+$outend))

sum=$(($sumend-$sumfirst))

aver=$(($sum/$sec))

2.docker的監控

docker自身提供了一種內存監控的方式,即可以通過docker stats對容器內存進行監控。

該方式實際是通過對cgroup中相關數據進行取值從而計算得到。其數據來源是/sys/fs/cgroup

docker client相關代碼入口可參考:/docker/docker/api/client/stats.go#141

docker daemon相關代碼入口可參考:/docker/docker/daemon/daemon.go#1474

(1)Cpu數據

docker daemon會記錄這次讀取/sys/fs/cgroup/cpuacct/docker/  [containerId]/cpuacct.usage的值,作爲cpu_total_usage;並記錄了上一次讀取的該值爲      pre_cpu_total_usage;讀取/proc/stat中cpu field value,並進行累加,得到system_usage;並    記錄上一次的值爲pre_system_usage;讀取/sys/fs/cgroup/cpuacct/docker/       [containerId]/cpuacct.usage_percpu中的記錄,組成數組per_cpu_usage_array;

docker stats計算Cpu Percent的算法:

cpu_delta = cpu_total_usage – pre_cpu_total_usage;

system_delta = system_usage – pre_system_usage;

CPU % = ((cpu_delta / system_delta) * length(per_cpu_usage_array) ) * 100.0

(2) Memory數據

讀取/sys/fs/cgroup/memory/docker/[containerId]/memory.usage_in_bytes的值,作爲    mem_usage;如果容器限制了內存,則讀取/sys/fs/cgroup/memory/docker/  [id]/memory.limit_in_bytes作爲mem_limit,否則mem_limit = machine_mem;docker stats計算 Memory數據的算法:

MEM USAGE = mem_usage

MEM LIMIT = mem_limit

MEM % = (mem_usage / mem_limit) * 100.0

(3)Network Stats數據:

獲取屬於該容器network namespace veth pairs在主機中對應的veth*虛擬網卡EthInterface       數組,然後循環數組中每個網卡設備,讀取/sys/class/net/[device]/statistics/rx_bytes得到rx_bytes, 讀取/sys/class/net/[device]/statistics/tx_bytes得到對應的tx_bytes。

將所有這些虛擬網卡對應的rx_bytes累加得到該容器的rx_bytes。

將所有這些虛擬網卡對應的tx_bytes累加得到該容器的tx_bytes。

docker stats計算Network IO數據的算法:

NET I = rx_bytes

NET O = tx_bytes

三、容器的監控方案

1.單臺主機容器監控:

(1)docker stats

單臺主機上容器的監控實現最簡單的方法就是使用命令Docker stats,就可以顯示所有容器的資源使用情況.

這樣就可以查看每個容器的CPU利用率、內存的使用量以及可用內存總量。請注意,如果你沒有限制容器內存,那麼該命令將顯示您的主機的內存總量。但它並不意味着你的每個容器都能訪問那麼多的內存。另外,還可以看到容器通過網絡發送和接收的數據總量

雖然可以很直觀地看到每個容器的資源使用情況,但是顯示的只是一個當前值,並不能看到變化趨勢。

(2)Google的 cAdvisor 是另一個知名的開源容器監控工具:

只需在宿主機上部署cAdvisor容器,用戶就可通過Web界面或REST服務訪問當前節點和容器的性能數據(CPU、內存、網絡、磁盤、文件系統等等),非常詳細。

它的運行方式也有多種:

a.直接下載命令運行

下載地址:https://github.com/google/cadvisor/releases/latest

格式:  nohup /root/cadvisor  -port=10000 &>>/var/log/kubernetes/cadvisor.log &

訪問: http://ip:10000/

b.以容器方式運行

docker pull index.alauda.cn/googlelib/cadvisor

運行:

docker run -d --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw –volume=/sys:/sys:ro       --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080  --name=cadvisor                      

index.alauda.cn/googlelib/cadvisor:latest

c.kubelet選項:

在啓動kubelete時候,啓動cadvisor

cAdvisor當前都是隻支持http接口方式,被監控的容器應用必須提供http接口,所以能力較弱。在Kubernetes的新版本中已經集成了cAdvisor,所以在Kubernetes架構下,不需要單獨再去安裝cAdvisor,可以直接使用節點的IP加默認端口4194就可以直接訪問cAdvisor的監控面板。UI界面如下:

因爲cAdvisor默認是將數據緩存在內存中,在顯示界面上只能顯示1分鐘左右的趨勢,所以歷史的數據還是不能看到,但它也提供不同的持久化存儲後端,比如influxdb等,同時也可以根據業務的需求,只利用cAdvisor提供的api接口,定時去獲取數據存儲到數據庫中,然後定製自己的界面。

如需要通過cAdvisor查看某臺主機上某個容器的性能數據只需要調用:       http://<host_ip>:4194/v1.3/subcontainers/docker/<container_id>

cAdvisor的api接口返回的數據結構如下:

可以根據這些數據分別計算出 CPU、內存、網絡等資源的使用或者佔用情況。

四、kubernetes上的監控

1.容器的監控

在Kubernetes監控生態中,一般是如下的搭配使用:

(1)Cadvisor+InfluxDB+Grafana:

Cadvisor:將數據,寫入InfluxDB

InfluxDB :時序數據庫,提供數據的存儲,存儲在指定的目錄下

Grafana :提供了WEB控制檯,自定義查詢指標,從InfluxDB查詢數據,並展示

cAdivsor雖然能採集到監控數據,也有很好的界面展示,但是並不能顯示跨主機的監控數據,當主機多的情況,需要有一種集中式的管理方法將數據進行彙總展示,最經典的方案就是 cAdvisor+ Influxdb+grafana,可以在每臺主機上運行一個cAdvisor容器負責數據採集,再將採集後的數據都存到時序型數據庫influxdb中,再通過圖形展示工具grafana定製展示面板。

在上面的安裝步驟中,先是啓動influxdb容器,然後進行到容器內部配置一個數據庫給cadvisor專用,然後再啓動cadvisor容器,容器啓動的時候指定把數據存儲到influxdb中,最後啓動grafana容器,在展示頁面裏配置grafana的數據源爲influxdb,再定製要展示的數據,一個簡單的跨多主機的監控系統就構建成功了。

(2)Kubernetes——Heapster+InfluxDB+Grafana:

Heapster:在k8s集羣中獲取metrics和事件數據,寫入InfluxDB,heapster收集的數據比cadvisor多,卻全,而且存儲在influxdb的也少。

InfluxDB:時序數據庫,提供數據的存儲,存儲在指定的目錄下。

Grafana:提供了WEB控制檯,自定義查詢指標,從InfluxDB查詢數據,並展示。

Heapster是一個收集者,將每個Node上的cAdvisor的數據進行彙總,然後導到InfluxDB。Heapster的前提是使用cAdvisor採集每個node上主機和容器資源的使用情況,再將所有node上的數據進行聚合,這樣不僅可以看到Kubernetes集羣的資源情況,還可以分別查看每個node/namespace及每個node/namespace下pod的資源情況。這樣就可以從cluster,node,pod的各個層面提供詳細的資源使用情況。

2、kubernetes中主機監控方案:

prometheus

prometheus是個集 db、graph、statistic、alert 於一體的監控工具,安裝也非常簡單,下載包後做些參數的配置,比如監控的對象就可以運行了,默認通過9090端口訪問。

(1) 部署node-exporter容器

node-exporter 要在集羣的每臺主機上部署,使用主機網絡,端口是9100 如果有多個K8S集羣,則要在多個集羣上部署,部署node-exporter的命令如下:

# kubectl create -f node-exporter-deamonset.yaml

獲取metrics數據http://ip:9100/metrics

返回的數據結構不是json格式,如果要使用該接口返回的數據,可以通過正則匹配,匹配出需要的數據,然後在保存到數據庫中。

(2) 部署Prometheus和Grafana

Prometheus 通過配置文件發現新的節點,文件路徑是/sd/*.json,可以通過修改已有的配置文件,添加新的節點納入監控,命令如下:

# kubectl create -f prometheus-file-sd.yaml

(3)查看Prometheus監控的節點

Prometheus 的訪問地址是:http://192.168.xxx.xxx:31330

通過網頁查看監控的節點Status –> Targets

(4)另外可以配置Grafana展示Prometheus輸出的監控數據,配置儀表盤等。

Grafana 訪問地址是:http://192.168.xxx.xxx:31331

賬號:admin 密碼:admin

注:系統預置了幾個常用監控儀表盤配置,更多的配置可以到官方網站下載

五、監控工具的對比

以上從幾個典型的架構上介紹了一些監控,但都不是最優實踐。需要根據生產環境的特點結合每個監控產品的優勢來達到監控的目的。比如Grafana的圖表展示能力強,但是沒有告警的功能,那麼可以結合Prometheus在數據處理能力改善數據分析的展示。下面列了一些監控產品,但並不是嚴格按表格進行分類,比如Prometheus和Zabbix都有采集,展示,告警的功能。都可以瞭解一下,各取所長。

採集 cAdvisor, Heapster, collectd, Statsd, Tcollector, Scout
存儲 InfluxDb, OpenTSDB, Elasticsearch
展示 Graphite, Grafana, facette, Cacti, Ganglia, DataDog
告警 Nagios, prometheus, Icinga, Zabbix

今天分享的內容主要就是這些,有不懂的地方或者有講錯的地方歡迎大家提出,謝謝大家。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章