Azure Container Apps允许应用程序安全地存储敏感配置值。 一旦在应用程序级别定义了机密,加密值即可在您的容器应用中供版本使用。 此外,可以在缩放规则中引用安全值。 有关使用 Dapr 处理机密信息的指南,请参阅 Dapr 集成。
- 机密信息的范围限定于一个应用程序,而不属于应用程序的任何特定修订。
- 添加、移除或更改机密不会生成新修订。
- 每种应用程序修订都可以引用一个或多个机密。
- 多种修订可以引用相同机密。
已更新或删除的机密不会自动影响应用中的现有修订。 如果更新或删除了机密,可以通过以下两种方式之一对更改进行响应:
- 部署新的修订版本。
- 重启现有修订。
删除机密之前,请部署不再引用旧密码的新修订。 然后停用涉及机密的所有修订。
定义机密
机密定义为一组键/值对。 每个机密的值可以直接指定,也可以指定为对存储在 Azure Key Vault 中的机密的引用。
注意
请不要直接在生产环境中指定机密值。 请改用对存储在Azure Key Vault中的机密的引用,如容器应用部分中的 存储机密值中所述。
在容器应用中存储机密值
当您通过门户或不同的命令行选项定义密钥时。
在 Azure 门户 中转到你的容器应用。
在“设置”部分下,选择“机密”。
选择 添加 。
在“添加机密”上下文窗格中输入以下信息:
- 密钥:机密的名称。
- 类型:选择“容器应用机密”。
-
值:密钥的值。
选择 添加 。
机密在应用程序级在 resources.properties.configuration.secrets 部分中定义。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"value": "<MY-CONNECTION-STRING-VALUE>"
}],
}
}
}
此处,队列存储帐户的连接字符串在 secrets 数组中声明。 在此示例中,将 <MY-CONNECTION-STRING-VALUE> 替换为连接字符串的值。
创建容器应用时,将使用 --secrets 参数来定义机密。
- 该参数接受以空格分隔的键/值对集。
- 等号 (
=) 分隔每个对。
az containerapp create \
--resource-group "my-resource-group" \
--name queuereader \
--environment "my-environment-name" \
--image demos/queuereader:v1 \
--secrets "queue-connection-string=<CONNECTION_STRING>"
此处,在 --secrets 参数中声明了队列存储帐户的连接字符串。 将 <CONNECTION_STRING> 替换为连接字符串的值。
创建容器应用时,机密定义为通过 ConfigurationSecrets 参数传递的一个或多个 Secret 对象。
$EnvId = (Get-AzContainerAppManagedEnv -ResourceGroupName my-resource-group -EnvName my-environment-name).Id
$TemplateObj = New-AzContainerAppTemplateObject -Name queuereader -Image demos/queuereader:v1
$SecretObj = New-AzContainerAppSecretObject -Name queue-connection-string -Value $QueueConnectionString
$ContainerAppArgs = @{
Name = 'my-resource-group'
Location = '<location>'
ResourceGroupName = 'my-resource-group'
ManagedEnvironmentId = $EnvId
TemplateContainer = $TemplateObj
ConfigurationSecret = $SecretObj
}
New-AzContainerApp @ContainerAppArgs
此处声明了一个队列存储帐户的连接字符串。
queue-connection-string 的值来自名为 $QueueConnectionString 的环境变量。
从密钥保管库引用机密
定义机密时,将创建对存储在Azure Key Vault中的机密的引用。 容器应用会自动从Key Vault检索机密值,并使它可用作容器应用中的机密。
若要从Key Vault引用机密,必须先在容器应用中启用托管标识,并授予对Key Vault机密的标识访问权限。
若要在容器应用中启用托管标识,请参阅托管标识。
若要授予对Key Vault机密的访问权限,请向托管标识授予 Azure RBAC 角色Key Vault机密用户。
在 Azure 门户 中转到你的容器应用。
在“设置”部分下,选择“身份”。
在“系统分配”选项卡中,将“状态”设置为“启用”。
注意
还可以使用用户分配的托管标识,该标识可跨多个资源重复使用,并且独立于应用生命周期保留。 若要使用它,请选择“用户分配”选项卡并选择现有标识。
选择“保存”以启用系统分配的托管标识。
此时会显示一个弹出窗口,确认要启用系统分配的托管标识,并将容器应用注册到Microsoft Entra ID。 选择 “是”。
在“设置”部分下,选择“机密”。
选择 添加 。
在“添加机密”上下文窗格中输入以下信息:
- 密钥:机密的名称。
-
Type:选择Key Vault引用值。
-
Key Vault机密 URL:Key Vault中机密的 URI。 此 URI 具有以下形式:
https://<YOUR_KEY_VAULT_NAME>.vault.azure.cn/secrets/<YOUR_SECRET_NAME>/<32_DIGIT_HEX_ID>
-
标识:选择“系统分配”。
选择 添加 。
机密在应用程序级在 resources.properties.configuration.secrets 部分中定义。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "<KEY_VAULT_SECRET_URI>",
"identity": "system"
}],
}
}
}
此处,队列存储帐户的连接字符串在 secrets 数组中声明。 使用指定的标识从Key Vault自动检索其值。 若要使用用户托管标识,请将 system 替换为该标识的资源 ID。
将 <KEY_VAULT_SECRET_URI> 替换为Key Vault中机密的 URI。
创建容器应用时,将使用 --secrets 参数来定义机密。
- 该参数接受以空格分隔的键/值对集。
- 等号 (
=) 分隔每个对。
- 若要指定Key Vault引用,请使用
<SECRET_NAME>=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<MANAGED_IDENTITY_ID> 格式。 例如,queue-connection-string=keyvaultref:https://mykeyvault.vault.azure.cn/secrets/queuereader,identityref:/subscriptions/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0/resourcegroups/my-resource-group/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-identity。
az containerapp create \
--resource-group "my-resource-group" \
--name queuereader \
--environment "my-environment-name" \
--image demos/queuereader:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>"
此处,在 --secrets 参数中声明了队列存储帐户的连接字符串。 将 <KEY_VAULT_SECRET_URI> 替换为Key Vault中机密的 URI。 将 <USER_ASSIGNED_IDENTITY_ID> 替换为用户分配的标识的资源 ID。
注意
用户分配的标识必须有权读取Key Vault中的机密。 系统分配的标识不能与 create 命令一起使用,因为它只有在创建容器应用之后才可用。
PowerShell 不支持机密的密钥保管库引用。
Key Vault机密 URI 和机密轮换
Key Vault机密 URI 必须具有以下格式之一:
-
https://myvault.vault.azure.cn/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931: 引用特定版本的密钥。
-
https://myvault.vault.azure.cn/secrets/mysecret:访问最新版本的密钥。
如果 URI 中未指定版本,则应用将使用密钥保管库中存在的最新版本。 有更新的版本可用时,应用会在 30 分钟内自动检索最新版本。 在环境变量中引用机密的任何活动修订版都会自动重启,以选取新值。
若要完全控制使用哪个机密版本,请在 URI 中指定版本。
在环境变量中引用敏感信息
如定义机密部分中所述,在应用程序级别声明机密后,可以在容器应用中创建新修订时在环境变量中引用这些机密。 当环境变量引用机密时,将使用机密中定义的值进行填充。
示例
以下示例展示一个在应用程序级别声明连接字符串的应用程序。 此连接在容器环境变量和缩放规则中被引用。
在容器应用中定义机密后,可以在创建新修订版时在环境变量中引用该机密。
在 Azure 门户 中转到你的容器应用。
在“应用”部分下,选择“修订和副本”。
在“修订和副本”页面中,选择“创建新修订”。
在“创建和部署新修订”页面的“容器”选项卡的“容器映像”部分下,选择容器。
选择 编辑。
在“编辑容器”上下文窗格中,选择“环境变量”选项卡。
选择 添加 。
输入以下信息:
- 名称:环境变量的名称。
-
Source:选择“引用一个机密”。
-
值:选择之前定义的机密。
选择“保存”。
在“创建和部署新修订”页面中,选择“创建”以创建新修订。
在此示例中,应用程序连接字符串声明为 queue-connection-string,并在配置部分的其他地方可用。
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"environment_id": {
"type": "String"
},
"key_vault_secret_uri": { ⬅️
"type": "String" ⬅️
} ⬅️
},
"variables": {},
"resources": [
{
"name": "queuereader",
"type": "Microsoft.App/containerApps",
"apiVersion": "2022-03-01",
"kind": "containerapp",
"location": "[parameters('location')]",
"properties": {
"managedEnvironmentId": "[parameters('environment_id')]",
"configuration": {
"activeRevisionsMode": "single",
"secrets": [ ⬅️
{ ⬅️
"name": "queue-connection-string", ⬅️
"keyVaultUrl": "[parameters('key_vault_secret_uri')", ⬅️
"identity": "system" ⬅️
}] ⬅️
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"env": [
{
"name": "QueueName",
"value": "myqueue"
},
{
"name": "ConnectionString", ⬅️
"secretRef": "queue-connection-string" ⬅️
}
]
}
],
"scale": {
"minReplicas": 0,
"maxReplicas": 10,
"rules": [
{
"name": "myqueuerule",
"azureQueue": {
"queueName": "demoqueue",
"queueLength": 100,
"auth": [
{
"secretRef": "queue-connection-string", ⬅️
"triggerParameter": "connection" ⬅️
}
]
}
}
]
}
}
}
}]
}
此处,名为 connection-string 的环境变量从应用程序级 queue-connection-string 机密获取其值。 此外,Azure Queue Storage 的缩放规则中的身份验证配置使用 queue-connection-string 机密来定义连接。
为避免通过 ARM 模板将机密值提交到源代码管理,请将机密值作为 ARM 模板参数传递。
在此示例中,将使用Azure CLI和环境变量中引用的机密创建容器应用。 若要在Azure CLI中引用环境变量中的机密,请将其值设置为 secretref:,后跟机密的名称。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>" \
--env-vars "QueueName=myqueue" "ConnectionString=secretref:queue-connection-string"
此处,名为 connection-string 的环境变量从应用程序级 queue-connection-string 机密获取其值。
PowerShell 不支持机密的密钥保管库引用。
在此示例中,将使用 Azure PowerShell 创建一个包含引用在环境变量中的机密的容器。 若要通过 PowerShell 在环境变量中引用机密,请将其值设置为 secretref:,后跟机密的名称。
$EnvId = (Get-AzContainerAppManagedEnv -ResourceGroupName my-resource-group -EnvName my-environment-name).Id
$SecretObj = New-AzContainerAppSecretObject -Name queue-connection-string -Value $QueueConnectionString
$EnvVarObjQueue = New-AzContainerAppEnvironmentVarObject -Name QueueName -Value myqueue
$EnvVarObjConn = New-AzContainerAppEnvironmentVarObject -Name ConnectionString -SecretRef queue-connection-string -Value secretref
$TemplateObj = New-AzContainerAppTemplateObject -Name myQueueApp -Image demos/myQueueApp:v1 -Env $EnvVarObjQueue, $EnvVarObjConn
$ContainerAppArgs = @{
Name = 'myQueueApp'
Location = '<location>'
ResourceGroupName = 'my-resource-group'
ManagedEnvironmentId = $EnvId
TemplateContainer = $TemplateObj
ConfigurationSecret = $SecretObj
}
New-AzContainerApp @ContainerAppArgs
此处,名为 ConnectionString 的环境变量从应用程序级 $QueueConnectionString 机密获取其值。
在存储卷中挂载机密
如定义机密部分中所述,在应用程序级别声明机密后,可在您的容器应用中创建新修订版时在卷挂载中引用这些机密。 在卷中装载机密时,每个机密都将作为文件装载到卷中。 文件名是机密的名称,文件内容则是机密的值。 在卷加载中可以加载所有机密,也可以加载特定机密。
示例
在容器应用中定义机密后,可以在创建新修订版时在卷装载中引用该机密。
在 Azure 门户 中转到你的容器应用。
在“应用”部分下,选择“修订和副本”。
在“修订和副本”页面中,选择“创建新修订”。
在“创建和部署新修订”页面的“容器”选项卡的“容器映像”部分下,选择容器。
选择 编辑。
在“编辑容器”上下文窗格中,选择“卷装载”选项卡。
选择“创建新卷”。
在“添加卷”上下文窗格中输入以下信息:
-
卷类型:选择
Secret。
-
名称:
mysecrets
-
挂载所有密钥:已启用
注意
如果要加载特定机密,请禁用“装载所有机密”,然后选择要加载的机密。
选择 添加 。
在编辑容器上下文窗格的卷名称下,选择mysecrets。
在“装载路径”下,输入 /mnt/secrets。
选择“保存”。
在创建和部署新修订页面中,选择创建以创建具有卷挂载的新修订。
在此示例中,在应用程序级别声明了两个机密。 这些机密装载在名为 mysecrets 且类型为 Secret 的卷中。 卷装载在路径 /mnt/secrets 处。 然后,应用程序可以引用卷挂载中的机密。
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"environment_id": {
"type": "String"
},
"key_vault_secret_uri": {
"type": "Securestring"
},
"api-key": {
"type": "Securestring"
}
},
"variables": {},
"resources": [
{
"name": "queuereader",
"type": "Microsoft.App/containerApps",
"apiVersion": "2022-11-01-preview",
"kind": "containerapp",
"location": "[parameters('location')]",
"properties": {
"managedEnvironmentId": "[parameters('environment_id')]",
"configuration": {
"activeRevisionsMode": "single",
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "[parameters('key_vault_secret_uri')",
"identity": "system"
},
{
"name": "api-key",
"value": "[parameters('api-key')]"
}
]
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"volumeMounts": [
{
"name": "mysecrets",
"mountPath": "/mnt/secrets"
}
]
}
],
"volumes": [
{
"name": "mysecrets",
"storageType": "Secret"
}
]
}
}
}]
}
若要加载特定机密并指定它们在装载的卷中的路径,请在卷对象的 secrets 数组中定义机密。 以下示例演示如何在文件名为 queue-connection-string 的 mysecrets 卷装载中仅加载 connection-string.txt 机密。
{
"properties": {
...
"configuration": {
...
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "[parameters('key_vault_secret_uri')",
"identity": "system"
},
{
"name": "api-key",
"value": "[parameters('api-key')]"
}
]
},
"template": {
"containers": [
{
"image": "myregistry/myQueueApp:v1",
"name": "myQueueApp",
"volumeMounts": [
{
"name": "mysecrets",
"mountPath": "/mnt/secrets"
}
]
}
],
"volumes": [
{
"name": "mysecrets",
"storageType": "Secret",
"secrets": [
{
"secretRef": "queue-connection-string",
"path": "connection-string.txt"
}
]
}
]
}
...
}
...
}
在应用中,可以从位于 /mnt/secrets/connection-string.txt 的文件中读取机密。
在此示例中,在应用程序级别声明了两个机密。 这些机密装载在名为 mysecrets 且类型为 Secret 的卷中。 卷装载在路径 /mnt/secrets 处。 然后,应用程序可以将机密作为卷挂载中的文件进行读取。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--user-assigned "<USER_ASSIGNED_IDENTITY_ID>" \
--secrets "queue-connection-string=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<USER_ASSIGNED_IDENTITY_ID>" "api-key=$API_KEY" \
--secret-volume-mount "/mnt/secrets"
若要加载特定机密并指定它们在装载的卷中的路径,请使用 YAML 定义应用。
后续步骤