AWS EC2实例部署Flask元数据Docker应用卡顿排查求助
问题:Docker部署Flask获取EC2元数据时请求卡顿
我需要构建一个HTML页面,显示指定标题、姓名以及EC2实例元数据(Instance ID、可用区、私有IPv4地址、子网ID)。通过SSH连接EC2实例完成Docker部署后,调用http://127.0.0.1:5000时出现卡顿,无法正常返回页面。
我的Python代码
from flask import Flask from ec2_metadata import ec2_metadata app = Flask(__name__) @app.route('/') def get_instance_metadata(): instance_id = ec2_metadata.instance_id availability_zone = ec2_metadata.availability_zone private_ip = ec2_metadata.private_ipv4 subnet_id = ec2_metadata.network_interfaces[ec2_metadata.mac]['subnet-id'] return f""" <html> <body> <h1>EC2 Metadata</h1> <p><strong>Instance ID:</strong> {instance_id}</p> <p><strong>Availability Zone:</strong> {availability_zone}</p> <p><strong>Private IP:</strong> {private_ip}</p> <p><strong>Subnet ID:</strong> {subnet_id}</p> </body> </html> """ if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
执行的Bash操作步骤
sudo yum update sudo yum install docker sudo systemctl start docker sudo systemctl enable docker sudo systemctl status docker mkdir flask_docker nano flask_docker/app.py nano flask_docker/requirements.txt # 依赖内容: # Flask==1.1.2 # Werkzeug==1.0.1 # Jinja2==2.11.3 # MarkupSafe==1.1.1 # itsdangerous==1.1.0 # click==7.1.2 # ec2-metadata==0.13 # requests==2.26.0 nano flask_docker/Dockerfile # Dockerfile内容: # syntax=docker/dockerfile:1.4 # FROM python:3.8-alpine # WORKDIR /app # COPY requirements.txt requirements.txt # RUN pip3 install -r requirements.txt # COPY . . # CMD ["python3", "app.py"] sudo docker build -t flask_container . sudo docker images sudo docker run -p 5000:5000 -d flask_container sudo docker ps netstat -tulnp curl http://127.0.0.1:5000 # 此处出现卡顿问题
问题分析与解决方法
核心原因
卡顿本质是Docker容器内无法正常访问EC2元数据服务(169.254.169.254),主要由以下几点导致:
- Alpine轻量镜像缺少必要系统依赖,影响HTTP请求正常发起
- Bridge模式下的Docker容器网络无法正确路由到元数据服务地址
- 元数据请求超时设置或网络权限限制
具体解决方案
方案1:使用主机网络运行容器
让容器直接复用EC2实例的网络栈,绕过Bridge模式的路由限制:
sudo docker run --network host -d flask_container
运行后直接访问http://127.0.0.1:5000即可正常获取元数据。
方案2:替换基础镜像为Debian Slim
Alpine镜像的轻量特性导致依赖缺失,换成Debian基础镜像可避免此类问题,修改Dockerfile:
syntax=docker/dockerfile:1.4 FROM python:3.8-slim WORKDIR /app COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt COPY . . CMD ["python3", "app.py"]
重新构建并运行容器:
sudo docker build -t flask_container . sudo docker run -p 5000:5000 -d flask_container
方案3:为Alpine镜像补充必要依赖
在Alpine镜像中安装证书和网络工具,确保HTTP请求正常:
syntax=docker/dockerfile:1.4 FROM python:3.8-alpine WORKDIR /app # 安装必要依赖 RUN apk add --no-cache ca-certificates curl COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt COPY . . CMD ["python3", "app.py"]
重新构建运行即可。
额外检查项
- 确认EC2实例的安全组和NACL未阻止对
169.254.169.254的HTTP访问(默认允许) - 若实例绑定了IAM角色,确保角色拥有访问EC2元数据的权限(基础权限默认开放)
内容的提问来源于stack exchange,提问作者Javier García Fernández
相关产品推荐
相关产品推荐

