docker容器间通信加密需在应用层启用tls,而非依赖网络驱动;核心步骤包括创建专用自定义桥接网络、为服务生成含正确san的证书、挂载证书到容器并配置应用使用https/grpc-tls,最后通过openssl s_client等工具验证证书有效性与连接。

容器间通信默认是明文的,要实现加密传输,核心是让应用层协议走 TLS,而不是靠 Docker 网络驱动本身加密。Docker 的 bridge、overlay 等网络模式只负责连通性,不提供链路层或传输层加密。真正起作用的是在容器内运行的服务(如 HTTP API、gRPC、数据库客户端等)启用 TLS,并配合证书管理。
用自定义桥接网络打通基础通信
加密的前提是容器能稳定互通。避免使用默认 bridge 网络,因其不支持容器名自动解析,IP 易变,不利于证书绑定。
- 创建专用网络:
docker network create app-secure - 启动服务时指定该网络:
docker run -d --name api --network app-secure -v /certs:/certs my-api:latest - 同一网络下的容器可直接用服务名通信,例如
curl https://api:8443/health,无需硬编码 IP
为服务配置 TLS 证书
证书需覆盖容器内可解析的主机名(通常是服务名),否则会因 CN/SAN 不匹配导致连接失败。
- 生成 CA 及服务证书(建议用
openssl或cfssl):
CA 私钥ca-key.pem→ CA 证书ca.pem→ 服务私钥api-key.pem→ 服务证书api-cert.pem - 证书的
Subject Alternative Name (SAN)必须包含服务名,例如:DNS:api, DNS:localhost, IP:172.19.0.2 - 将
ca.pem挂载进客户端容器的信任库,或将证书路径传给客户端 SDK(如 Python 的requests.get(..., verify="/certs/ca.pem"))
在容器中启用 HTTPS/gRPC-TLS
以常见服务为例,不是改 Docker 命令,而是改应用启动方式或配置文件:
- Nginx:在
server块中启用ssl on,指定ssl_certificate /certs/api-cert.pem和ssl_certificate_key /certs/api-key.pem - Node.js(Express):用
https.createServer({ key, cert }, app)启动,证书路径指向挂载目录 - PostgreSQL:服务端启用
ssl = on,客户端连接串加?sslmode=verify-full&sslrootcert=/certs/ca.pem
验证与调试要点
加密链路出问题,90% 是证书或 DNS 解析问题,而非网络不通。
- 进入客户端容器执行:
openssl s_client -connect api:8443 -CAfile /certs/ca.pem,看是否返回Verify return code: 0 (ok) - 确认服务容器内能解析自身名字:
getent hosts api应返回容器 IP - 检查证书有效期、权限(容器内需可读)、路径拼写,尤其注意 Windows 换行符导致的 PEM 格式损坏











