Docker 容器网络问题排查与最佳实践 - PushGateway 部署案例分析
qustion
1. 问题背景
在数据中心部署 Prometheus PushGateway 服务时,遇到了一个典型的容器网络访问问题。相同的部署配置在不同数据中心呈现出不同的网络访问结果,本文将详细分析问题的排查过程和解决方案。
2. 问题现象
搭建典型的pushgateway服务,使用了nginx与pushgateway整合,为什么整合呢?主要原因是安全扫描扫描出来很多pushgateway的安全漏洞,也木有经历去修改,直接使用nginx做了deny,配置文件如下:
docker-compose.yaml
docker-compose.yaml
version: "3"
services:
pushgateway:
image: prom/pushgateway:v1.9.0
networks:
- internal-network
privileged: true
restart: always
volumes:
- ./pushgateway_data:/data
command:
- '--persistence.file=/data/pushgateway.data'
- '--persistence.interval=5m'
nginx:
image: nginx:1.23.2
networks:
- internal-network
ports:
- "9091:80" # 对外暴露9091端口,内部转发至80
depends_on:
- pushgateway
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
restart: always
networks:
internal-network: # 自定义网络
nginx.conf
networks:
internal-network: # 自定义网络
nginx.conf
events {}
http {
server {
server_tokens off;
listen 80;
location / {
proxy_pass http://pushgateway:9091; # 代理到 pushgateway 服务
proxy_set_header Host $host;
}
# 禁用访问 pprof 的路径
location ~ ^/(debug|pprof) {
deny all;
return 404;
}
}
}
服务的管理启动使用了service:
**cat /etc/systemd/system/pushgateway.service **
[Unit]
Description=pushgateway Service
Requires=docker.service
After=docker.service
[Service]
Type=simple
User=apppub
Group=apppub
WorkingDirectory=/app/metabank/pushgateway
ExecStart=/bin/bash -c '/usr/bin/docker-compose up & sleep 5 && /usr/bin/docker-compose logs -f pushgateway >> /app/metabank/pushgateway/pushgateway_logs/pushgateway.log 2>&1'
ExecStop=/bin/bash -c '/usr/bin/docker-compose down'
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
数据中心服务器由合作方提供,但是部署过程中出现了下面的问题:
- 数据中心A:服务正常,容器间网络互通,外部可访问
- 数据中心B:本地访问正常,跨主机访问异常
问题排查过程
镜像一致性验证
首先验证了 prom/pushgateway:v1.9.0
镜像的一致性,通过对比 SHA256 确认镜像完全一致,排除镜像问题。
网络模式测试
将网络模式修改为 host 模式后,服务恢复正常,初步锁定为容器网络配置问题。
系统参数对比
通过 sysctl -a
对比发现关键差异:
# 数据中心A
net.ipv4.ip_forward = 1
# 数据中心B
net.ipv4.ip_forward = 0
核心问题解析
net.ipv4.ip_forward 参数说明
该参数控制 Linux 系统的 IP 转发功能:
- 1: 启用 IP 转发
- 0: 禁用 IP 转发
在容器环境中,该参数对网络模式的影响:
- bridge 模式需要启用 IP 转发
- host 模式不依赖 IP 转发
Docker 网络模式对比
下面是常用的集中网络模式,更全面的可以参照:https://blog.csdn.net/qq_41917355/article/details/142833506
Bridge 模式(默认)
- 创建独立的网络命名空间
- 容器间通过虚拟网桥通信
- 需要 IP 转发支持
- 优点:隔离性好
- 缺点:性能有一定损耗
Host 模式
- 共享主机网络栈
- 直接使用主机端口
- 不需要 IP 转发
- 优点:网络性能好
- 缺点:端口容易冲突
Container模式
优点:
- -容器间共享网络命名空间,通信效率高
- -适合不同容器需要共享网络栈的场景
- -节省系统资源
缺点:
- 容器间网络隔离性差
- 可能存在端口冲突
- 依赖于另一个容器的网络配置
None 模式
- 完全隔离的网络环境
- 适用于不需要网络的场景
优化后的部署方案
由于中心的系统参数不能进行修改,不能保证两个中心配置文件一致,只能保证两个中心的pushgateway服务功能端口一致,故采用了host的网络模式进行部署:
Host 模式部署配置
# docker-compose.yaml
version: "3"
services:
pushgateway:
image: prom/pushgateway:v1.9.0
network_mode: "host"
privileged: true
restart: always
volumes:
- ./pushgateway_data:/data
command:
- '--persistence.file=/data/pushgateway.data'
- '--persistence.interval=5m'
- '--web.listen-address=127.0.0.1:9092' # pushgateway只监听本地9092端口
nginx:
image: nginx:1.23.2
network_mode: "host"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
restart: always
depends_on:
- pushgateway
# nginx.conf
events {}
http {
server {
server_tokens off;
listen 9091; # nginx对外监听9091端口
location / {
proxy_pass http://127.0.0.1:9092; # 转发到本地9092端口
proxy_set_header Host $host;
}
location ~ ^/(debug|pprof) {
deny all;
return 404;
}
}
}
服务启动配置
# /etc/systemd/system/pushgateway.service
[Unit]
Description=pushgateway Service
Requires=docker.service
After=docker.service
[Service]
Type=simple
User=apppub
Group=apppub
WorkingDirectory=/app/metabank/pushgateway
ExecStart=/bin/bash -c '/usr/bin/docker-compose up & sleep 5 && /usr/bin/docker-compose logs -f pushgateway >> /app/metabank/pushgateway/pushgateway_logs/pushgateway.log 2>&1'
ExecStop=/bin/bash -c '/usr/bin/docker-compose down'
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
通过上述配置文件的修改,该中心pushgateway服务可以正常使用。
最佳实践建议
- 在无法修改系统参数的环境中,优先考虑使用 host 网络模式
- 使用 host 模式时注意端口冲突问题
- 通过 nginx 反向代理增加安全性控制
- 合理规划端口映射,避免端口冲突
- 做好日志收集和监控
总结
本文通过一个实际案例,详细讲解了容器网络问题的排查思路和解决方案。在实际运维工作中,了解不同网络模式的特点和系统参数的影响至关重要。通过合理选择网络模式,可以在不同环境约束下实现最优的部署方案。