从Docker容器连接到CosmosDB

从Docker容器连接到CosmosDB,docker,azure-cosmosdb,Docker,Azure Cosmosdb,我正在努力学习Docker,并且正在慢慢地建立一个解决方案。我创建了一个Azure Function应用程序,它公开了一个Http端点。我创建了Docker文件以在linux容器中构建和运行解决方案(image:mcr.microsoft.com/azure functions/dotnet:3.0,Debian image)。我在一台Windows机器上 我在我的Windows计算机上安装了Azure CosmosDB Emulator,并希望从linux容器中运行的函数应用程序连接到它 我将

我正在努力学习Docker,并且正在慢慢地建立一个解决方案。我创建了一个Azure Function应用程序,它公开了一个Http端点。我创建了Docker文件以在linux容器中构建和运行解决方案(image:
mcr.microsoft.com/azure functions/dotnet:3.0
,Debian image)。我在一台Windows机器上

我在我的Windows计算机上安装了Azure CosmosDB Emulator,并希望从linux容器中运行的函数应用程序连接到它

我将cosmos的连接字符串作为环境变量传递

ARG COSMOS_CONNECTION_STRING="AccountEndpoint=https://host.docker.internal:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
我正试图通过以下代码连接到模拟器:

等待新的CosmosClient(Environment.GetEnvironmentVariable(“AzureCosmosConnectionString”,EnvironmentVariableTarget.Process)
.GetContainer(“数据库名称”、“容器名称”)
.UpsertItemAsync(dto)
.配置等待(错误);
当我这样做的时候,我得到了以下错误(我假设前几行是最相关的,但是如果我错了,我会包括其余的):

我假设此尝试不起作用,至少部分原因是Windows计算机上的证书是为
localhost
创建的,而要从docker连接到它,地址必须是
host.docker.internal

尝试2 将导出的证书添加到运行函数应用程序的Kestrel进程中,希望通过将以下内容添加到我的dockerfile中来实现
ENV ASPNETCORE\u Kestrel\u证书\u默认路径=/src/localhost.pfx

尝试3次 更新
CosmosClient
实例化以包括覆盖
HttpClientFactory
的选项,如下所示:

src/
  scripts/
    azureCosmosDbEmulator.ps1
    trust_cosmos_db_emulator_crt.sh
  certificates/
  DockerFile
CosmosClient=新的CosmosClient(
Environment.GetEnvironmentVariable(“AzureCosmosConnectionString”,EnvironmentVariableTarget.Process),
新CosmosClientOptions
{
HttpClientFactory=()=>
{
使用(var httpClientHandler=new httpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback=httpClientHandler.DangerousAcceptionServerCertificateValidator;
返回新的HttpClient(httpClientHandler);
}
}
});
在上面的每一次尝试中,我仍然看到同样的错误。不知道还有什么可以让它工作

刚在GitHub上找到。似乎我并不孤单。

更新(2/10/2021) SDK现在允许以简单的方式覆盖SSL验证(参考):

旧信息 参考:

步骤1-导出证书 接下来,证书必须是PFX,而不是CRT。它会要求您设置一些密码

第2步-将证书放在您可以从docker复制或访问的位置 例如,在引导Docker时,我将其与我想要运行的代码放在一个可以映射到的文件夹中:

步骤3-获取计算机的IP地址 根据,我使用了
ipconfig
并获得了我的Windows IP

步骤4-启动docker映像 在我的例子中,我使用了一个NetCore3.1SDK,这是微软的官方版本

我用一个交互式shell启动了容器,并将
localhost
映射到我在步骤3中得到的IP。这让您在连接字符串中使用localhost

docker-run-v/c/DockerSample:/DockerSample--add host=“localhost:192.168.1.15”-it mcr.microsoft.com/dotnet/core/sdk:3.1/bin/bash

我还挂载了我保存项目和要导入的证书的文件夹。这不是必需的,但我对Docker不太熟悉,不知道是否有更好的方法通过证书

shell启动后,我基本上运行中描述的命令,并添加证书

步骤5 Docker容器现在应该具有连接到localhost所需的证书,并且您不需要HttpClientFactory

注意:还有一个错误跟踪HttpClientFactory没有在任何地方使用,这是您的错误源

更新(2/10/2021) SDK现在允许以简单的方式覆盖SSL验证(参考):

旧信息 参考:

步骤1-导出证书 接下来,证书必须是PFX,而不是CRT。它会要求您设置一些密码

第2步-将证书放在您可以从docker复制或访问的位置 例如,在引导Docker时,我将其与我想要运行的代码放在一个可以映射到的文件夹中:

步骤3-获取计算机的IP地址 根据,我使用了
ipconfig
并获得了我的Windows IP

步骤4-启动docker映像 在我的例子中,我使用了一个NetCore3.1SDK,这是微软的官方版本

我用一个交互式shell启动了容器,并将
localhost
映射到我在步骤3中得到的IP。这让您在连接字符串中使用localhost

docker-run-v/c/DockerSample:/DockerSample--add host=“localhost:192.168.1.15”-it mcr.microsoft.com/dotnet/core/sdk:3.1/bin/bash

我还挂载了我保存项目和要导入的证书的文件夹。这不是必需的,但我对Docker不太熟悉,不知道是否有更好的方法通过证书

shell启动后,我基本上运行中描述的命令,并添加证书

步骤5 Docker容器现在应该具有连接到localhost所需的证书,并且您不需要HttpClientFactory

注意:还有一个错误跟踪HttpClientFactory没有在任何地方使用,这是您的错误源
ARG CERTIFICATE_PASSWORD="Test|234"
RUN openssl pkcs12 \
-in "/src/localhost.pfx" \
-clcerts \
-nokeys \
-out "/src/localhost.crt" \
-passin pass:${CERTIFICATE_PASSWORD}
RUN cp "/src/localhost.crt" "/usr/local/share/ca-certificates/"
RUN update-ca-certificates
CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
    HttpClientFactory = () =>
    {
        HttpMessageHandler httpMessageHandler = new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
        };

        return new HttpClient(httpMessageHandler);
    },
    ConnectionMode = ConnectionMode.Gateway
};


CosmosClient client = new CosmosClient(endpoint, authKey, cosmosClientOptions);
src/
  scripts/
    azureCosmosDbEmulator.ps1
    trust_cosmos_db_emulator_crt.sh
  certificates/
  DockerFile
COPY ["/scripts/", "/scripts/"]
COPY ["/certificates/", "/certificates/"]
RUN /scripts/trust_cosmos_db_emulator_crt.sh