从 Kubernetes Pod 调用时 Azure Keyvault 错误请求

Azure Keyvault Bad Request When Called From Kubernetes Pod

我 运行 在将某些服务从 Microsoft Service Fabric 转换为 Kubernetes 时访问 Azure Key Vault 时遇到问题。在我们的 ASP.NET 核心 ConfigureServices 调用中,我们从 Microsoft.Extensions.Configuration.AzureKeyVaultConfigurationExtensions 调用 AddAzureKeyVault 来注入我们配置的一些敏感部分,如下所示。

public void ConfigureServices(IServiceCollection services)
{

    var config = new ConfigurationBuilder()
        .SetBasePath(AppContext.BaseDirectory)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddAzureKeyVault(
            Environment.GetEnvironmentVariable("KEYVAULT_LOCATION"),
            Environment.GetEnvironmentVariable("KEYVAULT_CLIENT_ID"),
            Environment.GetEnvironmentVariable("KEYVAULT_CLIENT_SECRET")
        ).Build();

        //...
}

这在本地 docker 映像 运行 中工作正常,但是一旦部署到 Azure Kubernetes 服务中,pod 就会失败并显示以下内容...

Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'BadRequest'
   at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)

查看 Microsoft.Extensions.Configuration.AzureKeyVaultConfigurationExtensions 的源代码,我可以用最少的代码重现该问题。

public void ConfigureServices(IServiceCollection services)
{
    GetSecrets(
        Environment.GetEnvironmentVariable("KEYVAULT_LOCATION"),
        Environment.GetEnvironmentVariable("KEYVAULT_CLIENT_ID"),
        Environment.GetEnvironmentVariable("KEYVAULT_CLIENT_SECRET")
    ).GetAwaiter().GetResult();
}

public async Task GetSecrets(string loc, string clientId, string clientSecret)
{
    KeyVaultClient.AuthenticationCallback callback =
        (authority, resource, scope) => GetTokenFromClientSecret(authority, resource, clientId, clientSecret);

    IKeyVaultClient _client = new KeyVaultClient(callback);

    //Exception thrown here
    var secrets = await _client.GetSecretsAsync(loc).ConfigureAwait(false);
}

private static async Task<string> GetTokenFromClientSecret(string authority, string resource, string clientId, string clientSecret)
{
    var authContext = new AuthenticationContext(authority);
    var clientCred = new ClientCredential(clientId, clientSecret);
    var result = await authContext.AcquireTokenAsync(resource, clientCred);
    return result.AccessToken;
}

我的问题是,与本地 docker 映像相比,从 AKS 中的 pod 调用此身份验证有何不同,会导致此调用失败?

我已确认 pod 可以访问更广泛的互联网,key vault 没有防火墙,Insights 在 key vault 日志中显示一些身份验证失败。 Client Id 和 Secret 是正确的并且具有正确的权限,因为这在 Docker 中本地工作。我错过了什么?

我只是 运行 你的代码示例在我的机器、本地集群和 AKS 集群上。它在所有地方都有效。请检查您的环境。您可能找错地方了。您的本地环境中必须有一些东西。在不同的环境中尝试 运行。例如:在家里(没有 VPN)。