[英]How to access Azure KeyVault from Asp.net Core Docker container deployed in Azure Kubernetes Service (AKS) as pod?
[英]How to access Azure Keyvault from docker container running locally?
我有一个 docker 映像,其中包含一个 ASP.NET Core 应用程序,该应用程序使用 Azure Key Vault 访问连接字符串等内容。 当我在本地运行图像时,出现此错误:
Unhandled Exception: Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/[guid]. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/[guid]. Exception Message: Tried to get token using Managed Service Identity. Unable to connect to the Managed Service Identity (MSI) endpoint. Please check that you are running on an Azure resource that has MSI setup.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/[guid]. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Environment variable LOCALAPPDATA not set.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/[guid]. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. /bin/bash: az: No such file or directory
据我了解,它首先尝试获取访问令牌作为托管服务身份。 由于它不在 Azure 云中运行,因此无法执行此操作并尝试通过 Visual Studio 连接服务获取它。 由于这不会出现在 docker 映像上,它会尝试使用 Azure CLI,但这并未安装在 docker 映像上。
所以我需要将 Azure CLI 安装到 docker 镜像中。 鉴于 Dockerfile 的基本映像是FROM microsoft/dotnet:2.1-aspnetcore-runtime
,这是如何完成的?
此基本映像是 Alpine OS 映像,所以我是否需要考虑使用 Alpine 安装 Azure CLI?
假设我安装了 Azure CLI,有没有一种方法可以访问 Key Vault,而无需在 Dockerfile 源代码中存储任何凭据或通过纯文本将它们传递给容器?
更一般地说,这里最好的方法是什么。
我当前的解决方案是将环境变量与访问令牌一起使用。
获取密钥并存储在环境变量中(在您进行 az 登录并设置正确的订阅之后):
$Env:ACCESS_TOKEN=(az account get-access-token --resource=https://vault.azure.net | ConvertFrom-Json).accessToken
将代码更改为:
config.AddEnvironmentVariables();
KeyVaultClient keyVaultClient;
var accessToken = Environment.GetEnvironmentVariable("ACCESS_TOKEN");
if (accessToken != null)
{
keyVaultClient = new KeyVaultClient(
async (string a, string r, string s) => accessToken);
}
else
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
}
config.AddAzureKeyVault(
$"https://{builtConfig["KeyVaultName"]}.vault.azure.net/",
keyVaultClient,
new DefaultKeyVaultSecretManager());
您的问题的一个可能解决方案是生成服务主体 ( SP ) 并授予此服务主体访问密钥保管库的权限(通过 RBAC 或 IAM)。 有关创建SP 的Microsoft 文档
使用SP的凭据作为client-id
和client-secret
( 随机示例),然后您可以登录保管库并检索机密。
尽管您提出这个问题已经有一段时间了,但适用于生产环境的另一种选择是使用 x509 证书。
微软有这篇文章解释了如何做到这一点。 您可以使用自签名证书或任何其他有效的 SSL 证书。 这取决于您的需求。
为了简化和自动化E. Staal 的回答,我想出了这个:
更新您的.gitignore
文件,在其底部添加以下行:
appsettings.local.json
在解决方案资源管理器中右键单击该项目,然后单击Properties
; 在Build Events
选项卡中,找到Pre-build event command line
文本框并添加以下代码:
cd /d "$(ProjectDir)" if exist "appsettings.local.json" del "appsettings.local.json" if "$(ConfigurationName)" == "Debug" ( az account get-access-token --resource=https://vault.azure.net > appsettings.local.json )
在您的launchSettings.json
(或使用项目设置下的可视化编辑器)中配置以下值:
{ "profiles": { // ... "Docker": { "commandName": "Docker", "environmentVariables": { "DOTNET_ENVIRONMENT": "Development", "AZURE_TENANT_ID": "<YOUR-AZURE-TENANT-ID-HERE>" } } } }
在您的Program.cs
文件中找到 CreateHostBuilder 方法并相应地更新ConfigureAppConfiguration
块——这里以我的为例:
Host.CreateDefaultBuilder(args).ConfigureAppConfiguration ( (ctx, cfg) => { if (ctx.HostingEnvironment.IsDevelopment()) { cfg.AddJsonFile("appsettings.local.json", true); } var builtConfig = cfg.Build(); var keyVault = builtConfig["KeyVault"]; if (!string.IsNullOrWhiteSpace(keyVault)) { var accessToken = builtConfig["accessToken"]; cfg.AddAzureKeyVault ( $"https://{keyVault}.vault.azure.net/", new KeyVaultClient ( string.IsNullOrWhiteSpace(accessToken) ? new KeyVaultClient.AuthenticationCallback ( new AzureServiceTokenProvider().KeyVaultTokenCallback ) : (x, y, z) => Task.FromResult(accessToken) ), new DefaultKeyVaultSecretManager() ); } } )
如果这仍然不起作用,请验证是否已执行az login
并且az account get-access-token --resource=https://vault.azure.net
是否适合您。
这是因为您的 docker 容器以root用户身份运行,而在密钥保管库中注册的用户是其他用户 (yourusername@yourcmpany.com)
尝试使用此链接中的方法进行安装: https : //github.com/Azure/azure-cli/issues/8863
安装后:
az login --service-principal --username "ServicePrincipalName-or-ID" --password "ServicePrincipalPassword" --tenant "Azure_Tenant"
az keyvault secret show --name "SecretName" --vault-name "KeyVaultName" --query value
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.