在微服務架構中,服務例項動態增減是常態,因此需要一個機制讓服務之間能夠自動發現彼此。服務註冊與發現機制應運而生,解決了服務間通訊的挑戰。客戶端服務發現模式下,客戶端直接查詢註冊中心取得服務地址,實作簡單但客戶端負擔較重。伺服器端服務發現模式則透過負載平衡器或 API 閘道器間接查詢,簡化客戶端邏輯並提升效率。Consul、Zookeeper 和 etcd 等開源工具提供高用性和安全性,適合建構穩定的服務註冊中心。Eureka 則專注於微服務場景,提供簡潔易用的介面。此外,Registrator 等外部工具可自動監控容器狀態並更新註冊資訊,避免服務自行註冊的複雜性,並遵循單一責任原則,提升整體架構的穩健性。

容器協調中的服務註冊與發現

在微服務架構中,服務註冊與發現是不可或缺的部分。服務註冊是指微服務將其位置資訊註冊到一個中央系統,而服務發現則是指客戶端如何找到並連線到這些服務。以下玄貓將探討客戶端與伺服器端的服務發現機制,並介紹一些常見的開源工具。

客戶端服務發現

在客戶端服務發現機制中,客戶端需要主動查詢服務註冊中心以取得服務的實際位置。這種方法的優點是簡單直觀,但缺點是將發現服務的責任交給了客戶端應用程式。

此圖示展示了客戶端服務發現的工作流程:

  graph LR;
    Connect[Connect]
    location[location]
    service[service]
    A[Service Registry] --> B[Service A (Instance 1)]
    A --> C[Service A (Instance 2)]
    A --> D[Service B (Instance 1)]
    A --> E[Service B (Instance 2)]
    A --> F[Service B (Instance 3)]
    G[Service A (Client)] -- Query registry for a service location --> A;
    G -- Connect to the actual service --> B;
    G -- Connect to the actual service --> C;
    G -- Connect to the actual service --> D;
    G -- Connect to the actual service --> E;
    G -- Connect to the actual service --> F;

內容解密:

  • Service Registry:中央註冊中心,儲存所有服務的位置資訊。
  • Service A / Service B:表示不同的微服務及其例項。
  • Query registry for a service location:客戶端查詢中央註冊中心以取得服務位置。
  • Connect to the actual service:根據查詢結果,客戶端連線到實際的服務例項。

伺服器端服務發現

相較於客戶端服務發現,伺服器端服務發現則是將負載平衡器或 API 閘道器作為中介,客戶端無需直接查詢中央註冊中心。這種方法將發現和負載平衡的責任交給了伺服器端,減輕了客戶端的負擔。

此圖示展示了伺服器端服務發現的工作流程:

  graph LR;
    Forwards[Forwards]
    location[location]
    A[Service Registry] --> B[Service A (Instance 1)]
    A --> C[Service A (Instance 2)]
    A --> D[Service B (Instance 1)]
    A --> E[Service B (Instance 2)]
    A --> F[Service B (Instance 3)]
    G[Load Balancer / API Gateway] -- Query registry for a service location --> A;
    G -- Forwards the request to Service B -->
    E;

內容解密:

  • Load Balancer / API Gateway:作為中介層,負責查詢中央註冊中心並進行負載平衡。
  • Forwards the request to Service B:根據查詢結果,負載平衡器將請求轉發到適當的服務例項。

常見的開源工具

玄貓來看一些常見的開源工具:

  1. Consul(HashiCorp):提供高用性和安全性,支援多種協定進行查詢。
  2. Zookeeper(Apache):廣泛應用於分散式系統中的組態管理和命名服務。
  3. etcd:由 CoreOS 開發,專注於一致性和可靠性,適合用於 Kubernetes。
  4. SmartStack(AirBnB):結合多種技術,提供強大的監控和自動化能力。
  5. Eureka(Netflix):專為微服務設計,提供簡單且高效的註冊和發現機制。
  6. SkyDNS:根據 DNS 的服務發現工具,適合需要 DNS 查詢的場景。

自我註冊與外部工具

微服務可以透過自我註冊或外部工具來更新其位置資訊。自我註冊是指微服務自行向中央註冊中心報告其位置資訊,但這違反了單一責任原則。因此,外部工具如 Registrator 被廣泛使用來自動處理這些操作。

自我註冊

  graph LR;
    A[Micro Service] --> B[Service Registry];
    C[Micro Service] --> B;

外部工具

  graph LR;
    A[Registrator] --> B[Service Registry];
    C[Docker Container] --> D(Docker Events);
    D-->A;

內容解密:

  • Registrator:一個開源元件,自動監控 Docker 容器的啟動和停止事件,並將這些資訊傳遞給中央註冊中心。
  • Docker Events:Docker 生成的事件通知,Registrator 根據這些事件來更新中央註冊中心中的資訊。

在這兩個方式中,外部工具通常更為推薦,因為它能保證微服務專注於核心功能而不必額外處理註冊邏輯。

主題標題:容器管理與監控

段落標題:容器管理的挑戰與解決方案

在理解容器協調、擴充套件及網路架構後,讓我們探討當事情出錯時的處理方法。在生產環境中,可能會有數百甚至數千個容器執行,因此有效且高效地管理這些容器至關重要。本章將探討容器監控和管理,包括捕捉日誌、收集資源指標以及使用一些叢集範圍的監控系統。

首先,我們來瞭解容器的整體監控方面,以及為何這與現有市場上的解決方案有所不同。

段落標題:容器監控的特點與挑戰

監控一個包含容器的環境並不困難,但速度、數量和環境可能會讓它變得複雜。傳統上,市場上的監控工具已經成熟,用於監控和管理實體主機、網路及虛擬機器。然而,容器是新興技術,市場仍在解決監控問題。容器監控不同之處在於以下幾個方面和挑戰:

  • 佈署環境:一個組織可能會在自己的資料中心內直接在實體基礎設施上執行一些容器,也可能在AWS等服務提供商的虛擬機器上執行一些容器。這增加了管理的複雜性。

  • 容器的可擴充套件性:整個應用程式可以在一台實體機或幾台虛擬機器上執行。而對於容器,最佳實踐是每個服務一個容器,一個應用程式可能由數百甚至數千個服務組成,這意味著需要管理數百甚至數千個容器。在微服務架構中,應用程式的擴充套件需要根據需求自動縮減和擴充套件容器的數量。

  • 變化速度:與實體主機或虛擬機器不同,容器的壽命可能從幾秒鐘到幾天不等。當任務完成後,容器就會消失。

  • 各種工具使用:雖然容器提供了速度和效率,但它們也使簡單性不復存在。佈署、管理和發現容器需要大量工具。例如,您可以使用Docker Swarm、Kubernetes或Mesos等多種容器協調工具。您可以指定網路組態、每個容器要啟動的例項數量等。協調工具根據主機中的資源可用性來控制容器的建立、刪除和管理。每次建立新的容器時,它都會獲得一個新的IP地址。所有這些都使得整體監控和指標收集變得非常困難。

  • 分散式資料:資料必須從各種工具中收集並合併到一個中央位置以進行分析和發現潛在問題。Docker提供了一些功能來取得這些資料和統計資訊以主動監控容器和整個系統。

目前有許多供應商特定選項,每個選項都有其自身優勢。Docker最近推出了Ecosystem Technology Partner (ETP) 計劃,與透過API與Docker整合其監控工具的公司合作。您可以在 Docker官網 上搜尋這些合作夥伴。

段落標題:日誌記錄

在支援多個應用程式且具有多個叢集和多份執行中的服務副本的生產環境中,您可能會有大量正在執行的容器。當事情出錯時,日誌記錄變得非常重要以便進行故障排除。例如,回想一下微服務架構中討論的內容,我們指的是由一個典型大規模應用程式中的數百到數千個微服務組成。Docker 容器非常適合執行這麼多微服務,因為它們提供了我們之前討論過的許多優點。

然而,問題是當每個容器將所有從stdout 和stderr 產生的資料寫入日誌時如何進行日誌管理?如何保持所有這些日誌同步並放置在便於故障排除且高效工作的地方?再次說明Docker 提供了驅動程式來簡化我們的工作。每個驅動程式都能幫助我們從執行中的服務獲得日誌資訊。

以下是目前支援的一些日誌驅動程式:

次段落標題:json-file

json-file 是 Docker 守護程式的預設日誌驅動程式。除非您組態了該屬性或守護程式使用其他驅動程式,否則每個 Docker 都會使用此驅動程式。

次段落標題:None

None 可以關閉所有日誌記錄功能。

次段落標題:Syslog

Syslog 會將所有日誌訊息傳送至本地或遠端安裝好的 syslog 伺服器中。若要啟用此功能請先修改主機上的 daemon.json 檔案將 log driver 設為 syslog 並指定相關設定。

次段落標題:awslogs

awslogs 會將所有日誌訊息傳送至 Amazon CloudWatch Logs 中。若要啟用此功能請先修改主機上的 daemon.json 檔案將 log driver 設為 awslogs 並指定相關設定。

次段落標題:Splunk

Splunk 是透過 HTTP Event Collector(HEC)將日誌資訊傳送給 Splunk 的驅動程式。 若要啟用此功能請先修改主機上的 daemon.json 檔案將 log driver 設為 Splunk 並指定相關設定。 此驅動程式需要指定 Splunk-token 和 splunk-url 構成引數。

次段落標題:Journald

Journald 是將日誌資訊傳送到 systemd 的 journal 的驅動程式。 若要啟用此功能請先修改主機上的 daemon.json 檔案將 log driver 設為 journald。 Log entries can be retrieved using journalctl or Docker log commands.

次段落標題:gcplogs

gcplogs 是將日誌資訊傳送到 Google Cloud Platform(GCP)日誌平台上以便查詢及分析這些資訊。 若要啟用此功能請先修改主機上的 daemon.json 檔案將 log driver 設為 gcplogs並指定相關設定。

此圖示表示 Docker 日誌驅動各型別流向及其轉接樣貌
```mermaid
graph LR;
    A[Docker 日誌] --> B[json-file]
    A --> C[None]
    A --> D[Syslog]
    A --> E[awslogs]
    A --> F[Splunk]
    A --> G[Journald]
    A --> H[gcplogs]

內容解密:

  1. json-file 是 Docker 的預設日誌驅動程式,每次佈署新版本時都會生成新檔案以確保不會覆寫原始檔案。
  2. none 用於完全關閉 Docker 日誌功能。
  3. Syslog 提供統一存取所有 Docker 日誌資料來進行故障排除。
  4. awslogs 是專門設計給 Amazon CloudWatch Logs 的驅動程式使用者可以透過 AWS Console 檢視及分析。
  5. Splunk 是針對 Splunk 中台推出專門駕駛提供者。
  6. Journald 是針對 systemd 中台推出專門駕駛提供者。
  7. gcplogs 是針對 Google Cloud Platform 中台推出專門駕駛提供者。

容器管理技術的深度解析

在現代軟體開發與維運中,容器技術已成為不可或缺的一部分。瞭解如何有效管理容器,包括日誌管理和度量收集,對於提升系統的可觀察性和穩定性至關重要。本文將探討這些核心技術,並結合實務案例來說明其應用。

容器日誌管理

日誌驅動程式

在Docker中,日誌驅動程式是用來收集和傳送容器日誌的機制。Docker支援多種日誌驅動程式,包括json-filesysloggelf等。其中,json-file是預設的日誌驅動程式。

要檢查當前的日誌驅動程式,可以使用以下命令:

docker info | grep 'Logging Driver'

這將顯示當前的日誌驅動程式:

Logging Driver: json-file

更改日誌驅動程式

你可以在啟動容器時指定日誌驅動程式,例如使用GELF(Graylog Extended Log Format):

docker run -it --log-driver gelf ubuntu:latest sh

此外,你也可以在啟動Docker守護程式時修改預設的日誌驅動程式。在Linux主機上,你可以編輯/etc/Docker/daemon.json檔案:

{
    "log-driver": "gelf",
    "log-opts": {
        "gelf-address": "udp://graylog-server:12201"
    }
}

重新啟動Docker守護程式後,新啟動的容器將使用GELF作為日誌驅動程式。

關閉日誌

如果你希望完全關閉某個容器的日誌功能,可以在啟動容器時指定none作為日誌驅動程式:

docker run -it --log-driver none ubuntu:latest sh

這樣做會使該容器不會產生任何日誌。

小段落標題

這種方式適用於需要高效資源利用且不需要詳細日誌記錄的情境。例如,在測試環境中,你可能希望降低資源消耗,這時候可以考慮關閉不必要的日誌功能。

中央化日誌系統

隨著應用程式規模擴大,單純依賴於容器本身的日誌管理已經無法滿足需求。這時候需要引入中央化的日誌系統來處理所有容器的日誌記錄。

中央化日誌系統應具備以下功能:

  1. 過濾、索引、分類別:幫助快速定位和分析問題。
  2. 排序和搜尋:提升查詢效率。
  3. 多維度標籤:便於追蹤和管理。

度量收集

度量收集是監控容器效能和健康狀況的重要手段。Docker提供了基本的度量收集工具和API介面,讓你可以實作實時監控。

Docker Stats

docker stats命令可以提供當前執行中的容器的即時效能資料:

docker stats

這個命令會顯示每個容器的CPU使用率、記憶體使用率、網路I/O以及塊I/O等資料。例如:

CONTAINER CPU% MEM USAGE / LIMIT MEM% NET I/O BLOCK I/O PIDS
b4831186f0d4 0.00% 1.98 MiB / 47.08 GiB 0.00% 0 B / 0 B 2.12 MB / 0 B 1

你可以透過--format選項來自定義輸出格式。例如:

docker stats --format "table {{.Name }} \t {{.ID }} \t {{.CPUPerc}} \t {{.MemUsage}}"
小段落標題

自定義輸出格式可以幫助你更靈活地展示所需的效能資料。例如,如果你只關心CPU和記憶體使用率,就可以選擇只顯示這些資料。

REST API

Docker還提供了REST API來取得更詳細的效能資料。例如,透過以下命令可以取得特定容器的即時效能資料:

curl --unix-socket /var/run/docker.sock -X GET 'http:/v1.24/containers/<container ID>/stats'

這個API會每秒鐘傳回一次資料流。你可以根據需要編寫自定義指令碼來處理這些資料。

cAdvisor

cAdvisor(Container Advisor)是由Google開發的一個監控解決方案,提供詳細的容器使用和效能指標資料。它本身也是一個容器,可以佈署在主機上來收集所有容器的資料。

cAdvisor提供了直觀的圖形介面來展示資料,幫助你更直觀地瞭解各個容器的執行狀況。你可以透過以下命令來啟動cAdvisor:

docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  --device=/dev/kmsg \
google/cadvisor:latest

然後存取http://<host-ip>:8080就可以看到cAdvisor提供的監控介面。

創新監控方式

透過結合這些工具與技術,玄貓(BlackCat)建議採取以下策略來提升監控效率:

  • 標籤管理:在構建影像時新增有意義的標籤,方便後續管理和查詢。
  • 自動化告警:組態自動化告警系統來及時發現異常情況。
  • 多維度分析:利用中央化日誌系統進行多維度資料分析,快速定位問題根源。
  • 持續最佳化:根據收集到的資料持續最佳化系統組態和應用設計。

意見

隨著技術不斷進步與演變,未來我們期待見到更加智慧化與自動化的監控工具與解決方案出現。未來版本Docker可能會引入更多功能強大且易於使用的監控API或工具以滿足複雜應用需求。

若想更深入瞭解相關技術內容及最佳實踐方法建議參考 官方檔案 或加入台灣本地技術社群交流學習更多實務知識與經驗分享。

透過本文介紹瞭如何有效地管理和監控Docker容器日誌與度量資料,希望讀者能夠從中獲得啟發並且運用於實際應用中提升整體維運效率及穩定性!