如何使用Elasticsearch和cAdvisor監(jiān)控Docker容器
如果你正在運(yùn)行 Swarm 模式的集群,或者只運(yùn)行單臺 Docker,你都會有下面的疑問:
我如何才能監(jiān)控到它們都在干些什么?這個(gè)問題的答案是“很不容易”。
你需要監(jiān)控下面的參數(shù):
- 容器的數(shù)量和狀態(tài)。
- 一臺容器是否已經(jīng)移到另一個(gè)節(jié)點(diǎn)了,如果是,那是在什么時(shí)候,移動到哪個(gè)節(jié)點(diǎn)?
- 給定節(jié)點(diǎn)上運(yùn)行著的容器數(shù)量。
- 一段時(shí)間內(nèi)的通信峰值。
- 孤兒卷和網(wǎng)絡(luò)(LCTT 譯注:孤兒卷就是當(dāng)你刪除容器時(shí)忘記刪除它的卷,這個(gè)卷就不會再被使用,但會一直占用資源)。
- 可用磁盤空間、可用 inode 數(shù)。
- 容器數(shù)量與連接在 docker0 和 docker_gwbridge 上的虛擬網(wǎng)卡數(shù)量不一致(LCTT 譯注:當(dāng) docker 啟動時(shí),它會在宿主機(jī)器上創(chuàng)建一個(gè)名為 docker0 的虛擬網(wǎng)絡(luò)接口)。
- 開啟和關(guān)閉 Swarm 節(jié)點(diǎn)。
- 收集并集中處理日志。
本文的目標(biāo)是介紹 Elasticsearch + Kibana + cAdvisor 的用法,使用它們來收集 Docker 容器的參數(shù),分析數(shù)據(jù)并產(chǎn)生可視化報(bào)表。
閱讀本文后你可以發(fā)現(xiàn)有一個(gè)監(jiān)控儀表盤能夠部分解決上述列出的問題。但如果只是使用 cAdvisor,有些參數(shù)就無法顯示出來,比如 Swarm 模式的節(jié)點(diǎn)。
如果你有一些 cAdvisor 或其他工具無法解決的特殊需求,我建議你開發(fā)自己的數(shù)據(jù)收集器和數(shù)據(jù)處理器(比如Beats),請注意我不會演示如何使用 Elasticsearch 來集中收集 Docker 容器的日志。
“你要如何才能監(jiān)控到 Swarm 模式集群里面發(fā)生了什么事情?要做到這點(diǎn)很不容易。” —— @fntlnz
我們?yōu)槭裁匆O(jiān)控容器?
想象一下這個(gè)經(jīng)典場景:你在管理一臺或多臺虛擬機(jī),你把 tmux 工具用得很溜,用各種 session 事先設(shè)定好了所有基礎(chǔ)的東西,包括監(jiān)控。然后生產(chǎn)環(huán)境出問題了,你使用 top、htop、iotop、jnettop 各種 top 來排查,然后你準(zhǔn)備好修復(fù)故障。
現(xiàn)在重新想象一下你有 3 個(gè)節(jié)點(diǎn),包含 50 臺容器,你需要在一個(gè)地方查看整潔的歷史數(shù)據(jù),這樣你知道問題出在哪個(gè)地方,而不是把你的生命浪費(fèi)在那些字符界面來賭你可以找到問題點(diǎn)。
什么是 Elastic Stack ?
Elastic Stack 就一個(gè)工具集,包括以下工具:
- Elasticsearch
- Kibana
- Logstash
- Beats
我們會使用其中一部分工具,比如使用 Elasticsearch 來分析基于 JSON 格式的文本,以及使用 Kibana 來可視化數(shù)據(jù)并產(chǎn)生報(bào)表。
另一個(gè)重要的工具是 Beats,但在本文中我們還是把精力放在容器上,官方的 Beats 工具不支持 Docker,所以我們選擇原生兼容 Elasticsearch 的 cAdvisor。
cAdvisor 工具負(fù)責(zé)收集、整合正在運(yùn)行的容器數(shù)據(jù),并導(dǎo)出報(bào)表。在本文中,這些報(bào)表被到入到 Elasticsearch 中。
cAdvisor 有兩個(gè)比較酷的特性:
- 它不只局限于 Docker 容器。
- 它有自己的 Web 服務(wù)器,可以簡單地顯示當(dāng)前節(jié)點(diǎn)的可視化報(bào)表。
設(shè)置測試集群,或搭建自己的基礎(chǔ)架構(gòu)
和我以前的文章一樣,我習(xí)慣提供一個(gè)簡單的腳本,讓讀者不用花很多時(shí)間就能部署好和我一樣的測試環(huán)境。你可以使用以下(非生產(chǎn)環(huán)境使用的)腳本來搭建一個(gè) Swarm 模式的集群,其中一個(gè)容器運(yùn)行著 Elasticsearch。
如果你有充足的時(shí)間和經(jīng)驗(yàn),你可以搭建自己的基礎(chǔ)架構(gòu)Bring Your Own Infrastructure,BYOI。如果要繼續(xù)閱讀本文,你需要:
- 運(yùn)行 Docker 進(jìn)程的一個(gè)或多個(gè)節(jié)點(diǎn)(docker 版本號大于等于 1.12)。
- 至少有一個(gè)獨(dú)立運(yùn)行的 Elasticsearch 節(jié)點(diǎn)(版本號 2.4.X)。
重申一下,此 Elasticsearch 集群環(huán)境不能放在生產(chǎn)環(huán)境中使用。生產(chǎn)環(huán)境也不推薦使用單節(jié)點(diǎn)集群,所以如果你計(jì)劃安裝一個(gè)生產(chǎn)環(huán)境,請參考 Elastic 指南。
對喜歡嘗鮮的用戶的友情提示
我就是一個(gè)喜歡嘗鮮的人(當(dāng)然我也已經(jīng)在生產(chǎn)環(huán)境中使用了最新的 alpha 版本),但是在本文中,我不會使用最新的 Elasticsearch 5.0.0 alpha 版本,我還不是很清楚這個(gè)版本的功能,所以我不想成為那個(gè)引導(dǎo)你們出錯(cuò)的關(guān)鍵。
所以本文中涉及的 Elasticsearch 版本為最新穩(wěn)定版 2.4.0。
測試集群部署腳本
前面已經(jīng)說過,我提供這個(gè)腳本給你們,讓你們不必費(fèi)神去部署 Swarm 集群和 Elasticsearch,當(dāng)然你也可以跳過這一步,用你自己的 Swarm 模式引擎和你自己的 Elasticserch 節(jié)點(diǎn)。
執(zhí)行這段腳本之前,你需要:
Docker Machine – 最終版:在 DigitalOcean 中提供 Docker 引擎。
DigitalOcean API Token: 讓 docker 機(jī)器按照你的意思來啟動節(jié)點(diǎn)。
創(chuàng)建集群的腳本
現(xiàn)在萬事俱備,你可以把下面的代碼拷到 create-cluster.sh 文件中:
- #!/usr/bin/env bash
- #
- # Create a Swarm Mode cluster with a single master and a configurable number of workers
- workers=${WORKERS:-"worker1 worker2"}
- #######################################
- # Creates a machine on Digital Ocean
- # Globals:
- # DO_ACCESS_TOKEN The token needed to access DigitalOcean's API
- # Arguments:
- # $1 the actual name to give to the machine
- #######################################
- create_machine() {
- docker-machine create \
- -d digitalocean \
- --digitalocean-access-token=$DO_ACCESS_TOKEN \
- --digitalocean-size 2gb \
- $1
- }
- #######################################
- # Executes a command on the specified machine
- # Arguments:
- # $1 The machine on which to run the command
- # $2..$n The command to execute on that machine
- #######################################
- machine_do() {
- docker-machine ssh $@
- }
- main() {
- if [ -z "$DO_ACCESS_TOKEN" ]; then
- echo "Please export a DigitalOcean Access token: https://cloud.digitalocean.com/settings/api/tokens/new"
- echo "export DO_ACCESS_TOKEN=<yourtokenhere>"
- exit 1
- fi
- if [ -z "$WORKERS" ]; then
- echo "You haven't provided your workers by setting the \$WORKERS environment variable, using the default ones: $workers"
- fi
- # Create the first and only master
- echo "Creating the master"
- create_machine master1
- master_ip=$(docker-machine ip master1)
- # Initialize the swarm mode on it
- echo "Initializing the swarm mode"
- machine_do master1 docker swarm init --advertise-addr $master_ip
- # Obtain the token to allow workers to join
- worker_tkn=$(machine_do master1 docker swarm join-token -q worker)
- echo "Worker token: ${worker_tkn}"
- # Create and join the workers
- for worker in $workers; do
- echo "Creating worker ${worker}"
- create_machine $worker
- machine_do $worker docker swarm join --token $worker_tkn $master_ip:2377
- done
- }
- main $@
賦予它可執(zhí)行權(quán)限:
- chmod +x create-cluster.sh
創(chuàng)建集群
如文件名所示,我們可以用它來創(chuàng)建集群。默認(rèn)情況下這個(gè)腳本會創(chuàng)建一個(gè) master 和兩個(gè) worker,如果你想修改 worker 個(gè)數(shù),可以設(shè)置環(huán)境變量 WORKERS。
現(xiàn)在就來創(chuàng)建集群吧。
- ./create-cluster.sh
你可以出去喝杯咖啡,因?yàn)檫@需要花點(diǎn)時(shí)間。
最后集群部署好了。
現(xiàn)在為了驗(yàn)證 Swarm 模式集群已經(jīng)正常運(yùn)行,我們可以通過 ssh 登錄進(jìn) master:
- docker-machine ssh master1
然后列出集群的節(jié)點(diǎn):
- docker node ls
- ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
- 26fi3wiqr8lsidkjy69k031w2 * master1 Ready Active Leader
- dyluxpq8sztj7kmwlzs51u4id worker2 Ready Active
- epglndegvixag0jztarn2lte8 worker1 Ready Active
安裝 Elasticsearch 和 Kibana
注意,從現(xiàn)在開始所有的命令都運(yùn)行在主節(jié)點(diǎn) master1 上。在生產(chǎn)環(huán)境中,你可能會把 Elasticsearch 和 Kibana 安裝在一個(gè)單獨(dú)的、大小合適的實(shí)例集合中。但是在我們的實(shí)驗(yàn)中,我們還是把它們和 Swarm 模式集群安裝在一起。
為了將 Elasticsearch 和 cAdvisor 連通,我們需要創(chuàng)建一個(gè)自定義的網(wǎng)絡(luò),因?yàn)槲覀兪褂昧思?,并且容器可能會分布在不同的?jié)點(diǎn)上,我們需要使用 overlay 網(wǎng)絡(luò)(LCTT 譯注:overlay 網(wǎng)絡(luò)是指在不改變現(xiàn)有網(wǎng)絡(luò)基礎(chǔ)設(shè)施的前提下,通過某種約定通信協(xié)議,把二層報(bào)文封裝在 IP 報(bào)文之上的新的數(shù)據(jù)格式,是目前最主流的容器跨節(jié)點(diǎn)數(shù)據(jù)傳輸和路由方案)。
也許你會問,“為什么還要網(wǎng)絡(luò)?我們不是可以用 link 嗎?” 請考慮一下,自從引入用戶定義網(wǎng)絡(luò)后,link 機(jī)制就已經(jīng)過時(shí)了。
以下內(nèi)容摘自 Docker 文檔:
在 Docker network 特性出來以前,你可以使用 Docker link 特性實(shí)現(xiàn)容器互相發(fā)現(xiàn)、安全通信。而在 network 特性出來以后,你還可以使用 link,但是當(dāng)容器處于默認(rèn)橋接網(wǎng)絡(luò)或用戶自定義網(wǎng)絡(luò)時(shí),它們的表現(xiàn)是不一樣的?,F(xiàn)在創(chuàng)建 overlay 網(wǎng)絡(luò),名稱為 monitoring:
- docker network create monitoring -d overlay
Elasticsearch 容器
- docker service create --network=monitoring \
- --mount type=volume,target=/usr/share/elasticsearch/data \
- --constraint node.hostname==worker1 \
- --name elasticsearch elasticsearch:2.4.0
注意 Elasticsearch 容器被限定在 worker1 節(jié)點(diǎn),這是因?yàn)樗\(yùn)行時(shí)需要依賴 worker1 節(jié)點(diǎn)上掛載的卷。
Kibana 容器
- docker service create --network=monitoring --name kibana -e ELASTICSEARCH_URL="http://elasticsearch:9200" -p 5601:5601 kibana:4.6.0
如你所見,我們啟動這兩個(gè)容器時(shí),都讓它們加入 monitoring 網(wǎng)絡(luò),這樣一來它們可以通過名稱(如 Kibana)被相同網(wǎng)絡(luò)的其他服務(wù)訪問。
現(xiàn)在,通過 routing mesh 機(jī)制,我們可以使用瀏覽器訪問服務(wù)器的 IP 地址來查看 Kibana 報(bào)表界面。
獲取 master1 實(shí)例的公共 IP 地址:
- docker-machine ip master1
打開瀏覽器輸入地址:http://[master1 的 ip 地址]:5601/status
所有項(xiàng)目都應(yīng)該是綠色:
讓我們接下來開始收集數(shù)據(jù)!
收集容器的運(yùn)行數(shù)據(jù)
收集數(shù)據(jù)之前,我們需要創(chuàng)建一個(gè)服務(wù),以全局模式運(yùn)行 cAdvisor,為每個(gè)有效節(jié)點(diǎn)設(shè)置一個(gè)定時(shí)任務(wù)。
這個(gè)服務(wù)與 Elasticsearch 處于相同的網(wǎng)絡(luò),以便于 cAdvisor 可以推送數(shù)據(jù)給 Elasticsearch。
- docker service create --network=monitoring --mode global --name cadvisor \
- --mount type=bind,source=/,target=/rootfs,readonly=true \
- --mount type=bind,source=/var/run,target=/var/run,readonly=false \
- --mount type=bind,source=/sys,target=/sys,readonly=true \
- --mount type=bind,source=/var/lib/docker/,target=/var/lib/docker,readonly=true \
- google/cadvisor:latest \
- -storage_driver=elasticsearch \
- -storage_driver_es_host="http://elasticsearch:9200"
注意:如果你想配置 cAdvisor 選項(xiàng),參考這里?,F(xiàn)在 cAdvisor 在發(fā)送數(shù)據(jù)給 Elasticsearch,我們通過定義一個(gè)索引模型來檢索 Kibana 中的數(shù)據(jù)。有兩種方式可以做到這一點(diǎn):通過 Kibana 或者通過 API。在這里我們使用 API 方式實(shí)現(xiàn)。
我們需要在一個(gè)連接到 monitoring 網(wǎng)絡(luò)的正在運(yùn)行的容器中運(yùn)行索引創(chuàng)建命令,你可以在 cAdvisor 容器中拿到 shell,不幸的是 Swarm 模式在開啟服務(wù)時(shí)會在容器名稱后面附加一個(gè)唯一的 ID 號,所以你需要手動指定 cAdvisor 容器的名稱。
拿到 shell:
- docker exec -ti <cadvisor-container-name> sh
創(chuàng)建索引:
- curl -XPUT http://elasticsearch:9200/.kibana/index-pattern/cadvisor -d '{"title" : "cadvisor*", "timeFieldName": "container_stats.timestamp"}'
如果你夠懶,可以只執(zhí)行下面這一句:
- docker exec $(docker ps | grep cadvisor | awk '{print $1}' | head -1) curl -XPUT http://elasticsearch:9200/.kibana/index-pattern/cadvisor -d '{"title" : "cadvisor*", "timeFieldName": "container_stats.timestamp"}'
把數(shù)據(jù)匯總成報(bào)表
你現(xiàn)在可以使用 Kibana 來創(chuàng)建一份美觀的報(bào)表了。但是不要著急,我為你們建了一份報(bào)表和一些圖形界面來方便你們?nèi)腴T。
訪問 Kibana 界面 => Setting => Objects => Import,然后選擇包含以下內(nèi)容的 JSON 文件,就可以導(dǎo)入我的配置信息了:
- [
- {
- "_id": "cAdvisor",
- "_type": "dashboard",
- "_source": {
- "title": "cAdvisor",
- "hits": 0,
- "description": "",
- "panelsJSON": "[{\"id\":\"Filesystem-usage\",\"type\":\"visualization\",\"panelIndex\":1,\"size_x\":6,\"size_y\":3,\"col\":1,\"row\":1},{\"id\":\"Memory-[Node-equal->Container]\",\"type\":\"visualization\",\"panelIndex\":2,\"size_x\":6,\"size_y\":4,\"col\":7,\"row\":4},{\"id\":\"memory-usage-by-machine\",\"type\":\"visualization\",\"panelIndex\":3,\"size_x\":6,\"size_y\":6,\"col\":1,\"row\":4},{\"id\":\"CPU-Total-Usage\",\"type\":\"visualization\",\"panelIndex\":4,\"size_x\":6,\"size_y\":5,\"col\":7,\"row\":8},{\"id\":\"Network-RX-TX\",\"type\":\"visualization\",\"panelIndex\":5,\"size_x\":6,\"size_y\":3,\"col\":7,\"row\":1}]",
- "optionsJSON": "{\"darkTheme\":false}",
- "uiStateJSON": "{}",
- "version": 1,
- "timeRestore": false,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}}}]}"
- }
- }
- },
- {
- "_id": "Network",
- "_type": "search",
- "_source": {
- "title": "Network",
- "description": "",
- "hits": 0,
- "columns": [
- "machine_name",
- "container_Name",
- "container_stats.network.name",
- "container_stats.network.interfaces",
- "container_stats.network.rx_bytes",
- "container_stats.network.rx_packets",
- "container_stats.network.rx_dropped",
- "container_stats.network.rx_errors",
- "container_stats.network.tx_packets",
- "container_stats.network.tx_bytes",
- "container_stats.network.tx_dropped",
- "container_stats.network.tx_errors"
- ],
- "sort": [
- "container_stats.timestamp",
- "desc"
- ],
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@/kibana-highlighted-field@\"],\"fields\":{\"*\":{}},\"fragment_size\":2147483647},\"filter\":[]}"
- }
- }
- },
- {
- "_id": "Filesystem-usage",
- "_type": "visualization",
- "_source": {
- "title": "Filesystem usage",
- "visState": "{\"title\":\"Filesystem usage\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"defaultYExtents\":false,\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.filesystem.usage\",\"customLabel\":\"USED\"}},{\"id\":\"2\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":false}},{\"id\":\"3\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.filesystem.capacity\",\"customLabel\":\"AVAIL\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.filesystem.device\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}",
- "uiStateJSON": "{\"vis\":{\"colors\":{\"Average container_stats.filesystem.available\":\"#E24D42\",\"Average container_stats.filesystem.base_usage\":\"#890F02\",\"Average container_stats.filesystem.capacity\":\"#3F6833\",\"Average container_stats.filesystem.usage\":\"#E24D42\",\"USED\":\"#BF1B00\",\"AVAIL\":\"#508642\"}}}",
- "description": "",
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}},\"filter\":[]}"
- }
- }
- },
- {
- "_id": "CPU-Total-Usage",
- "_type": "visualization",
- "_source": {
- "title": "CPU Total Usage",
- "visState": "{\"title\":\"CPU Total Usage\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.cpu.usage.total\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"container_Name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":true}}],\"listeners\":{}}",
- "uiStateJSON": "{}",
- "description": "",
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}"
- }
- }
- },
- {
- "_id": "memory-usage-by-machine",
- "_type": "visualization",
- "_source": {
- "title": "Memory [Node]",
- "visState": "{\"title\":\"Memory [Node]\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.memory.usage\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}",
- "uiStateJSON": "{}",
- "description": "",
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}"
- }
- }
- },
- {
- "_id": "Network-RX-TX",
- "_type": "visualization",
- "_source": {
- "title": "Network RX TX",
- "visState": "{\"title\":\"Network RX TX\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":true,\"addTooltip\":true,\"defaultYExtents\":false,\"mode\":\"stacked\",\"scale\":\"linear\",\"setYExtents\":false,\"shareYAxis\":true,\"times\":[],\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.network.rx_bytes\",\"customLabel\":\"RX\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"s\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.network.tx_bytes\",\"customLabel\":\"TX\"}}],\"listeners\":{}}",
- "uiStateJSON": "{\"vis\":{\"colors\":{\"RX\":\"#EAB839\",\"TX\":\"#BF1B00\"}}}",
- "description": "",
- "savedSearchId": "Network",
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"filter\":[]}"
- }
- }
- },
- {
- "_id": "Memory-[Node-equal->Container]",
- "_type": "visualization",
- "_source": {
- "title": "Memory [Node=>Container]",
- "visState": "{\"title\":\"Memory [Node=>Container]\",\"type\":\"area\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"smoothLines\":false,\"scale\":\"linear\",\"interpolate\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"container_stats.memory.usage\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"container_stats.timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"container_Name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"machine_name\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"row\":true}}],\"listeners\":{}}",
- "uiStateJSON": "{}",
- "description": "",
- "version": 1,
- "kibanaSavedObjectMeta": {
- "searchSourceJSON": "{\"index\":\"cadvisor*\",\"query\":{\"query_string\":{\"query\":\"* NOT container_Name.raw: \\\\\\\"/\\\\\\\" AND NOT container_Name.raw: \\\\\\\"/docker\\\\\\\"\",\"analyze_wildcard\":true}},\"filter\":[]}"
- }
- }
- }
- ]
這里還有很多東西可以玩,你也許想自定義報(bào)表界面,比如添加內(nèi)存頁錯(cuò)誤狀態(tài),或者收發(fā)包的丟包數(shù)。如果你能實(shí)現(xiàn)開頭列表處我沒能實(shí)現(xiàn)的項(xiàng)目,那也是很好的。
總結(jié)
正確監(jiān)控需要大量時(shí)間和精力,容器的 CPU、內(nèi)存、IO、網(wǎng)絡(luò)和磁盤,監(jiān)控的這些參數(shù)還只是整個(gè)監(jiān)控項(xiàng)目中的滄海一粟而已。
我不知道你做到了哪一階段,但接下來的任務(wù)也許是:
- 收集運(yùn)行中的容器的日志
- 收集應(yīng)用的日志
- 監(jiān)控應(yīng)用的性能
- 報(bào)警
- 監(jiān)控健康狀態(tài)
如果你有意見或建議,請留言。祝你玩得開心。
現(xiàn)在你可以關(guān)掉這些測試系統(tǒng)了:
- docker-machine rm master1 worker{1,2}