在 Azure 容器应用中管理机密
凭借 Azure 容器应用,应用程序可以安全地存储敏感配置值。 在应用程序级别定义机密后,安全值可用于容器应用中的修订版。 此外,可以在缩放规则中引用安全值。 有关通过 Dapr 使用机密的信息,请参阅 Dapr 集成。
- 机密的范围仅限于某一应用程序,在应用程序的任何特定修订之外。
- 添加、删除或更改机密不会生成新修订。
- 每种应用程序修订都可以引用一个或多个机密。
- 多种修订可以引用相同机密。
已更新或删除的机密不会自动影响应用中的现有修订。 如果更新或删除了机密,可以通过以下两种方式之一对更改进行响应:
- 部署新修订。
- 重启现有修订。
删除机密之前,请部署不再引用旧密码的新修订。 然后停用引用机密的所有修订。
定义机密
机密定义为一组键/值对。 每个机密的值是直接指定的,或指定为对 Azure 密钥保管库中存储的机密的引用。
在容器应用中存储机密值
当你通过门户或不同的命令行选项定义机密时。
在 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 密钥保管库中存储的机密的引用。 容器应用自动从密钥保管库检索机密值,并使其可用作容器应用中的机密。
若要引用密钥保管库中的机密,必须先在容器应用中启用托管标识,并为该标识授予对密钥保管库机密的访问权限。
若要在容器应用中启用托管标识,请参阅托管标识。
若要授予对密钥保管库机密的访问权限,请在密钥保管库中为创建的托管标识创建访问策略。 在此策略上启用“获取”机密权限。
在 Azure 门户中转到你的容器应用。
在“设置”部分下,选择“标识”。
在“系统分配”选项卡中选择“打开”。
选择“保存”以启用系统分配的托管标识。
在“设置”部分下,选择“机密”。
选择 添加 。
在“添加机密”上下文窗格中输入以下信息:
- 键:机密的名称。
- 类型:选择“密钥保管库引用”。
- 密钥保管库机密 URL:密钥保管库中机密的 URI。
- 标识:用于从密钥保管库检索机密的标识。
选择 添加 。
机密在应用程序级在 resources.properties.configuration.secrets
部分中定义。
"resources": [
{
...
"properties": {
"configuration": {
"secrets": [
{
"name": "queue-connection-string",
"keyVaultUrl": "<KEY-VAULT-SECRET-URI>",
"identity": "system"
}],
}
}
}
此处,secrets
数组中声明了到队列存储帐户的连接字符串。 其值是使用指定的标识自动从密钥保管库检索的。 若要使用用户托管标识,请将 system
替换为该标识的资源 ID。
将 <KEY-VAULT-SECRET-URI>
替换为密钥保管库中的机密的 URI。
创建容器应用时,将使用 --secrets
参数来定义机密。
- 该参数接受以空格分隔的键/值对集。
- 每个对都由等于号 (
=
) 分隔。
- 若要指定密钥保管库引用,请使用
<SECRET_NAME>=keyvaultref:<KEY_VAULT_SECRET_URI>,identityref:<MANAGED_IDENTITY_ID>
格式。 例如,queue-connection-string=keyvaultref:https://mykeyvault.vault.azure.cn/secrets/queuereader,identityref:/subscriptions/00000000-0000-0000-0000-000000000000/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>
替换为密钥保管库中的机密的 URI。 将 <USER_ASSIGNED_IDENTITY_ID>
替换为用户分配的标识的资源 ID。 对于系统分配的标识,请使用 system
而不是资源 ID。
注意
用户分配的标识必须有权读取密钥保管库中的机密。 系统分配的标识不能与 create 命令一起使用,因为它只有在创建容器应用之后才可用。
密钥保管库机密 URI 和机密轮换
密钥保管库机密 URI 必须采用以下格式之一:
https://myvault.vault.azure.cn/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
:引用特定版本的机密。
https://myvault.vault.azure.cn/secrets/mysecret
:引用最新版本的机密。
如果 URI 中未指定版本,则应用将使用密钥保管库中存在的最新版本。 有更新的版本可用时,应用会在 30 分钟内自动检索最新版本。 在环境变量中引用机密的任何活动修订版都会自动重启,以选取新值。
若要完全控制使用哪个机密版本,请在 URI 中指定版本。
在环境变量中引用机密
如定义机密部分中所述,在应用程序级别声明机密后,可以在容器应用中创建新修订时在环境变量中引用这些机密。 当环境变量引用机密时,将使用机密中定义的值进行填充。
示例
下面的示例显示了一个应用程序,该应用程序在应用程序级声明连接字符串。 此连接在容器环境变量和缩放规则中引用。
在容器应用中定义机密后,可以在创建新修订版时在环境变量中引用该机密。
在 Azure 门户中转到你的容器应用。
打开“修订版管理”页。
选择“创建新修订版”。
在“创建和部署新修订版”页中选择一个容器。
在“环境变量”部分选择“添加”。
输入以下信息:
- 名称:环境变量的名称。
- 源:选择“引用机密”。
- 值:选择要引用的机密。
选择“保存”。
选择“创建”以创建新修订版。
在此示例中,应用程序连接字符串声明为 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"
},
"queue-connection-string": {
"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",
"value": "[parameters('queue-connection-string')]"
}]
},
"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-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 \
--secrets "queue-connection-string=$CONNECTIONSTRING" \
--env-vars "QueueName=myqueue" "ConnectionString=secretref:queue-connection-string"
此处,名为 connection-string
的环境变量从应用程序级 queue-connection-string
机密获取其值。
在此示例中,我们通过 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 门户中转到你的容器应用。
打开“修订和副本”页。
选择“创建新修订版”。
在“创建和部署新修订版”页面。
选择一个容器并选择“编辑”。
在“卷装载”部分中,展开“机密”部分。
选择“创建新卷”。
输入以下信息:
注意
如果要加载特定机密,请禁用“装载所有机密”,然后选择要加载的机密。
选择添加。
在“卷名称”下,选择“mysecrets”。
在“装载路径”下,输入“/mnt/secrets”。
选择“保存”。
选择“创建”以创建具有卷装载的新修订版。
在此示例中,在应用程序级别声明了两个机密。 这些机密装载在类型为 Secret
的卷 mysecrets
中。 卷装载在路径 /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"
},
"queue-connection-string": {
"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",
"value": "[parameters('queue-connection-string')]"
},
{
"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
数组中定义机密。 以下示例演示如何在 mysecrets
卷装载中仅加载文件名为 connection-string.txt
的 queue-connection-string
机密。
{
"properties": {
...
"configuration": {
...
"secrets": [
{
"name": "queue-connection-string",
"value": "[parameters('queue-connection-string')]"
},
{
"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
的文件中读取机密。
在此示例中,在应用程序级别声明了两个机密。 这些机密装载在类型为 Secret
的卷 mysecrets
中。 卷装载在路径 /mnt/secrets
处。 然后,应用程序可以将机密作为卷装载中的文件读取。
az containerapp create \
--resource-group "my-resource-group" \
--name myQueueApp \
--environment "my-environment-name" \
--image demos/myQueueApp:v1 \
--secrets "queue-connection-string=$CONNECTIONSTRING" "api-key=$API_KEY" \
--secret-volume-mount "/mnt/secrets"
若要加载特定机密并指定它们在装载的卷中的路径,请使用 YAML 定义应用。
后续步骤