喬叔的 Elastic Stack 專業教育訓練
  • 喬叔的 Elastic Stack 專業教育訓練
  • 🧑關於喬叔 (Joe Wu)
  • Elastic 課程公開班
    • 🎯Elasticsearch 基礎實務班
      • 💯學員課後回饋
    • 🆕Elasticsearch 進階運維班
      • 💯學員課後回饋
    • Elasticsearch 進階開發班
    • Elastic Stack 基礎實務班
    • Elastic Observability 基礎實務班
    • 📩課程許願池
  • 技術分享
    • 📗喬叔帶你上手 Elastic Stack
      • 前言
      • Elastic Cloud 如何建立 Deployment
        • ES Node 的種類
        • 配置的選擇
      • Index 建立前你該知道的
        • ES Index 如何被建立
        • ES 的超前佈署 - Dynamic Mapping
        • ES 的超前佈署 - Index Template
        • ES Index 的別名 (Alias)
        • 管理你的 Index - Kibana Index
      • 管理 Index 的 Best Practices
        • Shard 的數量與 Rollover & Shrink API
        • 三溫暖架構 - Hot Warm Cold Architecture
        • Index Lifecycle Management (ILM)
        • Rollup
        • Transform
        • Snapshot Lifecycle Management (SLM)
        • 總結
      • Elastic Cloud 比免費版還多的功能
        • Elastic Stack 的方案比較與銷售方式
        • Centralized Beats Management
        • Centralized Pipeline Management
        • Watcher
        • Elasticsearch Token Service
        • Multi-stack monitoring & Automatic stack issue alerts
      • 向 App Search 學習怎麼用 Elasticsearch
        • 揭開 App Search 的面紗
        • Engine 的 Index Settings 篇
        • Engine 的 Mapping 篇
        • Engine 的 Search 基礎剖析篇
        • Engine 的 Search 進階剖析篇
      • Elasticsearch 的優化技巧
        • Indexing 索引效能優化
        • Searching 搜尋效能優化
        • Index 的儲存空間最佳化
        • Shard 的最佳化管理
      • 完賽心得
    • 📘喬叔帶你上手 Elastic Stack - 探索與實踐 Observability 系列
      • 前言 & 淺談 Observability
      • Elastic 的 Observability 解決方案
      • Uptime - 掌握系統的生命徵象
        • 我們要觀測的生命徵象是什麼?
        • 使用 Heartbeat 收集系統生命徵象數據
        • 透過 Kibana 觀看心電圖及設定警報
        • 使用合成監控 (Synthetics Monitor) 從使用者情境驗證服務的運作狀態
      • Metrics - 觀察系統的健康指標
        • Metrics 與 Metricbeat 的基本介紹
        • 使用 Metricbeat 掌握 Elastic Stack 的健康狀態
        • 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Host 篇
        • 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Docker 篇
        • 使用 Metricbeat 掌握 Infrastructure 的健康狀態 Kubernetes 篇
        • 使用 Metricbeat 掌握 Infrastructure 的健康狀態 AWS 篇
      • Logs - 挖掘系統內部發生的狀況
        • Logs 與 Filebeat 的基本介紹
        • 使用 Filebeat 應該要了解的設計細節與原理
        • 透過 Filebeat 收集 Elastic Stack 中各種服務的細節資訊
        • 透過 Filebeat 收集 Infrastructure 中各種服務的細節資訊
      • Traces - 觀察應用程式的效能瓶頸
        • Elastic APM 基本介紹
        • 使用 APM-Integratoin-Testing 建立 Elastic APM 的模擬環境
        • 如何在 Kibana 使用 APM UI
        • 使用 APM Server 來收集 APM 數據
        • 透過 APM Agents 收集並傳送後端服務運作的記錄
        • 透過真實使用者監控 (RUM, Real User Monitoring) 來改善使用者體驗
      • 建立結構化的 Log
        • Elastic Common Schema 結構化 Log 的規範
        • Elasticsearch Ingest Pipeline 資料 Index 前的轉換好幫手
          • 基本介紹
          • 各種常用的 Processor
          • Enrich 資料與例外處理
      • 有效的使用 Observability 的資料
        • 透過 Machine Learning 發現異常的問題
        • 使用 Kibana Alerts 主動通知異常狀況
        • 資料的生命週期管理
        • 使用 Elastic Observability 追縱及觀察問題的心得
      • 完賽心得
    • 😀Elasticsearch 技術分享小品
      • 🤖Elastic 與 AI
        • Elasticsearch Inference API 讓我們直接在 ES 裡運用 OpenAI Completion API
    • 🎥線上分享
      • 喬叔 Elasticsearch Index 管理與效能優化技巧
      • Elastic Certification 認證經驗分享
    • 🛠️workshop
      • 如何在 Elasticsearch 實現敏捷的資料建模與管理 @ DevOpsDays 2023
        • 工作坊實作內容
      • Elastic Observability 實作體驗坊 @ DevOpsDays 2022
        • 行前準備
        • 工作坊實作內容
      • 當 Elasticsearch 搜尋引擎遇上 AI @ HelloWordDevConference 2024
        • 投影片
        • Elasticsearch 環境準備
        • Google Colab 環境準備
        • 工作坊操作說明
        • ElasticSearch Relevance Engine (ESRE)
    • ⬆️Elastic Stack 版本升級記錄
      • 🔍Elasticsearch
  • 其他專業服務
    • 👩‍🎓企業包班 | 企業內訓
    • 👨‍💼顧問服務
    • 🈺專案合作
    • 🧩Elastic 授權代理
  • 相關連結
    • Facebook 粉絲頁
Powered by GitBook
On this page
  • 本篇學習重點
  • 使用 Filebeat 收集使用主機 (Host) 所佈署的 Infrastructure 當中的 Logs
  • 直接在服務的機器上安裝 Filebeat
  • 使用 Shared Drive 的方式收集 Logs
  • 使用 Filebeat 收集使用容器 (Container) 佈署的 Infrastructure 當中的 Logs
  • Docker 環境的 Log 產生方式
  • 收集所有 Docker Conainer 產生的 Logs
  • 使用 Kubernetes DaemonSet 收集 K8S Nodes 身上各 Pods 的 Logs
  • 使用 Kubernetes SideCar 的方式收集 K8S Pod 裡服務產生的實體 Logs
  • 參考資料
  1. 技術分享
  2. 喬叔帶你上手 Elastic Stack - 探索與實踐 Observability 系列
  3. Logs - 挖掘系統內部發生的狀況

透過 Filebeat 收集 Infrastructure 中各種服務的細節資訊

本篇學習重點

  • 使用 Filebeat 收集使用主機 (Host) 所佈署的 Infrastructure 當中 Logs 的方式

  • 使用 Filebeat 收集使用容器 (Container) 佈署的 Infrastructure 當中 Logs 的建議做法

使用 Filebeat 收集使用主機 (Host) 所佈署的 Infrastructure 當中的 Logs

當我們使用非容器化的佈署方式,也就是直接在各主機上安裝服務或應用程式時,我們要收集這些機器上的 Logs 時,可能會有二種方式:

直接在服務的機器上安裝 Filebeat

例如我們在一個單純的三層式服務架構之中,有以下三種服務的主機:

  • Apache Web Server

  • Java Backend Service

  • MySQL Database

而我們要收集這幾台機器上的 Logs 時,我們會建議直接在每台主機上安裝 Filebeat,並且在不同的機器上配置不同的 Inputs 與 Modules 設定值,來收取我們希望取得的 Logs,例如:

主機所安裝的服務
希望收集的資訊
Inputs
Modules
說明

Apache Web Server

Apache access & error logs

Apache

透過 Apache module 指定 access 與 error Logs 的檔案路徑。

Java Backend Service

Application logs

Log 或 filestream

由於 Logs 的格式是自訂義的,直接使用 filestream 來指定要 Logs 的檔案來源路徑,甚至要特別處理的 processors。

MySQL Database

MySQL logs

MySQL

透過 MySQL module 指定 error 與 slowlog Logs 的檔案路徑。

主機本身

主機本身的系統日誌,或是 auth logs

System

透過 System module 指定 syslog 與 auth Logs 的檔案路徑。

使用 Shared Drive 的方式收集 Logs

如果有使用 Shared drive 的方式,來簡化『集中化收集日誌』這件事的話,基本上就是在專門運行 Filebeat 的機器上,透過 NFS 之類的 Shared drives 取得各服務的日誌。

使用 Filebeat 收集使用容器 (Container) 佈署的 Infrastructure 當中的 Logs

Docker 環境的 Log 產生方式

當我們使用 Docker 來佈署服務時,一般的做法都是在 Container 之中直接把 log 輸出到 stdout 或是 stderr,並透過 Docker logging driver 去進行處理,而實際的檔案預設會寫在 Docker host 身上,例如在 linux 環境中,會寫到 /var/lib/docker/containers/ 的路徑底下。

注意:因為容器的生命週期可能隨時會中斷,一個有良好 scalability 的容器化架構的設計,會是 stateless 的,也就是當容器被關閉時,存在裡面的 logs 就消失了,所以一般絕對不建議把 logs 直接寫在 container 之中,至少也要使用 volume 的方式將 logs 寫到會持久保存的另外的儲存空間裡。

收集所有 Docker Conainer 產生的 Logs

因此我們要使用 Filebeat 來收集所有 Docker Container 產生的 logs 時,我們其實就是針對 Docker host 的這個路徑裡的 logs 下手,這也是 Filebeat Container Inputs 所使用的方法。

注意:Docker Input 已經在 7.2 版時棄用 (deprecated) 了,之後請直接使用 Container Input。

而 Container Input 的設定方式如下:

filebeat.inputs:
- type: container
  paths: 
    - '/var/lib/docker/containers/*/*.log'

注意:在這種使用一口氣收集所有 Containers 產生的 logs 時,應該要搭配一些內建的 Processors,例如 add_docker_metadata、add_kubernetes_metadata、add_cloud_metadata,將產生 logs 的 container 或是 pod 的資訊增加在 logs 之中,以便於後續使用時能進行分辨。

使用 Kubernetes DaemonSet 收集 K8S Nodes 身上各 Pods 的 Logs

而在 Kubernetes 裡,也如同前面『 Docker 環境的 Log 產生方式』運作的方式一樣,因為 Pods 會是 stateless,因此一般我們也都會直接將 logs 透過 stdout 或是 stderr 送出,並且由運行這些 Pods 所在的 Node,寫在實體的 disk 路徑 /var/log/containers/*.log 之中,因此我們也就可以使用 DaemonSet 的方式來佈署 Filebeat,並且將主機的 /var/log mount 到 Filebeat 身上,讓他可以直接使用 Container Inputs 的方式,取的這個所有 Pods 產生的 logs。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: kube-system
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    filebeat.inputs:
    - type: container
      paths:
        - /var/log/containers/*.log
      processors:
        - add_kubernetes_metadata:
            host: ${NODE_NAME}
            matchers:
            - logs_path:
                logs_path: "/var/log/containers/"

    # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this:
    #filebeat.autodiscover:
    #  providers:
    #    - type: kubernetes
    #      node: ${NODE_NAME}
    #      hints.enabled: true
    #      hints.default_config:
    #        type: container
    #        paths:
    #          - /var/log/containers/*${data.kubernetes.container.id}.log

    processors:
      - add_cloud_metadata:
      - add_host_metadata:

    cloud.id: ${ELASTIC_CLOUD_ID}
    cloud.auth: ${ELASTIC_CLOUD_AUTH}

    output.elasticsearch:
      hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
      username: ${ELASTICSEARCH_USERNAME}
      password: ${ELASTICSEARCH_PASSWORD}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: kube-system
  labels:
    k8s-app: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
  template:
    metadata:
      labels:
        k8s-app: filebeat
    spec:
      serviceAccountName: filebeat
      terminationGracePeriodSeconds: 30
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:8.0.0
        args: [
          "-c", "/etc/filebeat.yml",
          "-e",
        ]
        env:
        - name: ELASTICSEARCH_HOST
          value: elasticsearch
        - name: ELASTICSEARCH_PORT
          value: "9200"
        - name: ELASTICSEARCH_USERNAME
          value: elastic
        - name: ELASTICSEARCH_PASSWORD
          value: changeme
        - name: ELASTIC_CLOUD_ID
          value:
        - name: ELASTIC_CLOUD_AUTH
          value:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        securityContext:
          runAsUser: 0
          # If using Red Hat OpenShift uncomment this:
          #privileged: true
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /etc/filebeat.yml
          readOnly: true
          subPath: filebeat.yml
        - name: data
          mountPath: /usr/share/filebeat/data
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: varlog
          mountPath: /var/log
          readOnly: true
      volumes:
      - name: config
        configMap:
          defaultMode: 0640
          name: filebeat-config
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: varlog
        hostPath:
          path: /var/log
      # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
      - name: data
        hostPath:
          # When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
          path: /var/lib/filebeat-data
          type: DirectoryOrCreate
---
  • DaemonSet 有宣告 mount /var/lib/docker/container 以及 /var/log,讓 Filebeat 可以取得 container 的 logs。

  • DaemonSet 有另外宣告 /var/lib/filebeat-data 當作 data 的 volumeMounts 來掛載到 container 內的 /var/share/filebeat/data 路徑,讓這個 DaemonSet 的 Filebeat 運作時的檔案,是寫到實體主機的 disk 之中,不會因為重啟而造成資料的遺失。

  • 另外有特別使用 add_kubernetes_metadata 的 processor,讓這些一口氣收集進來的各種 Pod 產生的 logs,加上 Pod Name、Pod UID、Namespace、Labels 的資訊,讓我們在後續分析處理時,能分辨得出來是哪邊產生的 log。

  • 有一段是註解掉的 autodiscovery 的配置,若是使用 Docker、Kubernetes、或是使用 Nomad 時,可以考慮使用 autodiscovery 的機制,讓 container 或是 pod 動態增加時,也能夠由 DaemonSet 自動開始收集新增加容器產生的 logs。

使用 Kubernetes SideCar 的方式收集 K8S Pod 裡服務產生的實體 Logs

如果 Service container 寫的是實體的 Logs 檔案,另一種方式是我們可以使用 SideCar 的方法將 Logs 轉成 stdout 與 stderr 的方式往外傳送,以使用我們先前建議的容器化收集 logs 的方法。

首先將 Pod 中的 Service container 與 Sidecar container 使用 Shared Volume,讓 Sidecar container 能夠直接取得 Service container 產生 的 logs,並且 SideCar container 再負責將這個 logs tail 出來,輸出到 stdout 或 stderr,這樣後續就能同樣的使用 DaemonSet 或是專門收集 log 的 pod 的機制,進行後續的處理。

參考資料

Previous透過 Filebeat 收集 Elastic Stack 中各種服務的細節資訊NextTraces - 觀察應用程式的效能瓶頸

Last updated 2 years ago

使用這種方式,在 Filebeat 的 Inputs 與 Modules 的配置上,沒有特別的差異,只是會一口氣將這些配置設定在同一個 Filebeat 身上,不過有個地方要特別注意,Filebeat 的 Log 與 filestream input,在使用網路共享或是雲端應商的儲存空間時,因為會使用磁碟機的 inode 資訊與 device id 當作檔案的唯一識別,有時 shared drive 的這個值會改變,導致於已經處理過的檔案,又重新被判斷成是新的檔案,造成重覆的傳送,這部份會要透過自行產生唯一的識別 ID,並且指定 inode_maker 來避免這件事發生,細節請參考 。

裡面也可以在 stream 屬性去設定只要針對 stdout 或是 stderr 的內容進行收集,細節可以參考 。

如同我們前面 在介紹 Metricbea 時,提到在 Kubernetes 使用 DaemonSet 的方式同樣的考量,可以確保每個 Node 身上有一個獨立的 Filebeat pod 來進行收集整個 Nodes 上所有 Pods 裡的 logs,並且傳送到 Elasticsearch。

例如以官方的 為例 (以下僅截取 ConfigMap 與 DaemonSet 的主要配置,完整版請參考原始檔案):

📘
官方文件 - Filebeat Input - Logs
官方文件 - Filebeat Input - Container
使用 Metricbeat 掌握 Infrastructure 的健康狀態 Kubernetes 篇
filebeat-kubernetes.yaml
官方文件 - Filebeat Input - Logs
官方文件 - Filebeat Input - Container