Docker容器内Flask API无法调用另一容器REST API的问题排查
问题描述
通过Docker Compose分别部署了Flask API(hardware-reservation-api)+ MongoDB容器,以及Go语言开发的REST API(config-manager)。Flask API尝试调用http://config-manager:4000/env-config时出现超时,但本地运行Flask API并改用localhost:4000调用时可正常工作。
相关配置如下:
Flask服务的docker-compose.yaml
version: '3.9' services: mongo: image: mongo ports: - "27017:27017" hardware-reservation-api: build: . ports: - "7070:7070" environment: MONGO_URI: mongodb://mongo:27017/ depends_on: - mongo
Flask的Dockerfile
FROM python:3.6.5-slim WORKDIR /app ADD . /app RUN pip install --trusted-host pypi.python.org -r requirements.txt EXPOSE 7070 CMD ["python", "app.py"]
config-manager的docker-compose.yaml
version: '3.9' services: config-manager: build: . container_name: config-manager ports: - "4000:4000"
config-manager的Dockerfile
FROM golang:latest # Set the working directory to /app WORKDIR /app # Copy the go.mod and go.sum files to the container COPY go.mod . COPY go.sum . # Download all dependencies. This step can be cached unless the mod/sum files are changed. RUN go mod download # Copy the current directory contents into the container at /app COPY . . # Build the Go app RUN go build -o main . # Expose port 4000 for the API to listen on EXPOSE 4000 CMD ["./main"]
Flask API调用代码
api_url = config.get('flask', 'config_manager_url', fallback='http://config-manager:4000/env-config') params = {'path': environment_name} response = requests.get(api_url, params=params) if response.status_code == 200: # The API call was successful response_data = yaml.load(response.content, Loader=yaml.FullLoader) return response_data, "" else: val = f"Error: fetching configuration failed from config manager {response.status_code} - {response.text}" return None, val
问题原因
Docker Compose默认会为每个独立的docker-compose.yaml文件创建专属默认网络,两个不同的Compose项目处于完全隔离的网络环境中。Flask容器所在的网络无法解析config-manager这个服务名称,也无法访问另一个网络内的容器,因此出现调用超时。
解决方案
方法1:合并到同一个Docker Compose文件
将Flask、MongoDB和config-manager服务放到同一个docker-compose.yaml中,所有服务会自动加入同一默认网络,服务名可直接相互解析:
version: '3.9' services: mongo: image: mongo ports: - "27017:27017" hardware-reservation-api: build: ./path-to-flask-project # 调整为Flask项目的实际目录路径 ports: - "7070:7070" environment: MONGO_URI: mongodb://mongo:27017/ depends_on: - mongo - config-manager config-manager: build: ./path-to-go-project # 调整为Go项目的实际目录路径 ports: - "4000:4000"
方法2:创建共享自定义网络
手动创建一个Docker网络,让两个Compose项目都加入该网络,实现跨项目服务通信:
- 创建自定义网络:
docker network create shared-services-network
- 修改Flask的
docker-compose.yaml,加入共享网络:
version: '3.9' services: mongo: image: mongo ports: - "27017:27017" networks: - shared-network hardware-reservation-api: build: . ports: - "7070:7070" environment: MONGO_URI: mongodb://mongo:27017/ depends_on: - mongo networks: - shared-network networks: shared-network: external: true name: shared-services-network
- 修改config-manager的
docker-compose.yaml,加入共享网络:
version: '3.9' services: config-manager: build: . container_name: config-manager ports: - "4000:4000" networks: - shared-network networks: shared-network: external: true name: shared-services-network
方法3:使用宿主机IP访问(不推荐)
让Flask调用宿主机的实际IP(例如http://192.168.x.x:4000/env-config),但该方法依赖宿主机网络配置,移植性差,不适合生产环境。
内容的提问来源于stack exchange,提问作者Basu
相关产品推荐
相关产品推荐

