使用 Heartbeat 收集系統生命徵象數據

本篇學習重點

  • Elastic Heartbeat 簡介

  • 如何安裝及設定 Heartbeat 來收集系統的生命徵象數據

  • 使用 Heartbeat 時有哪些實用的技巧

什麼是 Heartbeat

Elastic Beats 是 Elastic Stack 中專門負責收集散落在各地的 Log 及各種資訊的一系列工具,Beats 家族的主要都是基於 libbeat framework 所開發,而 Heartbeat 是 Elastic Beats 家族的成員之一,是一個輕量化的常駐程式 (daemon),可以安裝在遠端的某一台機器上,並且定期的去檢查指定的服務是否還活著 (availability)。

Heartbeat 支援的監控方法有以下幾種:

  • ICMP (v4 or v6): 也就是我們很常在使用的 ping 這個指令所使用的 protocol,可以提供最基本的驗證,確認機器是否能正常的回應。

  • TCP: 可以針對特別的 TCP port 去發送指定的請求,並且傳送指定的 payload,也可以驗證回傳的 payload。

  • HTTP: 這個協定也是 Heartbeat 最常被使用到的通訊協定,像是我們 API 常用的 RESTful 協定,就可以透過 Heartbeat 發送請求,並且驗證 HTTP 回傳的 status coderesponse headerresponse body 是不是符合預期。

  • Browser: 這個功能很強,是目前最新、但還在實驗階段 (Experimental) 的功能,也就是收集 Elastic Observability 當中的 Synthetic Data 的功能,簡單來說他會模擬瀏覽器,來執行一系列我們指定的步驟,我們就可以依照使用者實際的情境,一步一步的模擬、並且驗證執行的結果,同時也會產生螢幕截圖讓我們知道執行的結果為何。這個功能會再下一篇文章進行介紹。

另外針對 TCPHTTP 都有支援 SSL/TLS 的 HTTPS 協定,也能支援 proxy 的設定,最貼心的是,他還能順便記錄 HTTPS 的憑證 (certificate) 的過期時間,我們也就能簡單的透過 Alert 的設定,在憑證過期之前發出警告。

Heartbeat 的使用情境

以下列出 Heartbeat 可以使用的一些情境,當然能用的範圍不只於此,我們也可以依照他的功能特性來創造合符合需求的應用情境。

  1. 從各個不同的地區、Data Center、檢查服務是否活著。

  2. 在複雜的網路環境中,從各網段監控服務可否被存取,透過這些數據協助判斷網路是否有狀況,是否哪個網段無法正常存取服務。

  3. 除了檢查服務是否活著,同時因為有收集回應的時間,所以也能確認是否有延遲時間更長、甚至導入於過時 (timeout) 的現象。

  4. 當我們與客戶有協議 SLA (Service Level Agreement) 時,透過 Heartbeat 收集的資料,透過 Kibana 彙總成報表,可以清楚的驗證我們是否有達到我們所承諾的 SLA。

  5. 反向的安全性檢查,例如我們不允許外網能存取到服務,可以透過 Heartbeat 從外網週期的驗證,服務不能被存取到。

  6. 針對特定服務存取的 API,定期驗證特定功能的正常狀態。

  7. 由於支援 Proxy,若商業服務的目標市場大量依賴於手機端用戶,甚至可以透過 proxy 使用當地的 ISP 的手機網路來當作跳板,驗證指定的 ISP 所提供的手機網路是否能正常存取服務。(以喬叔的經驗,就有發生在日本特定的 ISP 無法存取服務,但其他 ISP 卻可以使用的經驗,這時若是需要舉證,有這些日誌與記錄會非常有幫助)

  8. 在協助驗證服務的可用性 (availability) 時,一併協助驗證 HTTPS 的憑證是否快要過期,這部份也是服務可用性很重要的一點,而且從過往的新聞之中,有些很大很厲害的公司,也還是會發生不小心憑證過期忘了更新,而影響到用戶使用的案例。

安裝 Heartbeat

要安裝 Heartbeat,官方網站的快速上手文件 [1],已經非常的清楚簡單,我這邊就不做細部說明,只大約以 MacOS 環境為例,列出以下的步驟:

  1. 先準備好 Elasticsearch Cluster 的環境,你會需要用 Elasticsearch 來儲存與搜尋 Heartbeat 所收集到的資料。

  2. 準備好 Kibana 的環境,我們會要透過 Kibana 來檢視這些資料。

  3. 下載 Heartbeat 並解壓縮

curl -L -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-7.14.1-darwin-x86_64.tar.gz
tar xzvf heartbeat-7.14.1-darwin-x86_64.tar.gz
  1. 進入解壓縮後的目錄,修改 heartbeat.yml,指定 Elasticsearch 與 Kibana 的位置。

output.elasticsearch:
  hosts: ["myEShost:9200"]
  username: "heartbeat_internal"
  password: "YOUR_PASSWORD"
setup.kibana:
  host: "mykibanahost:5601" 
  username: "my_kibana_user"  
  password: "YOUR_PASSWORD"
  1. heartbeat.yml 裡面,或是在 monitors.d 的目錄裡建立自己訂義的 YAML 檔,來設定 Monitors 的規則。

heartbeat.monitors:
- type: icmp
  schedule: '*/5 * * * * * *' 
  hosts: ["myhost"]
  id: my-icmp-service
  name: My ICMP Service
- type: tcp
  schedule: '@every 5s' 
  hosts: ["myhost:12345"]
  mode: any 
  id: my-tcp-service
- type: http
  schedule: '@every 5s'
  urls: ["http://example.net"]
  service.name: apm-service-name 
  id: my-http-service
  name: My HTTP Service

注意:如果在 monitors.d 裡面建立新的 YAML 檔的話,檔案裡是直接放 heartbeat.monitors 裡面的設定值的,也就是 heartbeat.monitors 這一層是用宣告,直接從 - type: icmp 這一層開始宣告即可,請直接參考解壓縮之後,資料夾裡面附的範例。

  1. 依照佈署的地理位置,設定好 processors 裡的地區設定,這個設定可以協助之後在 Kibana 篩選檢視的範圍。

# ============================ Processors ============================

processors:
  - add_observer_metadata:
      # Optional, but recommended geo settings for the location Heartbeat is running in
      geo: 
        # Token describing this location
        name: us-east-1a 
        # Lat, Lon "
        #location: "37.926868, -78.024902" 
  1. 設置的最後是要透過 ./heartbeat setup -e 幫我們到 Elasticsearch 建立好 ILM (Index Lifecycle Management) 要使用的 Index Template。

  1. 最後執行 heartbeat。

sudo chown root heartbeat.yml 
sudo ./heartbeat -e

如果你使用 root 的身份執行 heartbeat 時,要記得將 config 的擁有者一併修改成 root。

  1. 最後可以就可以從 KibanaObservability 選單中的 Uptime 看到收集的資料了。

Heartbeat 使用的技巧

以下列出一些在 Heartbeat 在使用上的技巧,可以提供大家參考。

針對需求情境環境設定不定的 tags

Heartbeat 裡面可以設定 tags,並且在 heartbeat.yml 裡可以設定 General 的 tags,而進入到 monitors 裡,可以再設定特定 monitortag,這些 tags 設定的用途,是在 Kibana 的畫面很可以清楚的分類我們所定義的這一些監示排程的工作,並且可以快速的篩選。

而什麼情境來設定這些 tags,建議可以使用最常會用來分類及篩選進行檢示的項目,例如:Service Name、Data Center、Project Name…等。

若是有使用 301 或 302 HTTP Redirect 的頁面,要注意的設定

如果今天要透過 Heartbeat 來監測的是有設置 HTTP Redirect 的網頁頁面,首先要注意 max_redirects 的設定,預設是 0 ,也就是不會去執行 redirect,所以會要 Heartbeat 去跟隨 Redirect 回傳的指示進一步的存取下一個 Location 的話,要記得將這個設定打開,另外要注意這個設定打開之後,因為記錄的過程會變得較複雜,有些資訊會無法保留,這部份請直接參考官方文件 [2]。

另外在這種情境,可以視情況先設定一組專門確認有回傳 301302 結果、並且驗證 HTTP header 當中的 Location 設定值,另外再建一組是會依照 HTTP redirect 執行到最後頁面的結果,這樣能夠多確認這一步一步的過程是否如預期。

以下是我的一個例子,我會要求先取得 301 的 response status,並且最後我會要拿到的是 404 (雖然你看到 404 好像很怪,但這是我目前需要的情境 :P)。

- type: http # monitor type `http`. Connect via HTTP an optionally verify response
  id: onedoggo-web
  name: OneDoggo Web
  schedule: '@every 5s' # every 5 seconds from start of beat
  hosts: ["https://onedoggo.com"]
  ipv4: true
  ipv6: true
  mode: any
  supported_protocols: ["TLSv1.0", "TLSv1.1", "TLSv1.2"]
  # 記錄 Reponse header
  response.include_body: on_error
  check.response:
    status: 301
    headers:
    - location: https://onedoggo.com/98a4eb9cdd8b40ddb4a452af7577295d
  tags: ["onedoggo", "web"]
  fields:
    env: production

- type: http # monitor type `http`. Connect via HTTP an optionally verify response
  id: onedoggo-web
  name: OneDoggo Web
  schedule: '@every 5s' # every 5 seconds from start of beat
  hosts: ["https://onedoggo.com"]
  ipv4: true
  ipv6: true
  mode: any
  supported_protocols: ["TLSv1.0", "TLSv1.1", "TLSv1.2"]
  response.include_body: always
  max_redirects: 5
  check.response:
    status: 404
  tags: ["onedoggo", "web"]
  fields:
    env: production

Kibana 也很貼心,會將 Redirect 的過程都一步一步的標示出來,讓我們知道過程中走過哪些路徑。

自行定義 fields 欄位的資料,一方面在 Kibana 協助搜尋篩選,另外也能延伸自行使用

透過 fields 可以存放任何的資料,以下面為例,我們定義了 env 的欄位,裡面存了 production 的值,另外也定義了 onedoggo 的欄位,裡面是存放一整個物件。

- type: http # monitor type `http`. Connect via HTTP an optionally verify response
  id: onedoggo-web
  name: OneDoggo Web
  schedule: '@every 5s' # every 5 seconds from start of beat
  hosts: ["https://onedoggo.com"]
  ipv4: true
  ipv6: true
  mode: any
  supported_protocols: ["TLSv1.0", "TLSv1.1", "TLSv1.2"]
  # 記錄 Reponse header
  response.include_body: on_error
  check.response:
    status: 301
    headers:
    - location: https://onedoggo.com/98a4eb9cdd8b40ddb4a452af7577295d
  tags: ["onedoggo", "web"]
  fields:
    env: production
    onedoggo:
      product: homepage
      owner: joe
      tracking:
        user: standard

而這些設定,可以在 Kibana Uptime 的畫面協助過濾,另外也可以自行額外延伸使用,例如使用 heartbeat 所收集的資料,另外拉出 dashboard 等檢示的圖表。

將 Heartbeat 暫存在 Queue 中的資料,寫入 Disk 避免遺失

Heartbeat 所收集到的資料,在送出之前,預設是會存放在 Memory queue 當中,我們可以在 heartbeat.yml 中指定 queue 的方式:

queue.disk:
  max_size: 10GB
  path: /tmp/heartbeat/diskqueue
  max_retry_interval: 30s

透過類似以上的配置,可以讓 heartbeat 的資料寫入到 disk 中,避免 process 中斷時,資料直接遺失的風險。

使用 Autodiscover 自動偵測需要被監控的機器

Heartbeat 有支援 Autodiscover 的機制,像是使用 Docker, Kubernetes, AWS ELB,Heartbeat 可以自動幫我們偵測有哪些機器需要被監測,這部份的細節請參考官方文件 - Heartbeat Autodiscovery [3]。

使用時你可能會遇到的坑

如果使用 ICMP 並且使用 MacOS 的環境,會發生這種 Invalid argument 的錯誤。

有人已經在 Github 發 Issues ,而官方團隊也有回應 [4]:

Unfortunately it's still not our highest priority issue. One workaround would be using the docker image instead of plain heartbeat for now.

所以會需要特別切換成 root 來執行,或是先用 Docker 來繞路嘍。

參考資料

Last updated