AWS ECS服务发现与Nginx反向代理配置故障排查
AWS ECS中Nginx反向代理无法解析ECS服务发现上游主机问题排查
我在AWS ECS上搭建环境:Nginx托管React前端,两个Django后端应用通过Nginx反向代理实现通信。已配置ECS服务发现用于服务间通信,但Nginx容器启动时出现[emerg] host not found in upstream错误,无法找到上游主机。
已尝试的操作
- 配置
nginx.conf和default.conf,使用ECS服务发现名称解析后端服务 - 在
nginx.conf中设置解析器为Docker默认DNS127.0.0.11 - 更新Nginx和Django应用的ECS服务发现设置,确认服务已正确注册
- 修改配置后重新构建并部署Docker镜像
- 查看ECS日志,确认错误为上游主机无法找到
配置文件内容
default.conf
upstream healthmanagement { server healthmanagement-service.glucocare-services:8000; } upstream chat { server chat-service.glucocare-services:8000; } server { listen 80; location /api/ { proxy_pass http://healthmanagement; } location /chat/ { proxy_pass http://chat; } # Serve Django static files location /static/django { alias /app/healthcare_project/static/; } # Static Django media files location /media/ { alias /app/healthcare_project/media/; } # Serve React static files location /static/ { alias /usr/share/nginx/html/build/static/; } # Main location block to serve the React app location / { root /usr/share/nginx/html/build; try_files $uri $uri/ /index.html; } }
nginx.conf
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; resolver 172.31.0.2 valid=30s; include /etc/nginx/conf.d/*.conf; # Include all conf files from conf.d directory }
排查与解决思路
1. 验证ECS服务发现DNS解析能力
进入Nginx容器执行nslookup healthmanagement-service.glucocare-services,检查是否能返回后端服务IP:
- 若解析失败,确认后端Django服务是否已成功注册到
glucocare-services命名空间(查看ECS控制台服务发现注册状态) - 确保Nginx与后端服务处于同一VPC,安全组允许DNS查询(默认允许,可检查入出站规则)
- 确认
glucocare-services是私域命名空间,且已正确关联VPC
2. 调整Nginx配置实现动态DNS解析
Nginx默认启动时解析上游主机,若后端服务未就绪会导致启动失败。改用变量实现请求时动态解析:
修改default.conf的server块:
server { listen 80; set $healthmanagement_upstream healthmanagement-service.glucocare-services:8000; set $chat_upstream chat-service.glucocare-services:8000; location /api/ { proxy_pass http://$healthmanagement_upstream; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; } location /chat/ { proxy_pass http://$chat_upstream; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; } # 其余静态文件、React托管配置保持不变 }
3. 优化Nginx resolver配置
当前resolver 172.31.0.2是AWS VPC默认DNS,可补充ipv6=off避免IPv6解析问题:
resolver 172.31.0.2 valid=30s ipv6=off;
也可尝试使用Docker DNS127.0.0.11,但ECS环境中VPC DNS更可靠。
4. 配置ECS任务启动依赖
若Nginx先于后端服务启动,会导致启动时解析失败:
- 在ECS服务中配置服务依赖,让Nginx等待后端服务健康检查通过后再启动(基于服务发现的健康状态)
- 在Nginx的Dockerfile中添加启动等待脚本:
CMD ["/bin/sh", "-c", "until nslookup healthmanagement-service.glucocare-services; do sleep 5; done && nginx -g 'daemon off;'"]
5. 确认后端服务健康状态
检查后端Django服务的ECS任务是否处于运行中且健康检查通过,只有健康任务才会被注册到服务发现。
内容的提问来源于stack exchange,提问作者user24240592
相关产品推荐
相关产品推荐

