在生產環境中佈署Fluentd時,安全性至關重要。本文將探討如何利用TLS加密Fluentd通訊,以及如何管理敏感憑證,確保日誌資料的安全傳輸和儲存。此外,也將涵蓋如何在Docker和Kubernetes環境中佈署Fluentd,以實作更全面的日誌管理和監控。

FROM fluent/fluentd:v1.14-1

# 安裝必要外掛
RUN fluent-gem install fluent-plugin-elasticsearch \
    fluent-plugin-kubernetes_metadata_filter

# 複製自定義Fluentd組態
COPY fluent.conf /fluentd/etc/fluent.conf

# 設定環境變數
ENV FLUENTD_ARGS="--no-supervisor --use-v1-config"

# 暴露Fluentd埠
EXPOSE 24224

# 設定容器啟動命令
CMD ["fluentd"]

強化Fluentd的安全性與憑證管理

在前面的章節中,我們已經探討了Fluentd的基本組態和資料處理能力。然而,當我們將Fluentd佈署到生產環境中時,安全性和憑證管理就變成了至關重要的議題。本章節將探討如何透過TLS(傳輸層安全性協定)加密通訊、進行憑證管理以及如何安全地處理敏感資訊,如使用者名稱和密碼。

7.4 使用TLS加密Fluentd通訊

為了確保Fluentd節點之間的通訊安全,我們可以使用TLS加密。這需要為Fluentd組態證書和私鑰。證書可以由公共或私有的證書頒發機構(CA)頒發,也可以是自簽名的。

組態TLS

要組態TLS,我們需要指定證書路徑(cert_path)和私鑰路徑(private_key_path)。例如:

<source>
  @type forward
  port 28080
  bind 127.0.0.1
  <transport tls>
    cert_path ./myFluentd.crt
    private_key_path ./myFluentd.key
    client_cert_auth false
  </transport>
</source>

在這個例子中,cert_pathprivate_key_path分別指定了證書和私鑰的位置。client_cert_auth屬性用於指定是否驗證客戶端證書。

#### 程式碼解析:

<transport tls>
  cert_path ./myFluentd.crt
  private_key_path ./myFluentd.key
  client_cert_auth false
</transport>

內容解密:

  1. <transport tls>:開啟TLS傳輸層安全性協定,用於加密Fluentd節點之間的通訊。
  2. cert_path ./myFluentd.crt:指定TLS證書的路徑,確保通訊的安全性。
  3. private_key_path ./myFluentd.key:指定私鑰的路徑,與證書配合使用來建立安全連線。
  4. client_cert_auth false:設定是否驗證客戶端證書,在自簽名設定中通常設為false

7.5 憑證管理

Fluentd的組態不支援直接加密和解密憑證,因此使用者名稱和密碼等敏感資訊需要在組態檔案中以明文形式出現。這顯然會帶來安全風險。為瞭解決這個問題,我們可以採用以下幾種策略:

  1. 限制組態檔案存取許可權:透過作業系統許可權控制,限制對Fluentd組態檔案的存取。

  2. 使用包含檔案:將包含憑證的組態部分單獨存放,並嚴格控制這些檔案的存取許可權。

  3. 透過環境變數傳遞憑證:在啟動Fluentd之前,將憑證載入到環境變數中,然後在組態檔案中參照這些環境變數。

  4. 使用Vault管理憑證:利用HashiCorp的Vault工具來安全地儲存和檢索憑證。

使用環境變數傳遞憑證

我們可以透過一個指令碼,在啟動Fluentd之前將憑證載入到環境變數中。例如:

#!/bin/bash
export FLUENTD_USERNAME="hello-this-is-a-long-username"
export FLUENTD_PASSWORD="world-of-security-likes-long-passwords"
fluentd -c /path/to/fluentd.conf

然後在Fluentd組態檔案中參照這些環境變數:

<server>
  host 127.0.0.1
  port 28080
  username "#{ENV['FLUENTD_USERNAME']}"
  password "#{ENV['FLUENTD_PASSWORD']}"
</server>

#### 程式碼解析:

<server>
  host 127.0.0.1
  port 28080
  username "#{ENV['FLUENTD_USERNAME']}"
  password "#{ENV['FLUENTD_PASSWORD']}"
</server>

內容解密:

  1. <server>:定義一個伺服器的組態區塊,用於指定Fluentd轉發日誌事件的目標伺服器。
  2. host 127.0.0.1port 28080:分別指定伺服器的主機地址和埠號。
  3. username "#{ENV['FLUENTD_USERNAME']}"password "#{ENV['FLUENTD_PASSWORD']}":從環境變數中讀取使用者名稱和密碼,以避免在組態檔案中直接暴露敏感資訊。

在Docker和Kubernetes環境中使用Fluentd進行日誌管理

在前面的章節中,我們已經探討了Fluentd的基本使用和組態,並且著重於在獨立環境中使用Fluentd,以簡化複雜度。這有助於闡明一個觀點:儘管Fluentd與雲原生計算基金會(CNCF)相關聯,但它並不僅限於雲原生使用案例。在本章中,我們將探討如何在Docker和Kubernetes環境中使用Fluentd進行日誌管理。

設定Docker使用Fluentd作為日誌驅動程式

Docker提供了多種日誌驅動程式,其中包括Fluentd。設定Docker使用Fluentd作為日誌驅動程式,可以將容器的日誌事件轉發到Fluentd進行進一步處理。

設定步驟:

  1. 啟動Fluentd服務:首先,需要啟動一個Fluentd服務,並組態它接收來自Docker的日誌事件。

    fluentd -c /path/to/fluentd.conf
    
  2. 組態Docker使用Fluentd:在啟動Docker容器時,可以透過指定--log-driver=fluentd引數來設定容器使用Fluentd作為日誌驅動程式。

    docker run -it --log-driver=fluentd --log-opt fluentd-address=localhost:24224 mydockerimage
    
  3. 驗證日誌事件:透過檢查Fluentd的日誌輸出,驗證日誌事件是否正確轉發。

瞭解Kubernetes日誌管理的元件

Kubernetes提供了多種元件來管理日誌,包括節點級別的日誌、容器級別的日誌以及叢集級別的日誌。Fluentd可以用於收集這些日誌事件。

Kubernetes日誌管理元件:

  • 節點級別的日誌:由節點上的kubelet負責收集容器的日誌。
  • 容器級別的日誌:容器執行時(如Docker)負責管理容器的日誌輸出。
  • 叢集級別的日誌:需要額外的元件(如Fluentd)來收集和處理叢集中的日誌事件。

為Fluentd客製Kubernetes DaemonSets

DaemonSet是一種Kubernetes資源,用於在叢集中的每個節點上執行一個Pod。可以使用DaemonSet來佈署Fluentd,以收集節點上的日誌事件。

設定DaemonSet的步驟:

  1. 建立Fluentd的Docker映像:首先,需要建立一個包含Fluentd組態的Docker映像。

    FROM fluent/fluentd:v1.12-1
    # 複製組態檔案到容器中
    COPY fluent.conf /etc/fluent/fluent.conf
    
  2. 定義DaemonSet組態:建立一個YAML檔案,定義DaemonSet的組態。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentd
    spec:
      selector:
        matchLabels:
          name: fluentd
      template:
        metadata:
          labels:
            name: fluentd
        spec:
          containers:
          - name: fluentd
            image: myfluentdimage
            volumeMounts:
            - name: config
              mountPath: /etc/fluent
          volumes:
          - name: config
            configMap:
              name: fluentd-config
    
  3. 套用DaemonSet組態:使用kubectl apply命令套用DaemonSet組態。

    kubectl apply -f daemonset.yaml
    

組態Fluentd收集Kubernetes元件的日誌事件

可以透過組態Fluentd來收集Kubernetes元件的日誌事件,包括節點上的系統日誌和容器日誌。

組態Fluentd的步驟:

  1. 設定輸入外掛:組態Fluentd的輸入外掛,以收集Kubernetes元件的日誌事件。

    <source>
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag kubernetes.*
      format json
      keep_time_key true
    </source>
    
  2. 設定輸出外掛:組態Fluentd的輸出外掛,以將收集到的日誌事件轉發到目標系統。

    <match kubernetes.**>
      @type elasticsearch
      host elasticsearch-host
      port 9200
      index_name kubernetes-logs
      type_name log
    </match>
    

探索Kubernetes節點監控的工作原理

Kubernetes節點監控涉及收集節點上的系統日誌和效能指標。可以使用Fluentd和Prometheus等工具來實作節點監控。

節點監控的元件:

  • 節點上的kubelet:負責收集容器的日誌和效能指標。
  • Fluentd:用於收集和轉發節點上的日誌事件。
  • Prometheus:用於收集和儲存節點上的效能指標。

使用Docker和Kubernetes進行日誌管理

在雲原生微服務開發平台中,不同的技術層次形成了一個複雜的「蛋糕」結構,每一層都增加了技術的複雜度、抽象性和可擴充套件性。通常,每一層都假設讀者對前一層有一定的瞭解。作業系統提供了基礎,接著是容器技術,通常透過Docker實作。下一層是容器協調,如Kubernetes(當然還有其他選擇,如Mesos和OpenShift)。此外,還可以新增服務網格層,如Istio或Linkerd,以提供遙測、相互TLS等功能。然而,由於這些技術引入了額外的複雜性,本章將重點放在日誌管理在Docker和Kubernetes中的應用。

Fluentd在Docker Hub上的官方映像檔

上一章介紹了一系列佈署組態,包括適用於Kubernetes環境的模式。這些使用案例可以直接使用Fluentd和其他人提供的預定義容器,並釋出在中央Docker Hub倉函式庫(https://hub.docker.com/r/fluent/fluentd/)中。

該容器已經組態為可以傳遞一個位置來寫出日誌檔案,這樣就可以使用適當的掛載點,並允許從容器外部存取日誌,避免了容器終止時丟失日誌的問題。除了日誌檔案的位置外,我們還可以傳入自定義的Fluentd組態,如果預設組態不夠用的話。預設設定包括:

  • 24224埠用於接收使用forward外掛的日誌。
  • 標記為Docker.**的日誌被寫入/fluentd/log/docker.log
  • 所有其他日誌都被寫入/fluentd/log/data.*.log

官方Docker映像檔

根據Docker Hub,Fluentd有一個官方映像檔。官方映像檔意味著我們可以放心,該映像檔正在被維護,並且可以在https://hub.docker.com/_/fluentd找到(您至少需要一個免費的Docker Hub帳戶才能存取)。這並不是唯一的Fluentd提供的Docker映像檔,但其他映像檔沒有相同的保證。

Docker日誌驅動程式

日誌驅動程式的目的是捕捉stdin、stdout和stderr的輸出流(即您在控制檯上期望看到的內容),並將它們定向到合適的目的地;否則,這些資訊將「消失在乙太網中」。Docker提供了幾個內建的日誌驅動程式,包括:

  • Fluentd:與Fluentd forward端點通訊,該端點必須在主機上。
  • JSON檔案:預設設定;使用JSON格式將事件儲存在檔案中。
  • local:Docker自定義的根據檔案的儲存,針對其操作進行了最佳化。
  • Syslog:與Syslog產品整合。
  • journald:一個守護程式服務,使用與Syslog相同的API,但產生更結構化的檔案。它隨systemd一起提供,systemd提供了超出Linux核心的一系列OS服務(http://mng.bz/XWZ6)。
  • GELF:Graylog擴充套件日誌格式;被多個日誌框架(如Graylog和Logstash)採用的格式(https://docs.graylog.org/en/4.0/pages/gelf.html)。
  • ETW日誌:Windows日誌事件(http://mng.bz/y4vq)。
  • Google Cloud Platform、AWS CloudWatch、Rapid7、Splunk:一些供應商和平台提供了日誌驅動程式到他們的服務。

除了這些Docker自帶的日誌驅動程式外,您還可以構建自己的。但是,除非您希望將Docker日誌記錄與某個產品或平台緊密耦合,否則有很多選擇,無需進行開發。

為Docker日誌驅動程式做準備

要使用Fluentd日誌驅動程式,我們需要安裝Docker(以及本章後面部分的Kubernetes)。由於這些技術有顯著的不同

內容解密:

本章主要介紹瞭如何使用Docker和Kubernetes進行日誌管理。首先,介紹了雲原生微服務開發平台的不同技術層次,包括作業系統、容器技術(如Docker)、容器協調(如Kubernetes)等。接著,重點介紹了Fluentd在Docker Hub上的官方映像檔及其組態,包括如何傳遞日誌檔案位置和自定義Fluentd組態。此外,還介紹了Docker日誌驅動程式的作用和內建的日誌驅動程式,包括Fluentd、JSON檔案、Syslog等。最後,提到了為Docker日誌驅動程式做準備所需的步驟,包括安裝Docker和Kubernetes。

FROM fluent/fluentd:v1.14-1
# 使用官方Fluentd映像檔作為基礎

# 安裝必要的外掛
RUN fluent-gem install fluent-plugin-elasticsearch

# 複製自定義Fluentd組態
COPY fluent.conf /fluentd/etc/fluent.conf

# 設定環境變數
ENV FLUENTD_ARGS="--no-supervisor --use-v1-config"

# 暴露Fluentd埠
EXPOSE 24224

# 設定容器啟動命令
CMD ["fluentd"]

內容解密:

此Dockerfile用於構建一個包含Fluentd和必要外掛的自定義Docker映像檔。首先,它使用官方Fluentd映像檔作為基礎。然後,安裝fluent-plugin-elasticsearch外掛,以便將日誌傳送到Elasticsearch。接著,將自定義的fluent.conf組態檔案複製到映像檔中。設定環境變數FLUENTD_ARGS以啟用v1組態。暴露24224埠,以便其他容器可以將日誌傳送到Fluentd。最後,設定容器啟動命令為fluentd,以啟動Fluentd服務。