.NET Core服务通过Docker Compose部署时无法访问DynamoDB-Local
.NET Core 6 API容器化后无法连接Docker Compose部署的DynamoDB Local
本地运行正常的配置
单独启动DynamoDB Local时,使用以下Docker Compose文件:
version: '3.4' services: dynamodb-local: image: amazon/dynamodb-local:latest container_name: dynamodb-local command: "-jar DynamoDBLocal.jar -sharedDb" ports: - "8000:8000"
Program.cs中配置DynamoDB客户端:
var clientConfig = new AmazonDynamoDBConfig {ServiceURL = "http://localhost:8000" }; builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(clientConfig));
此时通过IIS Express运行API服务,一切正常。
容器化部署后的错误
将API也容器化,使用以下Docker Compose文件:
version: '3.4' services: dynamodb-local: image: amazon/dynamodb-local:latest container_name: dynamodb-local command: "-jar DynamoDBLocal.jar -sharedDb" ports: - "8000:8000" api: image: ${DOCKER_REGISTRY-}api container_name: insurance-service build: context: . dockerfile: src/Api/Dockerfile depends_on: - dynamodb-local
Visual Studio自动生成的docker-compose-override.yml内容:
version: '3.4' services: api: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 ports: - "80" - "443" volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
启动Docker Compose后,API服务启动正常,但保存数据时抛出错误:
Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.
临时调整后的新问题
尝试添加基础凭证避免IAM问题:
var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "http://localhost:8000" }; var creds = new BasicAWSCredentials("xxx", "xxx"); builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));
此时不再出现IAM错误,但API会无限重试连接localhost:8000,确认是容器间网络问题——API容器内的localhost指向自身,无法访问DynamoDB Local容器。
解决方案
修改DynamoDB服务地址:在API的Program.cs中,将ServiceURL改为Docker Compose中DynamoDB的服务名
dynamodb-local,容器间可通过服务名直接通信;同时禁用EC2元数据服务,避免不必要的凭证尝试:var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "http://dynamodb-local:8000", DisableEndpointDiscovery = true, UseHttp = true }; // DynamoDB Local不需要真实凭证,任意值即可 var creds = new BasicAWSCredentials("dummy", "dummy"); builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));优化Docker Compose配置(可选):
- 若不需要从主机直接访问DynamoDB Local,可移除其端口映射,容器间通信无需暴露端口到主机
- 添加健康检查确保API在DynamoDB就绪后再启动:
dynamodb-local: image: amazon/dynamodb-local:latest container_name: dynamodb-local command: "-jar DynamoDBLocal.jar -sharedDb" healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8000/ || exit 1"] interval: 5s timeout: 5s retries: 5 api: image: ${DOCKER_REGISTRY-}api container_name: insurance-service build: context: . dockerfile: src/Api/Dockerfile depends_on: dynamodb-local: condition: service_healthy
内容的提问来源于stack exchange,提问作者dayv2005
相关产品推荐
相关产品推荐

