Prometheus監(jiān)控Docker Swarm集群(二)
前面我講解了對于Docker的一些監(jiān)控知識以及Docker監(jiān)控開源工具Weave Scope做了一個概述,以及簡單安裝。
同時也了解了Weave Scope的不足之處,而引出來了cAdvisor配合Prometheus來監(jiān)控容器,本篇主要是針對Swarm集群的監(jiān)控詳細(xì)講解;
Swarm簡介
Docker Swarm 是 Docker 官方三劍客項目之一,提供 Docker 容器集群服務(wù),是 Docker 官方對容器云生態(tài)進(jìn)行支持的核心方案。
使用它,用戶可以將多個 Docker 主機(jī)封裝為單個大型的虛擬 Docker 主機(jī),快速打造一套容器云平臺。
Docker 1.12.0以后的版本 Swarm Mode 已經(jīng)內(nèi)嵌入 Docker Engine,成為了 Docker 子命令 Docker Swarm,絕大多數(shù)用戶已經(jīng)開始使用 Swarm Mode,Docker Engine API 已經(jīng)刪除 Docker Swarm。
Docker 1.12 Swarm mode 已經(jīng)內(nèi)嵌入 Docker 引擎,成為了 docker 子命令 docker swarm。請注意與舊的 Docker Swarm 區(qū)分開來。
Swarm mode 內(nèi)置 kv 存儲功能,提供了眾多的新特性,比如:具有容錯能力的去中心化設(shè)計、內(nèi)置服務(wù)發(fā)現(xiàn)、負(fù)載均衡、路由網(wǎng)格、動態(tài)伸縮、滾動更新、安全傳輸?shù)?。使?Docker 原生的 Swarm 集群具備與 Mesos、Kubernetes 競爭的實力。
節(jié)點
運行 Docker 的主機(jī)可以主動初始化一個 Swarm 集群或者加入一個已存在的 Swarm 集群,這樣這個運行 Docker 的主機(jī)就成為一個 Swarm 集群的節(jié)點 (node) 。
節(jié)點分為管理 (manager) 節(jié)點和工作 (worker) 節(jié)點。
管理節(jié)點用于 Swarm 集群的管理,docker swarm 命令基本只能在管理節(jié)點執(zhí)行(節(jié)點退出集群命令 docker swarm leave 可以在工作節(jié)點執(zhí)行)。
一個 Swarm 集群可以有多個管理節(jié)點,但只有一個管理節(jié)點可以成為 leader,leader 通過 raft 協(xié)議實現(xiàn)。
工作節(jié)點是任務(wù)執(zhí)行節(jié)點,管理節(jié)點將服務(wù) (service) 下發(fā)至工作節(jié)點執(zhí)行。管理節(jié)點默認(rèn)也作為工作節(jié)點。你也可以通過配置讓服務(wù)只運行在管理節(jié)點。
來自 Docker 官網(wǎng)的這張圖片形象的展示了集群中管理節(jié)點與工作節(jié)點的關(guān)系。

服務(wù)和任務(wù)
任務(wù) (Task)是 Swarm 中的最小的調(diào)度單位,目前來說就是一個單一的容器。
服務(wù) (Services) 是指一組任務(wù)的集合,服務(wù)定義了任務(wù)的屬性。服務(wù)有兩種模式:
replicated services 按照一定規(guī)則在各個工作節(jié)點上運行指定個數(shù)的任務(wù)。
global services 每個工作節(jié)點上運行一個任務(wù)
兩種模式通過 docker service create 的 --mode 參數(shù)指定。
來自 Docker 官網(wǎng)的這張圖片形象的展示了容器、任務(wù)、服務(wù)的關(guān)系。

Swarm監(jiān)控方案
一、基于cAdvisor+InfluxDB+Grafana
其中cAdvisor負(fù)責(zé)數(shù)據(jù)的收集,每一臺節(jié)點都部署一個 cAdvisor 服務(wù), Influxdb負(fù)責(zé)數(shù)據(jù)的存儲, Grafana負(fù)責(zé)數(shù)據(jù)的圖形可視化展示。
cAdvisor:數(shù)據(jù)收集模塊
InfluxDB:數(shù)據(jù)存儲
Grafana:圖形可視化
二、基于cAdvisor+Prometheus+Grafana
通過cAdvisor將業(yè)務(wù)服務(wù)器的進(jìn)行數(shù)據(jù)收集,Prometheus將數(shù)據(jù)抓取后存放到自己的時序庫中,Grafana則進(jìn)行圖表的展現(xiàn)。
cAdvisor:數(shù)據(jù)收集模塊
Prometheus 抓取cAdvisor收集的指標(biāo)數(shù)據(jù)存儲TSDB
Grafana:圖形可視化
初始化 Swarm 集群
安裝docker-ce,如果不指定版本,會安裝最新的latest版本:
Ubuntu下查看Docker-ce版本列表 apt-cache madison docker-ce
Centos查看Docker-ce版本列表 yum list docker-ce --showduplicates | sort -r
Docker-ce 版本 19.03.11~3-0~ubuntu-bionic
基礎(chǔ)環(huán)境:
manager: 192.168.1.220
worker01: 192.168.1.221
worker02: 192.168.1.222
apt install -y apt-transport-https software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt update
apt install docker-ce
協(xié)議端口:
TCP port: 2377 集群管理通訊
TCP and UDP port: 7946 節(jié)點之間通訊
UDP port: 4789 overlay網(wǎng)絡(luò)流量
# 在master機(jī)器上初始化集群,運行
MASTER_IP='192.168.1.220'
docker swarm init --advertise-addr ${MASTER_IP}
# output
Swarm initialized: current node (5tk280gclbz9a4gw0k9vu9bo0) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3lc66oda2binrl7vjfdjtf34tplt7q1bg446po6fgxasx3t48f-a05742d5tpwbkbl8r37hc9p2u 192.168.1.220:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# 在node01 node02節(jié)點運行提示的命令加入到集群中
docker swarm join --token SWMTKN-1-3lc66oda2binrl7vjfdjtf34tplt7q1bg446po6fgxasx3t48f-a05742d5tpwbkbl8r37hc9p2u 192.168.1.220:2377
manager節(jié)點初始化集群后,都會有這樣一個提示,這個的命令只是給個示例,實際命令需要根據(jù)初始化集群后的真實情況來運行。
# 在master機(jī)器上查看當(dāng)前的node節(jié)點
docker node ls
root@docker-swarm-master:~# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mnm180i3plzk2znjmdf0ded3w * docker-swarm-master Ready Active Leader 19.03.11
if8c5iltb2tau6g4v4vcccucr docker-swarm-node01 Ready Active 19.03.11
uu3jlkirrf0d5hf8bx8c5mnqc docker-swarm-node02 Ready Active 19.03.11
監(jiān)控Swarm集群
OK,Swarm集群初始化已經(jīng)完成,基于cAdvisor+InfluxDB+Grafana的yaml腳本
cat docker-compose-monitor.yml
version: '3'
services:
influx:
image: influxdb
volumes:
- influx:/var/lib/influxdb
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
grafana:
image: grafana/grafana
ports:
- 0.0.0.0:80:3000
volumes:
- grafana:/var/lib/grafana
depends_on:
- influx
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
cadvisor:
image: google/cadvisor
hostname: '{{.Node.Hostname}}'
command: -logtostderr -docker_only -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influx:8086
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
depends_on:
- influx
deploy:
mode: global
volumes:
influx:
driver: local
grafana:
driver: local
我們這里只講第二種,基于cAdvisor+Prometheus+Grafana的方案。
git clone https://github.com/cyancow/swarmprom.git
cd swarmprom
ADMIN_USER=admin \
ADMIN_PASSWORD=admin \
SLACK_URL=https://hooks.slack.com/services/9935226 \
SLACK_CHANNEL=devops-alerts \
SLACK_USER=alertmanager \
docker stack deploy -c docker-compose.yml mon
# output
Creating network mon_net
Creating config mon_caddy_config
Creating config mon_dockerd_config
Creating config mon_node_rules
Creating config mon_task_rules
Creating service mon_prometheus
Creating service mon_caddy
Creating service mon_dockerd-exporter
Creating service mon_cadvisor
Creating service mon_grafana
Creating service mon_alertmanager
Creating service mon_unsee
Creating service mon_node-exporter
# 查看部署的stack
docker stack ls
NAME SERVICES ORCHESTRATOR
mon 8 Swarm
# 查看部署的service
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
xnkq61woc3ag mon_alertmanager replicated 1/1 stefanprodan/swarmprom-alertmanager:v0.14.0
tzxe317tffgl mon_caddy replicated 1/1 stefanprodan/caddy:latest *:3000->3000/tcp, *:9090->9090/tcp, *:9093-9094->9093-9094/tcp
06rv2rj9oxbo mon_cadvisor global 3/3 google/cadvisor:latest
ropkluyyxora mon_dockerd-exporter global 3/3 stefanprodan/caddy:latest
29ygw9r4a92c mon_grafana replicated 1/1 stefanprodan/swarmprom-grafana:5.3.4
whqtwwmfvdjl mon_node-exporter global 3/3 stefanprodan/swarmprom-node-exporter:v0.16.0
xv19nuesymol mon_prometheus replicated 1/1 stefanprodan/swarmprom-prometheus:v2.5.0
ia2g1ayhzjf6 mon_unsee replicated 1/1 cloudflare/unsee:v0.8.0
如果想在 Swarm 部署 Portainer的話,需要在docker-compose里加入以下聲明
...
services:
agent:
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
ports:
- target: 9001
published: 9001
protocol: tcp
mode: host
networks:
- net
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
portainer:
image: portainer/portainer
command: -H tcp://tasks.agent:9001 --tlsskipverify
ports:
- "8000:8000"
volumes:
- portainer_data:/data
networks:
- net
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
...
# 使用以下命令更新
docker stack deploy -c docker-compose.yml mon
部署一個服務(wù),然后使用Prometheus監(jiān)控自動發(fā)現(xiàn)
cat test-compose.yml
version: "3.3"
networks:
net:
driver: overlay
attachable: true
mon_net:
external: true
services:
mongo:
image: healthcheck/mongo:latest
networks:
- net
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role != manager
mongo-exporter:
image: forekshub/percona-mongodb-exporter:latest
networks:
- net
- mon_net
ports:
- "9216:9216"
environment:
- MONGODB_URL=mongodb://mongo:27017
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager
# 部署
docker stack deploy -c test-compose.yml mongo
# 查看 stack 列表
docker stack ls
NAME SERVICES ORCHESTRATOR
mon 10 Swarm
mongo 2 Swarm
# 查看 service 列表
docker service ls|grep mongo
o20avg5k0lqb mongo_mongo replicated 1/1 healthcheck/mongo:latest
6atp7sl2byeu mongo_mongo-exporter replicated 1/1 forekshub/percona-mongodb-exporter:latest *:9216->9216/tcp
# 在其中一個節(jié)點查看mongo是否部署成功
docker ps -a|grep mongo
102b337589aa healthcheck/mongo:latest "docker-entrypoint.s…" 18 minutes ago Up 18 minutes (healthy) 27017/tcp mongo_mongo.1.whn157ky895refdogo4s3imrw
總結(jié)
至此對于swarm集群的監(jiān)控已經(jīng)講完了,對于swarm集群里,已經(jīng)植入了一些簡單的rules,關(guān)于Alertmanager與Rules的具體配置,具體可以參考官方網(wǎng)站。