从 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)。
我 运行 在将某些服务从 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)。