我跨越了两个 Docker 容器:一个包含 CosmosDb 模拟器图像容器,另一个包含我的函数应用程序。这两个容器都使用 Docker Desktop 在 Linux 中运行。
我需要能够从我的函数应用程序容器访问 cosmosDb 容器。事实证明这是有问题的,我花了几天时间才解决,所以我把解决方案放在这里。
Microsoft 指南没有解释如何执行此操作。它实际上的作用是告诉您如何从本地计算机访问 CosmosDb 容器。 https://learn.microsoft.com/en-us/azure/cosmos-db/docker-emulator-linux?tabs=sql-api%2Cssl-netstd21
cosmosdb 模拟器使用的证书始终具有 localhost 域,并且不能将其配置为容器主机名: https://localhost:8081/_explorer/emulator.pem
因此,如何从我的函数应用容器访问 Cosmos 容器?
我找到的解决方案是为 CosmosDb 容器配置固定 ip,然后我可以使用 http://
这里的关键是给 Cosmos 容器一个固定的 IP(在我的例子中是 172.16.238.246),您可以根据上面的微软指南使用它来获取证书。然后您可以从您的应用程序中调用它。请记住设置您的 HOST_IP 变量,以便您可以从本地电脑访问它。
Docker 组成:
networks:
default:
external: false
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
services:
cosmosDb:
container_name: CosmosDb
image: "mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator"
tty: true
restart: always
mem_limit: 3G
cpu_count: 4
environment:
- AZURE_COSMOS_EMULATOR_PARTITION_COUNT=5
- AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true
# Set this as an environment variable in host shell to allow access from your local pc using http://locahost:8081 e.g. $Env:HOST_IP="192.168.0.16"
- AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=${HOST_IP}
ports:
- '8081:8081'
- '10250-10255:10250-10255'
networks:
default:
ipv4_address: 172.16.238.246
healthcheck:
test: ["CMD", "curl", "-fk", "https://localhost:8081/_explorer/emulator.pem"]
interval: 5s
timeout: 10s
retries: 5
start_period: 20s
entrypoint: ["/bin/bash","-c"]
command:
- |
apt-get update -y && apt-get install -y curl
/usr/local/bin/cosmos/start.sh
myFuncApp:
build:
dockerfile: Dockerfile
context: .
container_name: MyFuncApp
image: myfuncapp
ports:
- '80:80'
entrypoint: ["/bin/bash","-c"]
command:
- |
curl -fk -o ~/cosmosemulatorcert.crt https://172.16.238.246:8081/_explorer/emulator.pem
cp ~/cosmosemulatorcert.crt /usr/local/share/ca-certificates/
update-ca-certificates
/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost
depends_on:
cosmosDb:
condition: service_healthy
Dockerfile:
FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4.0-dotnet-isolated6.0 AS base
FROM base AS final
COPY bin/Debug/net6.0 /home/site/wwwroot
RUN apt-get update -y && apt-get install -y curl
ENV CosmosDb__EndpointUrl="https://172.16.238.246:8081"
如果有帮助,我发现我可以在 Docker Compose 文件中使用 Azure Cosmos DB 模拟器的服务名称来引用它。
这是一个例子:
version: '3'
services:
devenv:
image: mcr.microsoft.com/dotnet/sdk:6.0
command: sleep infinity
volumes:
- ..:/workspace
depends_on:
- azurecosmosdb
azurecosmosdb:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
ports:
- 8081:8081
然后您可以使用服务名称和端口号引用模拟器。以下是创建 CosmosClient 的示例。
这里使用的按键是模拟器的默认按键。
CosmosClient client = new ("AccountEndpoint=https://azurecosmosdb:8081;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;");
使用 socat 将
localhost:8081
路由至 cosmosdb:8081
现在证书有效🧙
在应用程序容器上运行:
socat TCP-LISTEN:8081,fork TCP:cosmosdb:8081