使用 Elasticsearch 和 cAdvisor 監控 Docker 容器

2021-02-21 Linux中國

如果你正在運行 Swarm 模式的集群,或者只運行單臺 Docker,你都會有下面的疑問:

我如何才能監控到它們都在幹些什麼?

這個問題的答案是「很不容易」。

你需要監控下面的參數:

容器的數量和狀態。

一臺容器是否已經移到另一個節點了,如果是,那是在什麼時候,移動到哪個節點?

給定節點上運行著的容器數量。

一段時間內的通信峰值。

孤兒卷和網絡(LCTT 譯註:孤兒卷就是當你刪除容器時忘記刪除它的卷,這個卷就不會再被使用,但會一直佔用資源)。

可用磁碟空間、可用 inode 數。

容器數量與連接在 docker0 和 docker_gwbridge 上的虛擬網卡數量不一致(LCTT 譯註:當 docker 啟動時,它會在宿主機器上創建一個名為 docker0 的虛擬網絡接口)。

開啟和關閉 Swarm 節點。

收集併集中處理日誌。

本文的目標是介紹 Elasticsearch[1] + Kibana[2] + cAdvisor[3] 的用法,使用它們來收集 Docker 容器的參數,分析數據並產生可視化報表。

閱讀本文後你可以發現有一個監控儀錶盤能夠部分解決上述列出的問題。但如果只是使用 cAdvisor,有些參數就無法顯示出來,比如 Swarm 模式的節點。

如果你有一些 cAdvisor 或其他工具無法解決的特殊需求,我建議你開發自己的數據收集器和數據處理器(比如 Beats[4]),請注意我不會演示如何使用 Elasticsearch 來集中收集 Docker 容器的日誌。

「你要如何才能監控到 Swarm 模式集群裡面發生了什麼事情?要做到這點很不容易。」 —— @fntlnz[5]

我們為什麼要監控容器?

想像一下這個經典場景:你在管理一臺或多臺虛擬機,你把 tmux 工具用得很溜,用各種 session 事先設定好了所有基礎的東西,包括監控。然後生產環境出問題了,你使用top、htop、iotop、jnettop 各種 top 來排查,然後你準備好修復故障。

現在重新想像一下你有 3 個節點,包含 50 臺容器,你需要在一個地方查看整潔的歷史數據,這樣你知道問題出在哪個地方,而不是把你的生命浪費在那些字符界面來賭你可以找到問題點。

什麼是 Elastic Stack ?

Elastic Stack 就一個工具集,包括以下工具:

Elasticsearch

Kibana

Logstash

Beats

我們會使用其中一部分工具,比如使用 Elasticsearch 來分析基於 JSON 格式的文本,以及使用 Kibana 來可視化數據並產生報表。

另一個重要的工具是 Beats[6],但在本文中我們還是把精力放在容器上,官方的 Beats 工具不支持 Docker,所以我們選擇原生兼容 Elasticsearch 的 cAdvisor。

cAdvisor[7] 工具負責收集、整合正在運行的容器數據,並導出報表。在本文中,這些報表被到入到 Elasticsearch 中。

cAdvisor 有兩個比較酷的特性:

設置測試集群,或搭建自己的基礎架構

和我以前的文章[8]一樣,我習慣提供一個簡單的腳本,讓讀者不用花很多時間就能部署好和我一樣的測試環境。你可以使用以下(非生產環境使用的)腳本來搭建一個 Swarm 模式的集群,其中一個容器運行著 Elasticsearch。

如果你有充足的時間和經驗,你可以搭建自己的基礎架構Bring Your Own Infrastructure,BYOI。

如果要繼續閱讀本文,你需要:

重申一下,此 Elasticsearch 集群環境不能放在生產環境中使用。生產環境也不推薦使用單節點集群,所以如果你計劃安裝一個生產環境,請參考 Elastic 指南[9]。

對喜歡嘗鮮的用戶的友情提示

我就是一個喜歡嘗鮮的人(當然我也已經在生產環境中使用了最新的 alpha 版本),但是在本文中,我不會使用最新的 Elasticsearch 5.0.0 alpha 版本,我還不是很清楚這個版本的功能,所以我不想成為那個引導你們出錯的關鍵。

所以本文中涉及的 Elasticsearch 版本為最新穩定版 2.4.0。

測試集群部署腳本

前面已經說過,我提供這個腳本給你們,讓你們不必費神去部署 Swarm 集群和 Elasticsearch,當然你也可以跳過這一步,用你自己的 Swarm 模式引擎和你自己的 Elasticserch 節點。

執行這段腳本之前,你需要:

創建集群的腳本

現在萬事俱備,你可以把下面的代碼拷到 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 $@

賦予它可執行權限:

chmod +x create-cluster.sh

創建集群

如文件名所示,我們可以用它來創建集群。默認情況下這個腳本會創建一個 master 和兩個 worker,如果你想修改 worker 個數,可以設置環境變量 WORKERS。

現在就來創建集群吧。

./create-cluster.sh

你可以出去喝杯咖啡,因為這需要花點時間。

最後集群部署好了。

現在為了驗證 Swarm 模式集群已經正常運行,我們可以通過 ssh 登錄進 master:

docker-machine ssh master1

然後列出集群的節點:

docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

26fi3wiqr8lsidkjy69k031w2 *  master1   Ready   Active        Leader

dyluxpq8sztj7kmwlzs51u4id    worker2   Ready   Active

epglndegvixag0jztarn2lte8    worker1   Ready   Active

安裝 Elasticsearch 和 Kibana

注意,從現在開始所有的命令都運行在主節點 master1 上。

在生產環境中,你可能會把 Elasticsearch 和 Kibana 安裝在一個單獨的、大小合適[12]的實例集合中。但是在我們的實驗中,我們還是把它們和 Swarm 模式集群安裝在一起。

為了將 Elasticsearch 和 cAdvisor 連通,我們需要創建一個自定義的網絡,因為我們使用了集群,並且容器可能會分布在不同的節點上,我們需要使用 overlay[13] 網絡(LCTT 譯註:overlay 網絡是指在不改變現有網絡基礎設施的前提下,通過某種約定通信協議,把二層報文封裝在 IP 報文之上的新的數據格式,是目前最主流的容器跨節點數據傳輸和路由方案)。

也許你會問,「為什麼還要網絡?我們不是可以用 link 嗎?」 請考慮一下,自從引入用戶定義網絡後,link 機制就已經過時了。

以下內容摘自 Docker 文檔[14]:

在 Docker network 特性出來以前,你可以使用 Docker link 特性實現容器互相發現、安全通信。而在 network 特性出來以後,你還可以使用 link,但是當容器處於默認橋接網絡或用戶自定義網絡時,它們的表現是不一樣的。

現在創建 overlay 網絡,名稱為 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 節點,這是因為它運行時需要依賴 worker1 節點上掛載的卷。

Kibana 容器

docker service create --network=monitoring --name kibana -e ELASTICSEARCH_URL="http://elasticsearch:9200" -p 5601:5601 kibana:4.6.0

如你所見,我們啟動這兩個容器時,都讓它們加入 monitoring 網絡,這樣一來它們可以通過名稱(如 Kibana)被相同網絡的其他服務訪問。

現在,通過 routing mesh[15] 機制,我們可以使用瀏覽器訪問伺服器的 IP 地址來查看 Kibana 報表界面。

獲取 master1 實例的公共 IP 地址:

docker-machine ip master1

打開瀏覽器輸入地址:http://[master1 的 ip 地址]:5601/status

所有項目都應該是綠色:

讓我們接下來開始收集數據!

收集容器的運行數據

收集數據之前,我們需要創建一個服務,以全局模式運行 cAdvisor,為每個有效節點設置一個定時任務。

這個服務與 Elasticsearch 處於相同的網絡,以便於 cAdvisor 可以推送數據給 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 選項,參考這裡[16]。

現在 cAdvisor 在發送數據給 Elasticsearch,我們通過定義一個索引模型來檢索 Kibana 中的數據。有兩種方式可以做到這一點:通過 Kibana 或者通過 API。在這裡我們使用 API 方式實現。

我們需要在一個連接到 monitoring 網絡的正在運行的容器中運行索引創建命令,你可以在 cAdvisor 容器中拿到 shell,不幸的是 Swarm 模式在開啟服務時會在容器名稱後面附加一個唯一的 ID 號,所以你需要手動指定 cAdvisor 容器的名稱。

拿到 shell:

docker exec -ti <cadvisor-container-name> sh

創建索引:

curl -XPUT http://elasticsearch:9200/.kibana/index-pattern/cadvisor -d '{"title" : "cadvisor*",  "timeFieldName": "container_stats.timestamp"}'

如果你夠懶,可以只執行下面這一句:

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"}'

把數據匯總成報表

你現在可以使用 Kibana 來創建一份美觀的報表了。但是不要著急,我為你們建了一份報表和一些圖形界面來方便你們入門。

訪問 Kibana 界面 => Setting => Objects => Import,然後選擇包含以下內容的 JSON 文件,就可以導入我的配置信息了。(JSON 文件內容詳見原文)

這裡還有很多東西可以玩,你也許想自定義報表界面,比如添加內存頁錯誤狀態,或者收發包的丟包數。如果你能實現開頭列表處我沒能實現的項目,那也是很好的。

總結

正確監控需要大量時間和精力,容器的 CPU、內存、IO、網絡和磁碟,監控的這些參數還只是整個監控項目中的滄海一粟而已。

我不知道你做到了哪一階段,但接下來的任務也許是:

收集運行中的容器的日誌

收集應用的日誌

監控應用的性能

報警

監控健康狀態

如果你有意見或建議,請留言。祝你玩得開心。

現在你可以關掉這些測試系統了:

docker-machine rm master1 worker{1,2}

via: https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/

作者:Lorenzo Fontana[17] 譯者:bazz2 校對:wxy

本文由 LCTT[18] 原創編譯,Linux中國 榮譽推出

[1]: https://github.com/elastic/elasticsearch
[2]: https://github.com/elastic/kibana
[3]: https://github.com/google/cadvisor
[4]: https://github.com/elastic/beats
[5]: https://twitter.com/share?text=%22How+do+you+keep+track+of+all+that%27s+happening+in+a+Swarm+Mode+cluster%3F+Not+easily.%22+via+%40fntlnz&url=https://blog.codeship.com/monitoring-docker-containers-with-elasticsearch-and-cadvisor/
[6]: https://github.com/elastic/beats
[7]: https://github.com/google/cadvisor
[8]: https://blog.codeship.com/nginx-reverse-proxy-docker-swarm-clusters/
[9]: https://www.elastic.co/guide/en/elasticsearch/guide/2.x/deploy.html
[10]: https://docs.docker.com/machine/install-machine/
[11]: https://cloud.digitalocean.com/settings/api/tokens/new
[12]: https://www.elastic.co/blog/found-sizing-elasticsearch
[13]: https://docs.docker.com/engine/userguide/networking/get-started-overlay/
[14]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/
[15]: https://docs.docker.com/engine/swarm/ingress/
[16]: https://github.com/google/cadvisor/blob/master/docs/runtime_options.md
[17]: https://blog.codeship.com/author/lorenzofontana/
[18]: https://github.com/LCTT/TranslateProject

推薦文章

將文章分享給朋友是對我們最好的讚賞!

相關焦點

  • cAdvisor + Prometheus收集本機和docker容器數據
    cAdvisor + Prometheus收集本機和docker容器數據在這個萬物皆可容器化的時代,監控顯的尤為重要,在本篇文章,我們將對伺服器的相關容器和本機數據利用
  • 你必須知道的容器監控 (2) cAdvisor
    上一篇我們了解了docker自帶的監控子命令以及開源監控工具Weave Scope,這一篇我們來了解一下Google開發的容器監控工具cAdvisor。cAdvisor能夠較好地展示Host和容器兩個層次的監控數據,並且能夠展示歷史變化數據。
  • 使用Cadvisor監控Docker容器
    點擊上面的👆藍色文字,關注我們:)cAdvisor(container Advisor)分析並展示容器運行時的資源使用和性能數據
  • Docker簡易搭建 ElasticSearch 集群
    --name ES01 elasticsearch:5.6.8  docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9201:9201 -p 9301:9301 -v /home/soft/ES/config/es2.yml:/usr/share/elasticsearch/config/elasticsearch.yml -
  • 數據收集利器 cAdvisor - 每天5分鐘玩轉 Docker 容器技術(82)
    8080:8080 \  --detach=true \  --name=cadvisor \  google/cadvisor:latest通過 http://[Host_IP]:8080 訪問 cAdvisor。
  • elasticsearch和kibana的保姆級安裝教程
    目錄導航為什麼使用docker容器部署這些應用elasticsearch安裝安裝kibana安裝ik分詞器插件安裝elasticsearch-head插件參考文獻>為什麼使用docker容器部署這些應用什麼是dockerdocker是一種容器技術,可對軟體運行環境進行封裝,docker容器和虛擬機模型類似,區別在於容器的運行不會獨佔作業系統,適應了雲計算時代按需配置資源的模式。
  • Docker啟動MySQL、MongoDB、Redis、Elasticsearch、Grafana,資料庫
    前言:臨時使用資料庫時可以使用docker運行,這樣可以防止在系統上安裝破壞環境,同時使用docker啟動會比在系統中安裝配置要快速
  • Docker 如何安裝 ElasticSearch+ik 分詞器 +es-head 可視化插件
    三、docker 安裝 Elasticsearch1、拉去鏡像docker pull docker.io/elasticsearch:版本號docker pull docker.io/elasticsearch:7.1.12
  • 使用ElasticSearch,Kibana,ASP.NET Core和Docker可視化數據
    原文地址:http://www.dotnetcurry.com/aspnet/1354/elastic-search-kibana-in-docker-dotnet-core-app
  • Elastic Search入門:架構說明及Docker方式體驗
    但是Luncence的主要問題有兩點,其一是只支持Java類庫的調用方式,學習和使用門檻很高,其二是Luncence沒有線性擴展能力。搜索又是一個幾乎隨業務量線性擴張的功能,所以是否支持線性拓展資源很重要。ES其實是對Luncence的庫的上層封裝,通過Restful的形式可以讓日誌的構建和檢索等功能更容易在多語言環境下調用,做到即使是開發小白也能快速上手。
  • ELK 完整部署和使用 - 每天5分鐘玩轉 Docker 容器技術(90)
    幾乎所有的軟體和應用都有自己的日誌文件,容器也不例外。前面我們已經知道 Docker 會將容器日誌記錄到 /var/lib/docker/containers/<contariner ID>/<contariner ID>-json.log,那麼只要我們能夠將此文件發送給 ELK 就可以實現日誌管理。
  • Elasticsearch--分詞-自定義擴展詞庫---全文檢索引擎ElasticSearch工作筆記022
    然後我們再去看一下docker iamges 可以看到現在我們有elasticsearch,kibana,redis,mysql這幾個鏡像,我們還沒有nginx的鏡像.,以後我們的html就放到虛擬機上就可以了不用每次都,進入到docker容器中了,麻煩.
  • ​打開ElasticSearch、kibana、logstash的正確方式
    :為容器起一個別名# -p:將容器的運行埠映射到本地埠# -e "discovery.type=single-node":表示單節點模式下創建,後文將介紹集群模式的搭建# -v:表示將容器中的配置文件和data文件映射到上文本地所創建的文件,方便後面的配置# 將elasticsearch容器設置為開機自啟動docker update new-elasticsearch
  • Spring Boot整合Elasticsearch
    這是我們的application.yml文件的片段,它覆蓋了默認的集群名稱和地址,以及在Docker容器上啟動的Elasticsearch的地址:spring: data: elasticsearch: cluster-name: docker-cluster
  • Elasticsearch安裝中文分詞器analysis-ik插件和簡單使用
    一、安裝中文分詞器插件國內最常用的:elasticsearch-analysis-ik
  • 監控 Elasticsearch 及 Kibana
    我們可以使用一個專有的 Elasticsearch 集群來監視一個生產環境的 Elasticsearch 集群。在今天的幾篇中,我將詳細講述如何來對 Elastic Stack 的各個軟體棧進行監控。儘管我們可以使用把 Elasticsearch 自己的狀態信息導入到自己的索引中以進行分析,但是在實際的使用中,我們還是傾向於設置一個專用的 Elasticsearch 集群來進行監控,原因是:在生產環境中,通常的監視框架圖為:使用 Metricbeat 進行監視,可將所有數據直接路由到監視群集,而完全無需接觸生產群集你可以使用 Metricbeat 將有關
  • 使用 Elastic 技術棧構建 Kubernetes 全棧監控(完結)
    Elastic 技術棧構建 Kubernetes 全棧監控,使用 Elastic 技術棧構建 Kubernetes 全棧監控(二)Elastic APM 是 Elastic Stack 上用於應用性能監控的工具,它允許我們通過收集傳入請求、資料庫查詢、緩存調用等方式來實時監控應用性能。
  • ElasticSearch性感體驗
    Elasticsearch是個開源分布式搜尋引擎,提供搜集、分析、存儲數據三大功能。它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful 風格接口,多數據源,自動搜索負載等。Kibana也是一個開源和免費的工具,Kibana可以為Logstash和ElasticSearch提供的日誌分析友好的Web界面,可以幫助匯總、分析和搜索重要數據日誌。
  • elasticsearch入門實戰
    1.介紹Elasticsearch 是一個高度可擴展的開源全文搜索和分析引擎。
  • Fluentd+Elasticsearch+kibana 日誌收集部署實戰
    ELK是一套非常成熟的系統,她本身的構架非常適合Kubernetes集群,這裡官網當中也是選用的 Elasticsearch作為Sample的,GitHub上下載的kubernetes二進位包中本身就有這個.yaml文件,所以使用ELK作為收集日誌的理由相當充分。 對於任何基礎設施或後端服務系統,日誌都是極其重要的。