EC2实例中容器端口映射异常/缺失问题排查求助
问题说明
- 已查阅大量类似帖子及视频教程,但未找到匹配当前部署环境的解决方案,本文篇幅较长,感谢帮助。
我的目标
创建EC2实例并通过互联网连接其中的容器。
最小复现步骤
- 创建.NET Blazor应用
- 在Visual Studio中构建DockerFile(右键点击解决方案资源管理器中的项目名称 -> 添加 -> Docker支持,需调整Dockerfile中新增项目的目录结构,否则可能出错)
- 本地创建镜像
- 本地为镜像打标签
- 推送至DockerHub
- 快速推进…创建任务定义,将容器映射到端口8080(使用AWS控制台操作)
- 更新安全组,允许任意IP访问容器的8080端口(默认安全组配置见下文)
操作步骤(精简版)
本地环境
- 创建SQL Server数据库、Blazor应用、.NET Web API,本地运行一切正常
- 为Blazor应用创建Dockerfile(Visual Studio中右键点击项目 -> 添加 -> Docker支持)
- 为.NET Web API创建Dockerfile
- 创建Docker compose yml文件
- 运行容器,本地容器化环境运行顺畅
- 开始部署至AWS…
- 为本地镜像打标签并推送至DockerHub仓库(替代ECR)
AWS环境
- 通过AWS控制台为Blazor应用、Web API、SQL Server镜像创建任务定义
- 因任务复杂拆分为小任务,目前仅处理Blazor应用
- 创建集群
- 创建服务
- 实例已在集群中运行,但无法通过亚马逊提供的公网DNS或公网IPv4:端口组合访问应用
注意
下文提及两个Blazor应用:
- Blazor_custom_app:包含业务逻辑的自定义应用,是最初创建镜像和任务定义的对象
- Blazor_generic_app:用于测试的通用应用,无任何代码修改,若出现相同问题则可排除自定义代码影响
调试阶段1
- ping IP地址:运行Blazor_custom_app的EC2实例正常运行且可达
- 检查防火墙设置:Windows和Mac上访问均失败,但两台设备防火墙设置无异常
- SSH连接到运行Blazor_custom_app容器的EC2实例
- 执行
docker ps:容器正在运行 - 执行
sudo netstat -tuln:发现Blazor_custom_app容器映射到127.0.0.1 - 在Blazor_custom_app的Program.cs文件中添加以下代码:
if (Environment.GetEnvironmentVariable("AWS_EC2") == "true") { builder.WebHost.UseUrls("http://0.0.0.0:8080"); }
- 本地和Docker Desktop容器化环境重新运行应用:环境变量AWS_EC2设为"false",一切正常
- 为Blazor_custom_app创建新的任务定义、集群和服务,并为容器添加环境变量AWS_EC2
- 仍无法访问应用,推测Program.cs中的显式端口映射未生效
- 至少30次检查安全组、路由表、网络ACL和任务定义,相关配置见下文
任务定义
{ "family": "blazo_demo_app", "containerDefinitions": [ { "name": "blazor_demo_app_container", "image": "thecodeiackiller/blazor_demo:latest", "cpu": 205, "memory": 307, "memoryReservation": 205, "portMappings": [ { "name": "blazor_demo_app_container-8080-tcp", "containerPort": 8080, "hostPort": 8080, "protocol": "tcp", "appProtocol": "http" } ], "essential": true, "environment": [], "environmentFiles": [], "mountPoints": [], "volumesFrom": [], "ulimits": [], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/blazo_demo_app", "mode": "non-blocking", "awslogs-create-group": "true", "max-buffer-size": "25m", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "ecs" }, "secretOptions": [] }, "systemControls": [] } ], "taskRoleArn": "arn:aws:iam::xxxxxxxx2345:role/ecsTaskExecutionRole", "executionRoleArn": "arn:aws:iam::xxxxxxxx2345:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "volumes": [], "placementConstraints": [], "requiresCompatibilities": [ "EC2" ], "cpu": "512", "memory": "1024", "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" } }
默认安全组

路由表

网络ACL

调试阶段2
- 创建Blazor_generic_app,完成所有前置步骤并部署到EC2实例
- SSH连接到运行Blazor_generic_app容器的EC2实例
- 执行
docker ps:容器正在运行,但无关联端口
- 进一步检查容器,确认无端口关联

- 停止并移除EC2实例中运行的Blazor_generic_app容器
- 执行以下命令显式映射容器端口:
docker run -d -p 8080:8080 --name blazor_demo_container <username>/blazor_demo
- 使用AWS控制台自动生成的IP(3.95.178.4)加端口8080,可正常访问Blazor_demo_app
- 此操作仅临时解决问题,但排除了防火墙等潜在问题
我的结论
问题源于.NET默认配置或Docker镜像构建,并非自定义应用代码导致——通用Blazor应用也出现相同问题,推测Docker镜像为根源但无法准确定位。
Dockerfile
# Base image for running the application FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base USER app WORKDIR /app EXPOSE 8080 EXPOSE 8081 # Build stage FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src # Corrected paths for the project files COPY ["blazor_demo.csproj", "./"] # Restore dependencies RUN dotnet restore "./blazor_demo.csproj" # Copy all files and build COPY . . WORKDIR "/src" RUN dotnet build "blazor_demo.csproj" -c $BUILD_CONFIGURATION -o /app/build # Publish stage FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "blazor_demo.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false # Final image FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "blazor_demo.dll"]
后续计划
了解到应用负载均衡器或弹性负载均衡器可规避端口映射问题,但仍希望找到问题根源。
内容的提问来源于stack exchange,提问作者user22874144
相关产品推荐
相关产品推荐

