Docker Swarm 网络和服务配置问题及解决方案
问题:
node_exporter
服务未能加入 shared-net
网络,导致 Prometheus 无法连接到 node_exporter
。
错误信息:
monitor_prometheus.1.n17c946xz0qx@liu-virtual-machine | level=error ts=2024-06-28T09:44:20.378Z caller=notifier.go:528 component=notifier alertmanager=http://alertmanager:9093/api/v1/alerts count=0 msg="Error sending alert" err="Post http://alertmanager:9093/api/v1/alerts: dial tcp: lookup alertmanager on 127.0.0.11:53: no such host"
journalctl -f -u docker.service 报以下错误:
6月 28 18:04:39 liu-virtual-machine dockerd[50203]: time="2024-06-28T18:04:39.172574766+08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:172.18.0.3:59776" dns-server="udp:8.8.8.8:53" error="read udp 172.18.0.3:59776->8.8.8.8:53: i/o timeout" question=";smtp.qq.com.\tIN\t AAAA"
6月 28 18:04:43 liu-virtual-machine dockerd[50203]: time="2024-06-28T18:04:43.425425845+08:00" level=error msg="[resolver] failed to query external DNS server" client-addr="udp:172.18.0.3:54774" dns-server="udp:8.8.8.8:53" error="read udp 172.18.0.3:54774->8.8.8.8:53: i/o timeout" question=";smtp.qq.com.\tIN\t A"
逐步解决方案:
1. 检查 Docker 服务和容器
确保所有服务都在运行并处于正确状态:
docker service ls
docker ps -a
docker network ls
发现有容器部署在worker节点,开始认为这里原因。在最后总结完,是dns配置问题。
2. 如果缺少外部网络,创建它
如果 shared-net
网络未列出,请创建它:
docker network create --driver overlay shared-net
3. 修改 docker-compose.yml
文件
确保所有服务都连接到 shared-net
网络。以下是更新后的 docker-compose.yml
文件:
version: '3.8'
volumes:
prometheus_data: {}
grafana_data: {}
networks:
shared-net:
external: true
services:
prometheus:
image: prom/prometheus:v2.11.1
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- /etc/localtime:/etc/localtime:ro
- $PWD/prometheus/:/etc/prometheus/
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
networks:
- shared-net
ports:
- 9090:9090
depends_on:
- cadvisor
alertmanager:
image: prom/alertmanager:v0.18.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- /etc/localtime:/etc/localtime:ro
- $PWD/alertmanager/:/etc/alertmanager/
command:
- '--config.file=/etc/alertmanager/config.yml'
- '--storage.path=/alertmanager'
networks:
- shared-net
ports:
- 9093:9093
cadvisor:
image: lagoudocker/cadvisor:v0.37.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- /etc/localtime:/etc/localtime:ro
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- shared-net
ports:
- 8080:8080
node_exporter:
image: prom/node-exporter:v0.18.0
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints:
- node.role == manager # 确保 node_exporter 运行在 manager 节点
volumes:
- /etc/localtime:/etc/localtime:ro
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- --collector.filesystem.ignored-mount-points
- "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
networks:
- shared-net
ports:
- 9100:9100
grafana:
image: grafana/grafana
user: "104"
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- /etc/localtime:/etc/localtime:ro
- grafana_data:/var/lib/grafana
- $PWD/grafana/provisioning/:/etc/grafana/provisioning/
env_file:
- $PWD/grafana/config.monitoring
networks:
- shared-net
ports:
- 3000:3000
depends_on:
- prometheus
4. 重新部署堆栈
重新部署您的堆栈:
docker stack deploy -c docker-compose.yml your_stack_name
5. 验证网络配置
再次检查 shared-net
网络中是否包含所有服务:
docker network inspect shared-net
6. 验证连接
在 Prometheus 容器中,验证是否可以连接到 node_exporter
:
docker exec -it $(docker ps -q -f name=prometheus) wget -qO- http://node-exporter:9100/metrics
7. 检查容器日志
如果问题仍然存在,请检查 node_exporter
和 Prometheus 容器的日志:
docker logs $(docker ps -q -f name=node_exporter)
docker logs $(docker ps -q -f name=prometheus)
Docker Swarm 中 Prometheus 和 Node Exporter 连接问题的解决过程文档
问题描述
在 Docker Swarm 集群中,Prometheus 无法解析 Node Exporter 的地址,导致无法抓取 Node Exporter 的指标。
主要症状
prometheus
容器无法通过 DNS 名称解析node-exporter
的地址。wget
和ping
命令在prometheus
容器中无法访问node-exporter
。
解决步骤
1. 初步检查
-
检查服务和容器状态: 确保所有服务都在运行并处于正确状态。
docker service ls docker ps -a
-
检查网络配置: 确保所有服务都连接到
shared-net
网络。docker network inspect shared-net
2. 发现问题
- 使用
nslookup
和ping
命令检查 DNS 解析,发现prometheus
容器无法解析node-exporter
的 DNS 名称。docker exec -it <prometheus_container_id> sh nslookup node-exporter ping node-exporter wget -qO- http://node-exporter:9100/metrics
3. 临时解决方案
-
使用 IP 地址配置
prometheus.yml
文件: 确保 Prometheus 可以通过 IP 地址抓取 Node Exporter 的指标。获取
node-exporter
容器的 IP 地址:docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q -f name=monitor_node_exporter)
更新
prometheus.yml
配置文件:global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['10.0.1.58:9100'] # 使用 node-exporter 的 IP 地址
更新并重新部署 Prometheus 服务:
docker service update --force monitor_prometheus
4. 解决 DNS 解析问题
-
修改 Docker Daemon 配置文件: 在
/etc/docker/daemon.json
中添加 DNS 配置,以确保容器可以正确解析 DNS 名称。编辑
/etc/docker/daemon.json
文件,添加 DNS 配置:{ "registry-mirrors": ["https://9g4tfngi.mirror.aliyuncs.com"], "dns": ["8.8.8.8", "8.8.4.4"] }
-
重启 Docker 服务: 使更改生效。
sudo systemctl restart docker
-
确认更改生效:
docker info
5. 验证和重新部署
-
更新
prometheus.yml
文件(可选): 确认 DNS 解析正常后,可以将prometheus.yml
文件恢复为使用 DNS 名称。global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['node-exporter:9100']
-
重新部署服务: 确保所有容器和服务都使用新的 DNS 配置。
docker stack deploy -c docker-compose.yml monitor
-
验证连接: 在
prometheus
容器内,验证是否可以通过 DNS 名称连接到node-exporter
。docker exec -it $(docker ps -q -f name=monitor_prometheus) sh wget -qO- http://node-exporter:9100/metrics
最终结果
通过上述步骤,成功解决了 Prometheus 无法解析 Node Exporter 地址的问题。确保 Docker 的 DNS 配置正确,使 Prometheus 能够通过 DNS 名称抓取 Node Exporter 的指标。
总结
- 初步检查: 确认服务和网络状态。
- 发现问题: 确认 DNS 解析问题。
- 临时解决: 使用 IP 地址配置 Prometheus。
- 根本解决: 修改 Docker Daemon 配置文件,添加 DNS 配置。
- 验证和部署: 确认更改生效并重新部署服务。
通过这些步骤,您成功解决了 Prometheus 无法解析 Node Exporter 地址的问题。
Docker Swarm 中 Prometheus 和 Node Exporter 连接问题解决过程中使用的命令总结
1. 检查服务和容器状态
检查所有 Docker 服务是否在运行状态:
docker service ls
列出所有 Docker 容器:
docker ps -a
2. 检查网络配置
检查 shared-net
网络的配置,确保所有服务都连接到该网络:
docker network inspect shared-net
3. 在容器内进行 DNS 解析测试
进入 prometheus
容器:
docker exec -it <prometheus_container_id> sh
在 prometheus
容器内部使用 nslookup
和 ping
测试 DNS 解析:
nslookup node-exporter
ping node-exporter
尝试访问 node-exporter
的 metrics 端点:
wget -qO- http://node-exporter:9100/metrics
4. 获取 node-exporter
容器的 IP 地址
获取 node-exporter
容器的 IP 地址:
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q -f name=monitor_node_exporter)
5. 更新并重新部署 Prometheus 配置
更新 prometheus.yml
文件,使用 node-exporter
的 IP 地址:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['10.0.1.58:9100']
重新部署 Prometheus 服务:
docker service update --force monitor_prometheus
6. 修改 Docker Daemon 配置文件
编辑 /etc/docker/daemon.json
文件,添加 DNS 配置:
{
"registry-mirrors": ["https://9g4tfngi.mirror.aliyuncs.com"],
"dns": ["8.8.8.8", "8.8.4.4"]
}
重启 Docker 服务以使更改生效:
sudo systemctl restart docker
确认 DNS 配置生效:
docker info
7. 验证连接
进入 prometheus
容器,并尝试访问 node-exporter
的 metrics 端点:
docker exec -it $(docker ps -q -f name=monitor_prometheus) sh
wget -qO- http://node-exporter:9100/metrics
8. 重新部署服务
重新部署整个 Docker Stack,以确保所有容器和服务都使用新的 DNS 配置:
docker stack deploy -c docker-compose.yml monitor
通过这些命令,您成功诊断并解决了 Prometheus 无法解析 Node Exporter 地址的问题。