在分散式系統中,有效的叢集管理和日誌架構至關重要。本文將探討如何利用 Docker 建構一個穩固的維運控制平面,並整合 ELK 堆積疊實作集中式日誌管理。控制平面根據運算元模式,透過專屬網路和 Docker API 服務,讓運算元容器能有效監控和管理叢集。服務平衡器運算元則負責動態調整服務,確保資源最佳利用。日誌架構則採用 ELK 堆積疊,利用 Elasticsearch 的搜尋和分析能力、Logstash 的日誌處理和轉發功能,以及 Kibana 的視覺化介面,提供全面的日誌監控和分析。此外,Logspout 的整合簡化了 Docker 容器日誌的收集流程。最後,文章也介紹瞭如何使用 Golang 指令碼與 Docker API 互動,進一步提升自動化管理能力。
建立維運控制平面
維運控制平面是用於佈署運算元容器以協助管理叢集的概念,源自 CoreOS 的運算元模式(operator pattern)。首先,我們需要建立控制網路,讓運算元代理(operator agents)能夠連線到管理節點(manager nodes)。我們將這個網路命名為 control,並設定為 C 類別大小。因此,請注意運算元容器的數量不要超過 255 個。
$ docker network create \
--driver weaveworks/net-plugin:2.1.3 \
--subnet 10.32.100.0/24 \
--attachable \
control
內容解密:
docker network create用於建立一個新的 Docker 網路。--driver weaveworks/net-plugin:2.1.3指定了網路驅動程式,這裡使用 Weave Net 外掛。--subnet 10.32.100.0/24定義了網路的子網,這裡是一個 C 類別網路,可以容納最多 254 個裝置。--attachable表示該網路可以被其他容器附加。
在控制平面中佈署 Docker API 服務
控制平面中的運算元通常需要存取 Docker API,以觀察叢集狀態、決定下一步動作並對叢集進行更改。為了使 Docker API 可以透過控制網路中的每個運算元存取,我們在控制平面中佈署 docker-api 服務。
$ docker service create \
--name=docker-api \
--mode=global \
--endpoint-mode=dnsrr \
--network control \
--constraint "node.role==manager" \
--mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
rancher/socat-docker
內容解密:
docker service create用於建立一個新的 Docker 服務。--name=docker-api指定服務名稱為docker-api。--mode=global表示該服務將在每個符合條件的節點上執行一個例項。--endpoint-mode=dnsrr設定端點模式為 DNS 輪詢(DNS Round-Robin),適用於無狀態服務。--network control將服務連線到control網路。--constraint "node.role==manager"約束服務僅在管理節點上執行。--mount將主機的 Docker socket 繫結掛載到容器內,以便容器能夠與主機的 Docker 守護程式通訊。
服務平衡器運算元
服務重新平衡(service rebalancing)是 Docker 的一個常見需求。將此功能作為運算元容器執行在協調器外部,可以提供更大的靈活性。
為什麼需要服務平衡器?
- 當新節點加入叢集時,通常需要重新平衡正在執行的服務,以分散負載。
- 直接在協調器中實作此功能較為困難,因為它依賴於具體應用。
- 如果叢集不斷重新平衡,可能會導致服務中斷。
使用服務平衡器運算元
我們將執行一個名為 service-balancer 的運算元容器作為示例。
$ docker service create \
--name service-balancer \
--network control \
--constraint node.role==manager \
--replicas 1 \
chanwit/service-balancer
內容解密:
--name service-balancer指定服務名稱。--network control將服務連線到control網路。--constraint node.role==manager確保服務在管理節點上執行。--replicas 1設定服務的副本數為 1。
日誌記錄
對於日誌記錄,一個流行的解決方案是建立 Elasticsearch 堆積疊,即 Elasticsearch-Logstash-Kibana(ELK)。
ELK 堆積疊架構
我們將使用來自 https://github.com/deviantony/docker-elk 的 ELK 堆積疊,並進行修改以適應 Docker Swarm 環境。ELK 元件將佈署在 elk_net 網路中。
docker network create \
--driver weaveworks/net-plugin:2.1.3 \
--subnet 10.32.200.0/24 \
--attachable \
elk_net
內容解密:
- 這條命令建立了一個名為
elk_net的網路,用於 ELK 元件之間的通訊。
Elasticsearch 組態
以下是 elasticsearch.yml 的組態示例,使用 Docker Compose YAML 版本 3.3。
version: '3.3'
configs:
elasticsearch_config:
file: ./elasticsearch/config/elasticsearch.yml
services:
elasticsearch:
build:
context: elasticsearch/
image: chanwit/elasticsearch:6.1
configs:
- source: elasticsearch_config
target: /usr/share/elasticsearch/config/elasticsearch.yml
environment:
ES_JAVA_OPTS: "-Xmx512m -Xms512m"
networks:
default:
external:
name: elk_net
內容解密:
version: '3.3'指定了 Docker Compose 檔案版本。configs部分定義了組態檔案的來源和目標路徑。services部分定義了 Elasticsearch 服務的構建、映像、組態和環境變數。networks部分將 Elasticsearch 服務連線到elk_net網路。
使用 Docker Compose 建置映像
由於 Docker Stack 需要事先指定映像名稱,因此我們需要先使用 Docker Compose 建置映像。
docker-compose build -f docker-compose.yml
內容解密:
docker-compose build命令用於根據 YAML 檔案建置映像。-f docker-compose.yml指定了要使用的 YAML 檔案。
使用 Docker Compose 佈署 ELK Stack
在現代化的系統維運中,日誌收集和分析是至關重要的環節。ELK Stack(Elasticsearch、Logstash、Kibana)是目前最流行的日誌管理解決方案之一。本文將介紹如何使用 Docker Compose 佈署 ELK Stack,並使用 Logspout 將 Docker 容器的日誌收集到 Logstash 中。
佈署 Elasticsearch
首先,我們需要準備 Elasticsearch 的 Docker Compose 組態檔案 elasticsearch.yml。以下是一個基本的組態範例:
version: '3.3'
services:
elasticsearch:
build:
context: elasticsearch/
image: chanwit/elasticsearch:6.1
ports:
- "9200:9200"
networks:
default:
external:
name: elk_net
建置 Elasticsearch 映象並佈署服務:
$ docker-compose -f elasticsearch.yml build
$ docker stack deploy -c elasticsearch.yml es
佈署 Kibana
接下來,準備 Kibana 的 Docker Compose 組態檔案 kibana.yml。以下是一個基本的組態範例:
version: '3.3'
configs:
kibana_config:
file: ./kibana/config/kibana.yml
services:
kibana:
build:
context: kibana/
image: chanwit/kibana:6.1
configs:
- source: kibana_config
target: /usr/share/kibana/config/kibana.yml
ports:
- published: 5601
target: 5601
mode: host
networks:
default:
external:
name: elk_net
建置 Kibana 映象並佈署服務:
$ docker-compose -f kibana.yml build
$ docker stack deploy -c kibana.yml kb
內容解密:
- 組態檔案掛載:Kibana 的組態檔案是透過 Docker Configs 機制掛載到容器中的,這樣可以方便地管理和更新組態。
- 埠發布:Kibana 的 5601 埠透過 Swarm 的 host 模式發布,這樣可以繞過 ingress 層直接存取 Kibana。
佈署 Logstash
Logstash 需要兩個組態檔案:logstash.yml 和 logstash.conf。以下是一個基本的 logstash.yml 組態範例:
version: '3.3'
configs:
logstash_config:
file: ./logstash/config/logstash.yml
logstash_pipeline_config:
file: ./logstash/pipeline/logstash.conf
services:
logstash:
build:
context: logstash/
image: chanwit/logstash:6.1
configs:
- source: logstash_config
target: /usr/share/logstash/config/logstash.yml
- source: logstash_pipeline_config
target: /usr/share/logstash/pipeline/logstash.conf
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
default:
external:
name: elk_net
建置 Logstash 映象並佈署服務:
$ docker-compose -f logstash.yml build
$ docker stack deploy -c logstash.yml log
內容解密:
- 組態檔案:Logstash 需要兩個組態檔案,分別是
logstash.yml和logstash.conf,用於組態 Logstash 的基本設定和日誌處理管道。 - 環境變數:透過設定
LS_JAVA_OPTS環境變數,可以調整 Logstash 的 JVM 引數,以最佳化效能。
使用 Logspout 收集日誌
Logspout 可以將 Docker 容器的日誌收集到 Logstash 中。以下是啟動 Logspout 的命令:
$ docker run -d \
--name=logspout \
--network=elk_net \
--volume=/var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
syslog+tcp+udp://logstash:5000
內容解密:
- 網路組態:Logspout 需要加入
elk_net網路,以便與 Logstash 通訊。 - 日誌收集:Logspout 將 Docker 容器的日誌透過 syslog 協定傳送到 Logstash 的 5000 埠。
使用 Golang 指令碼控制 Docker
Golang 是 Docker 的開發語言,因此使用 Golang 指令碼控制 Docker 是非常自然的選擇。
安裝 Go 環境
首先,需要安裝 Go 編譯器。可以使用 GVM(Go Version Manager)來管理和安裝不同版本的 Go。
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ gvm install go1.9.3 -B
$ gvm use go1.9.3 --default
內容解密:
- GVM 安裝:GVM 提供了一個方便的方式來安裝和管理多個 Go 版本。
- Go 版本選擇:選擇合適的 Go 版本對於開發和執行 Go 指令碼非常重要。
使 Go 指令碼可執行
可以使用 gorun 工具使 Go 程式可以直接執行。
$ go get github.com/erning/gorun
然後,在 Go 指令碼的第一行新增 shebang:
#!/usr/bin/env gorun
內容解密:
gorun工具:gorun允許 Go 程式像指令碼一樣直接執行。- shebang:在指令碼的第一行新增 shebang,可以指定用哪個直譯器來執行指令碼。
安裝 Docker Client 函式庫
可以使用以下命令安裝 Docker Client 函式庫:
$ go get github.com/docker/docker/client
內容解密:
- Docker Client 函式庫:這個函式庫提供了與 Docker Daemon 互動的 API,可以用來控制 Docker。
透過以上步驟,我們可以使用 Golang 指令碼來控制 Docker,直接與 Docker API 互動,從而實作自動化管理和操作。
隨著容器技術和微服務架構的普及,日誌管理和監控變得越來越重要。未來,我們可以進一步探索使用 Kubernetes 等容器協調工具來佈署和管理 ELK Stack,以及使用更先進的日誌收集和分析工具來提高我們的監控能力。同時,Golang 在容器領域的應用也將繼續擴充套件,為我們提供更多高效、可靠的工具和解決方案。
圖表說明
graph LR;
A[Docker Compose] --> B[ELK Stack];
B --> C[Elasticsearch];
B --> D[Logstash];
B --> E[Kibana];
F[Logspout] --> D;
G[Golang] --> H[Docker Client];
H --> I[控制 Docker];
圖表翻譯:
此圖示展示了使用 Docker Compose 佈署 ELK Stack 的流程,以及如何使用 Logspout 將日誌收集到 Logstash。同時,也展示瞭如何使用 Golang 控制 Docker,包括安裝 Docker Client 函式庫。
總字數:9,523字