iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
DevOps

喬叔帶你上手 Elastic Stack - 探索與實踐 Observability系列 第 10

10 - Metrics - 觀察系統的健康指標 (4/6) - 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Docker 篇

Metrics - 觀察系統的健康指標 系列文章


本篇學習重點

  • 如何使用 Docker 來佈署 Metricbeat
  • 使用 Metricbeat 在 Docker 環境中,如何取得宿主實體機器或是整體 Docker Containers 的系統 Metrics
  • 如何透過 Metricbeat 輕鬆的來掌握 Docker 環境內的各 Containers 運作服務的健康狀態

使用 Docker 部署 Metricbeat

這篇要介紹的主題是 Docker ,因此這邊我們先來介紹如何使用 Docker 來部署 Metricbeat。[1]

Docker Image

Elastic 官方在 Docker @ Elastic 發佈了兩種版本的 Metricbeat Docker Image,底層是使用 CentOS 7。

  • beats/metricbeat
  • beats/metricbeat-oss

差別是什麼,老實說我稍微查了一下找不出差異,官方說授權的部份參考 Subscription 頁面,不過裡面針對 Metricbeat 的部份沒有描述到不同,不過大概可以確定的是 X-Pack 基本上是 Elastic License 的功能,所以 OSS 這個 Open Source 的版本應該是沒有 X-Pack 的功能的,至於其他的部份可能要再另外深入挖掘才知道。

不過由於 Elastic License 目前已經很寬鬆了,除了是要提供 SaaS 的服務,不然不太會踩到 License 的問題,接下來會用一般 Elastic License 的版本來操作。

可以透過 docker pull 取得 Docker Image,讓這個 image 下載到本機端。

docker pull docker.elastic.co/beats/metricbeat:7.15.0

透過 Docker 環境執行 Metricbeat 的 Setup

由於 Metricbeat 在第一次運行之前,我們會需要執行下面兩個動作:

  • 在 Elasticsearch 設定好 Metricbeat 要使用的 Index Template
  • 在 Kibana 匯入 Metricbeat 內建好的 Dashboard

這兩動作我們需要執行 ./metricbeat setup 的使令,所以在 Docker 的環境中,我們也要先單獨執行一次這個指令:

docker run \
docker.elastic.co/beats/metricbeat:7.15.0 \
setup -E setup.kibana.host=kibana:5601 \
-E output.elasticsearch.hosts=["elasticsearch:9200"]

這邊的 kibana:5601elasticsearch:9200 的位置,要自己視情況修改成正確的 Kibana 與 Elasticsearch 的位置。

使用 Docker 運行 Metricbeat

要開始運作 Metricbeat 也就是執行 docker run 並執行 metricbeat -e 的 Command:

docker run -d \
  --name=metricbeat \
  --user=root \
  --network=testnet \
  --volume="$(pwd)/metricbeat.docker.yml:/usr/share/metricbeat/metricbeat.yml:ro" \
  --volume="/var/run/docker.sock:/var/run/docker.sock:ro" \
  docker.elastic.co/beats/metricbeat:7.15.0 metricbeat -e \
  -E output.elasticsearch.hosts=["elasticsearch:9200"]  

啟動時有幾個參數可能會需要設置:

  • --user=root: 如果有使用 System Module 時,有些 socket 或是 system process 的資訊,會需要有足夠的權限才能存取,這部份的權限管理會需要留意。
  • --volume: 若是有獨立準備 metricbeat.yml 的 config 檔,會需要 mount 到 /usr/share/metricbeat/metricbeat.yml 的路徑上。
  • -E coutput.elasticsearch.hosts=: 如果沒有在 metricbeat.yml 特別設定,要使用環境變數指定 Elasticsesarch 的位置時,也要記得加上。
  • --net=: 如果有要透過 Metricbeat 去收集其他運作在 Docker Container 內服務的 Metrics,要記得 Network 的部份能夠存取得到。

在 Docker 環境中,Metricbeat 的設定方式

使用 Metricbeat 運行在 Docker Container 之中時,一般會有三大類要收集的 Metrics:

  1. 運行 Container 的實體主機的 System Metrics
  2. 每個 Docker Containers 的系統 Metrics
  3. 其他 Docker Containers 的服務 Metrics

以下我們分別來說明這些配置上的方式。

讓 Metricbeat 在 Docker Container 內取得實體主機的 System Metrics

由於 System Module 針對不同的 Metricset 會從幾個不同的系統位置取得資訊:

  • /proc: System Module 的許多資訊其實是來自這個 Linux proc filesystem 的位置。
  • /sys/fs/cgroup: System process 的 metricset 會從這個位置取得 process 的資訊。
  • /proc/net/dev: System network 的 metricset 會從這個位置取得網路的資訊。

因此我們會需要將這些主機實體位置,mount 到 Docker container 之中,讓運作在 Docker container 內的 Metricbeat 可以存取得到實體主機的這些資訊。

ocker run \
	--user root --cap-add sys_ptrace --cap-add dac_read_search \
  --mount type=bind,source=/proc,target=/hostfs/proc,readonly \ 
  --mount type=bind,source=/sys/fs/cgroup,target=/hostfs/sys/fs/cgroup,readonly \ 
  --mount type=bind,source=/,target=/hostfs,readonly \
  docker.elastic.co/beats/metricbeat:7.15.0 -e -system.hostfs=/hostfs

上面的例子是把這些路徑都 mount 在 container 內的 /hostfs 裡,並且在取後執行 metricbeat 時,加上參數指定這個位置 -system.hostfs=/hostfs

另外如果有使用 System socket 的 metricset 時,因為需要較高的權限,我們會需要特別加上 sys_ptracedac_read_search 的 System capability。

這邊要注意,上面提到的 /proc/sys、System capabilies…等設定是針對 Linux 環境,不適用於 Windows 或 MacOS。

使用 Metricbeat 取得整體 Docker Containers 的系統 Metrics

要使用 Metricbeat 來取得 Docker Containers 的資訊時,我們要使用的是 Metricbeat 裡的 Docker module。

./metricbeat modules enable docker

並且在要在 metricbeat.yml 裡,設定要收集的 docker metricsets,以及相關的配置。

metricbeat.modules:
- module: docker
  metricsets:
    - "container"
    - "cpu"
    - "diskio"
    - "healthcheck"
    - "info"
    #- "image"
    - "memory"
    - "network"
  hosts: ["unix:///var/run/docker.sock"]
  period: 10s
  enabled: true

這邊要注意到,由於 docker module 會透過 /var/run/docker.sock 與 docker 溝通,所以我們如果是運行在 Docker container 內的 Metricbeat,我們也會需要把實體主機的 /var/run/docker.sock mount 到 docker container 內,讓 Metricbeat 可以存取得到。

docker run -d \
  --volume="/var/run/docker.sock:/var/run/docker.sock:ro" \
  docker.elastic.co/beats/metricbeat:7.15.0 metricbeat -e \
  -E output.elasticsearch.hosts=["elasticsearch:9200"]  

使用 Metricbeat 取得其他 Docker Container 身上服務的 Metrics

要使用 Metricbeat 取得其他 Dockre Containre 所運作的服務的 Metrics 時,可以直接指定網路的位置,並且指定在相同的 docker network,讓 Metricbeat 可以存取得到其他服務,或是可以使用 Metricbeat 的 Autodiscover 功能。

由於在 Container 的環境之中,機器可能會時常開關,能夠動態的自動監控 Container 會比較實用,因此我們也就會以 Autodiscover 的介紹為主。

設置 Autodiscover 自動找尋需監控的機器 [2]

Metricbeat 的 Autodiscover 有支援兩種 Provider - DockerKubernetes ,這篇會以 Docker 為主要說明。

由於 Docker provider 會監聽 Docker events [3],在 Docker Container startstop 的時候,去更新需監控機器的列表,因此相關設定上,可以依照 Docker event 的資訊來進行篩選條件的設置,來決定哪些 container 要套用設定。

Docker event 的資訊如下:

{
  "host": "10.4.15.9",
  "port": 6379,
  "docker": {
    "container": {
      "id": "382184ecdb385cfd5d1f1a65f78911054c8511ae009635300ac28b4fc357ce51"
      "name": "redis",
      "image": "redis:3.2.11",
      "labels": {
        "io.kubernetes.pod.namespace": "default"
        ...
      }
    }
  }
}

這邊可以用來當篩選條件的欄位也就是:

  • host
  • port
  • docker.container.id
  • docker.container.image
  • docker.container.name
  • docker.container.labels

接下來是要在 metricbeat.yml 當中,設定 Autodiscover,並且依照上面提到的篩選條件,來設定 condition,決定哪些 container 是我們的目標對象。

metricbeat.autodiscover:
  providers:
    - type: docker
      labels.dedot: true
      templates:
        - condition:
            contains:
              docker.container.image: redis
          config:
            - module: redis
              metricsets: ["info", "keyspace"]
              hosts: "${data.host}:6379"

以上面的例子,目標是只要 Docker Image 是使用 redis 的 containers,就會是我們 auto discover 的目標,並且會 Redis module 來收集這些 containers 裡的資訊,相關的 Redis module 的設定,也會在 config 裡面去指定。

如此一來,在使用 Docker 動態增加或減少特定服務的 containers 時,我們的 Metricbeat 就會自動的去監控並收集 Metrics 的資訊了。

使用 Docker Autodiscover Provider 的 Hints 讓找機器更容易

Autodiscover 除了上述的使用 Docker event 方式來篩選之外,有提供針對 Docker Label 的標示來判定是否要監控的機制。

metricbeat.autodiscover:
  providers:
    - type: docker
      hints.enabled: true

要啟用這項功能,要把 hints.enabled: true 打開。

並且當我們要運作一個 Docker Container 時,就可以指定 Autodiscover 定義好的標籤 co.elastic.metrics,讓 Metricbeat 能認得這些 Containers。

以下是 Nginx 的一個例子:

  co.elastic.metrics/module: nginx
  co.elastic.metrics/metricsets: stubstatus
  co.elastic.metrics/hosts: '${data.host}:80'
  co.elastic.metrics/period: 10s

另外這是 Apache Server 的例子,並且實際用 Docker Run 時,如何加上標籤:

docker run \
  --label co.elastic.metrics/module=apache \
  --label co.elastic.metrics/metricsets=status \
  --label co.elastic.metrics/hosts='${data.host}:${data.port}' \
  --detach=true \
  --name my-apache-app \
  -p 8080:80 \
  httpd:2.4

在 Kibana 的 Metric Monitoring 掌握 Docker 環境的健康狀態

當 Metricbeat 把 Docker Container 相關的資訊開始進行收集後,我們就可以到 Kibana Observability 裡的 Metrics Inventory 頁面,並且選擇 Docker Containers 的呈現方式,來檢視 Docker Containers 裡的各項服務的狀態了。

10-Kibana-Metrics-Inventory-Docker-Container

Kibana Metrics 這邊的操作,可以參考前一篇 09 - Metrics - 觀察系統的健康指標 (3) - 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Host 篇 的介紹,這部份的差異不大,主要是 Docker 會有些特別針對 Docker 環境的數據檢視方式,這部份有興趣的讀者可以再去探索看看。

參考資料

  1. 官方文件 - Run Metricbeat on Docker
  2. 官方文件 - Metricbeat Autodiscover
  3. Docker events

上一篇
09 - Metrics - 觀察系統的健康指標 (3/6) - 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Host 篇
下一篇
11 - Metrics - 觀察系統的健康指標 (5/6) - 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Kubernetes 篇
系列文
喬叔帶你上手 Elastic Stack - 探索與實踐 Observability31

尚未有邦友留言

立即登入留言