如何通过反向代理统一暴露多个可视化容器
解读
在国内生产环境中,一个公网 IP 只能绑定 80/443 端口,而微服务架构下 Grafana、Prometheus、Jaeger、Nacos、MinIO 等可视化组件各自监听独立端口。直接映射会暴露内部端口、增大攻击面,且不符合等保 2.0 要求。反向代理的核心价值是**“统一入口 + 七层路由”**:通过域名或路径区分服务,TLS 终结、身份认证、限流、白名单全部在代理层完成,容器侧只需监听容器网络内部端口,实现“零端口映射”暴露。
知识点
- 容器网络模型:所有可视化容器挂到同一自定义 bridge 网络(或 overlay),通过容器名 DNS 解析实现东西向互通,避免 host 模式端口抢占。
- 反向代理选型:
- Traefik:云原生首选,自动发现 Docker label,无需 reload 即可热更新,支持 TCP/UDP 与 HTTPS,Let’s Encrypt 自动证书续期完全合规国内云厂商。
- Nginx:最稳,阿里系、腾讯系镜像源同步快,openresty + lua 可实现 WAF 与灰度,但需外挂 conf 文件或 etcd 做热更新。
- 路由规则:
- 域名路由:
grafana.xxx.com、jaeger.xxx.com——需提前在国内云厂商 DNS 备案。 - 路径路由:
/grafana/、/prometheus/——需加 X-Forwarded-Prefix 重写,防止静态资源 404。
- 域名路由:
- 安全加固:
- 非 root 用户启动容器(USER 指令),只读文件系统(
--read-only),drop 掉所有 capability。 - BasicAuth 或 OIDC 对接企业微信、钉钉 SSO,满足最小权限与审计留痕。
- Header 安全:强制 HSTS、X-Content-Type-Options、X-Frame-Options DENY,通过代理层统一注入。
- 非 root 用户启动容器(USER 指令),只读文件系统(
- 高可用:
- 代理容器双实例 + Swarm VIP 或 K8s Service 做负载均衡,健康检查路径
/ping必须返回 200。 - 配置版本化:Nginx 使用 configmap + GitOps,Traefik 使用 CRD,变更走钉钉审批 + GitLab CI,回滚秒级。
- 代理容器双实例 + Swarm VIP 或 K8s Service 做负载均衡,健康检查路径
答案
- 创建统一网络
docker network create --driver bridge visual - 启动可视化容器,不映射任何宿主机端口,只暴露内部端口并加 label 供 Traefik 识别
docker run -d --name grafana \ --network visual \ -e GF_SERVER_ROOT_URL="https://grafana.xxx.com" \ -l "traefik.enable=true" \ -l "traefik.http.routers.grafana.rule=Host(\`grafana.xxx.com\`)" \ -l "traefik.http.routers.grafana.tls=true" \ -l "traefik.http.routers.grafana.tls.certresolver=ali" \ grafana/grafana:latest - 启动 Traefik 反向代理,绑定 80/443,挂载阿里云 DNS 凭证用于自动 DNS-01 挑战签发证书
docker run -d --name traefik \ --network visual \ -p 80:80 -p 443:443 \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v $PWD/acme.json:/acme.json \ traefik:v3.0 --api.dashboard=true \ --providers.docker=true \ --certificatesresolvers.ali.acme.email=your@xxx.com \ --certificatesresolvers.ali.acme.storage=/acme.json \ --certificatesresolvers.ali.acme.dnschallenge.provider=alidns - 备案与解析:在阿里云 DNS 新增 A 记录
grafana.xxx.com指向公网 IP,ICP 备案完成即可访问。 - 安全验证:
curl -I https://grafana.xxx.com返回 HSTS 与 X-Frame-Options 头。- 宿主机
netstat -tnlp仅能看到 80/443,无 3000 端口暴露,通过等保扫描。
拓展思考
- 蓝绿发布:利用 Traefik weighted 服务标签,把新版本容器权重从 0 逐步调到 100,零中断完成可视化组件升级。
- 边缘场景:在边缘 K3s 集群中,用 Traefik CRD IngressRoute 替代传统 Ingress,HostPort 直接监听 80/443,节省一层 SLB 费用,适合零售门店、加油站等弱网环境。
- 多租户隔离:通过 Traefik Middleware 加 Header 鉴权(X-Tenant-ID),同一套 Grafana 多副本实例根据 Header 路由到不同数据库,实现** SaaS 化可观测平台**,满足金融客户硬多租需求。