【问题标题】:Access a Cosmos DB in a virtual network from a Function app从函数应用访问虚拟网络中的 Cosmos DB
【发布时间】:2019-07-20 21:55:02
【问题描述】:

为这篇长文道歉,但我已经在这个问题上工作了好几天,但似乎找不到解决方案。

情况

我想通过将 Cosmos DB 放置在虚拟网络 (VNet) 中来限制对 Azure 中的 Cosmos DB 的访问,并且只允许通过函数应用进行访问。

方法

第一部分很简单:创建一个 Cosmos DB 和一个 VNet,并按照here 的描述配置数据库的服务端点。

可以通过两种方式将函数应用连接到 VNet。

使用网关

按照this 指南,我已经为我的 VNet 配置了一个网关子网,并按照说明添加和配置了一个 VPN 网关。

之后,我将网关子网添加到 Cosmos DB 服务端点配置并设置我的 Function App

使用 VNet(预览)功能选择子网

这种方法更容易设置,但如 microsoft docs 中所述,它不适用于生产工作负载。
配置更简单,但由于结果相同,我在本文的其余部分省略了此选项。

配置

VNet

网关

宇宙数据库

功能应用

问题

尝试从我的函数应用连接到 Cosmos DB 时,我不断收到连接错误:

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "Unable to proceed with the request. Please check the authorization claims to ensure the required permissions to process the request.\r\nActivityId: f784890f-2e1a-4e36-bfb9-8f62ff32c034, Microsoft.Azure.Documents.Common/2.2.0.0, Windows/10.0.14393 documentdb-netcore-sdk/2.2.2",
    "ExceptionType": "Microsoft.Azure.Documents.DocumentClientException",
    "StackTrace": "   at Microsoft.Azure.Documents.Client.ClientExtensions.ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings, Boolean throwOnKnownClientErrorCodes)\r\n   at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.GetDatabaseAccountAsync(Uri serviceEndpoint)\r\n   at Microsoft.Azure.Documents.Routing.GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(Uri defaultEndpoint, IList`1 locations, Func`2 getDatabaseAccountFn)\r\n   at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.InitializeReaderAsync()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.InitializeGatewayConfigurationReader()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.GetInitializationTask()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.EnsureValidClientAsync()\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.ReadDatabasePrivateAsync(String databaseLink, RequestOptions options, IDocumentClientRetryPolicy retryPolicyInstance)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.<>c__DisplayClass1_0.<<ExecuteAsync>b__0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteRetryAsync(Func`1 callbackMethod, Func`3 callShouldRetry, Func`1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying(ExceptionDispatchInfo capturedException)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteRetryAsync(Func`1 callbackMethod, Func`3 callShouldRetry, Func`1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.BackoffRetryUtility`1.ExecuteAsync(Func`1 callbackMethod, IRetryPolicy retryPolicy, CancellationToken cancellationToken, Action`1 preRetryCallback)\r\n   at Microsoft.Azure.Documents.Client.DocumentClient.CreateDatabaseIfNotExistsPrivateAsync(Database database, RequestOptions options)\r\n   at VnetTestFunction.Function1.Run(HttpRequest req, ILogger log) in C:\\Development\\VnetTestFunction\\VnetTestFunction\\Function1.cs:line 39"
}

这两种方法没有区别。在这两种情况下,我的函数应用和数据库之间都没有连接。

作为测试,我按照this 教程添加了一个虚拟机并设置了一个代理。这可行,因此函数应用可以访问 VNet。

我的直觉说这是某个地方的一些配置问题,但我无法找出哪里。我会继续搜索,但非常感谢任何帮助。

使用的在线资源

【问题讨论】:

    标签: azure-functions azure-cosmosdb azure-virtual-network


    【解决方案1】:

    我相信您的配置是正确的,因为这两种方法都不应该按您的意愿工作。

    对于VNet Integration feature,您可以使用此网关安全地访问 VNet 中的资源。

    VNet 集成使您的 Web 应用(或函数应用)可以访问您的资源中的资源 虚拟网络,但不授予对您的 Web 应用程序的私有访问权限 虚拟网络。

    另外,Cosmos DB 不是 Azure VNet 中的资源,实际上你并没有使用这种方法限制 Azure 函数对 Cosmos DB 的访问。您的 Function App 已连接到 Internet 和您的 VNET。它仍然可以通过 Internet 从 Function App 到 Cosmos DB。

    此外,一旦在特定子网中启用 Cosmos DB 服务终结点,这确实会限制对 Azure Cosmos DB 帐户的访问,并在虚拟网络中使用来自此授权子网的连接。如果您只在 Cosmos DB 的防火墙中配置授权子网,我认为只有来自授权子网的请求才能绕过防火墙。在这种情况下,Azure 函数也不是授权子网中的资源。

    当您在 Azure VNet 中添加 VM 并按照integrating a Function App with an Azure Virtual Network 的过程设置代理时。在这种情况下,VM 是部署在 Azure VNet 中的资源。因此,您可以使用 VNet 集成功能在专用 VNet 中访问它。

    据我所知,如果您希望在 VNet 中使用 Azure Function App,您可以在 App Service Environments 中部署应用服务,这会将 Azure 应用服务直接部署到 Azure 虚拟网络中。当然,这是一个非常高的规模和成本。

    【讨论】:

    • 您好,南希,谢谢您的回答。它阐明了为什么它不起作用,但不幸的是,如果不使用像 App Service Environment 这样的昂贵构造,就不可能进行这样的构造。我将检查其他可能性,并将我的发现发布回这个问题。问候, Geert-Jan
    • 根据您实际想要做的事情,您还可以在容器中运行您的函数 (medium.com/@santiagom.iglesias/…)。是的,你不会有很好的无服务器/消费模型,但你可以把它放在 VNET 中或用它做任何事情。例如。在 Azure 容器实例中运行它(如果您不想 24/7 运行函数)
    • @Nancy:还没有。不幸的是,这不是我们积压的唯一问题。但是,我们计划在我们的办公室计划一个研讨会/小型黑客会议,以尝试找出我们的选择。根据结果​​,我将在此处发布更新。
    • @NancyXiong 如果您通过 vnet 集成让应用服务访问 vnet,是否可以强制功能应用程序/Web 应用程序采用 通过 vnet 使用 vnet 中 CosmosDB 服务终结点的本地 IP 地址?我不确定它如何与 VNET 的 DNS 一起工作,以及它是否应该自动工作(我在 docs.microsoft.com/en-us/azure/app-service/… 上读到了一些关于 AppSetting 的内容)
    猜你喜欢
    • 2015-08-21
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    相关资源
    最近更新 更多