两个Docker容器通过TLS通信时出现连接拒绝问题求助
问题解决:Docker容器间FastAPI服务连接拒绝错误
问题描述
我有两个基于Python+FastAPI的Docker容器(app_1与app_2),已配置自签名证书,均可通过浏览器以TLS方式访问。执行docker-compose up --build启动容器后,确认两者处于同一Docker网络,但app_1向app_2发起GET请求时出现connection refused(连接拒绝)错误。
错误原因分析
- 端口与协议不匹配:app_1请求的
http://app_2:8002中,8002是宿主机到容器443端口的映射端口,容器内部通信应直接使用容器监听的443端口;同时app_2启用了TLS,必须用https协议而非http。 - 自签名证书信任问题:requests库默认不信任自签名证书,会导致请求失败。
- 代码语法错误:app_1.py中存在缩进错误的调度器代码,可能导致服务启动异常。
解决方案
1. 修正请求URL与协议
将app_1中的请求地址改为容器内部的HTTPS端口:
url = "https://app_2:443"
2. 处理自签名证书验证
测试环境下可临时禁用证书验证(生产环境建议导入信任证书):
# 在make_request函数中添加 response = requests.get(url, verify=False) # 同时取消urllib3警告注释 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
3. 修复代码缩进错误
app_1.py中存在一行缩进错误的scheduler.enter代码,修正后:
scheduler = sched.scheduler(time.time, time.sleep) def make_rest_call_periodically(): make_request() scheduler.enter(10, 10, make_rest_call_periodically) scheduler.enter(10, 10, make_rest_call_periodically) # 修正缩进 scheduler.run()
4. 可选:配置容器启动依赖
在docker-compose.yml中给app_1添加depends_on,确保app_2先启动:
services: app_1: # ... 其他配置 depends_on: - app_2
修正后的完整代码
app_1.py
from fastapi import FastAPI import ssl import uvicorn import requests import time import urllib3 import sched app = FastAPI() # 禁用自签名证书警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @app.get('/') async def read_root(): return {"message": "Hello from app_1"} def make_request(): # 修正为容器内部HTTPS端口 url = "https://app_2:443" # 禁用证书验证(测试环境) response = requests.get(url, verify=False) if response.status_code == 200: print(response.json()) else: print(f"Request failed status code: {response.status_code}") scheduler = sched.scheduler(time.time, time.sleep) def make_rest_call_periodically(): make_request() scheduler.enter(10, 10, make_rest_call_periodically) # 修正缩进问题 scheduler.enter(10, 10, make_rest_call_periodically) scheduler.run() if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=443, ssl_keyfile="/app/certs/client.key", ssl_certfile="/app/certs/client.crt")
app_2.py(可选启用警告禁用)
from fastapi import FastAPI import ssl import uvicorn import requests import time import urllib3 app = FastAPI() # 可选:禁用自签名证书警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) @app.get('/') async def read_root(): return {"message": "Hello from app_2"} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=443, ssl_keyfile="/app/certs/client2.key", ssl_certfile="/app/certs/client2.crt")
docker-compose.yml(可选添加depends_on)
version: '3' services: app_1: build: context: . dockerfile: Dockerfile.app_1 ports: - 8001:443 container_name: app_1 volumes: - ./certs:/app/certs networks: - my-network depends_on: - app_2 app_2: build: context: . dockerfile: Dockerfile.app_2 ports: - 8002:443 container_name: app_2 volumes: - ./certs:/app/certs networks: - my-network networks: my-network: driver: bridge
内容的提问来源于stack exchange,提问作者Jim Archer
相关产品推荐
相关产品推荐

