在 Azure 容器应用 中使用存储挂载

容器应用可以访问不同类型的存储。 如有必要,单个应用可以利用多种类型的存储。

注意

避免在卷名称中使用特殊字符来防止部署失败。 例如,名为 credentials.json 的卷包含一个特殊字符 (.),这会导致部署错误。

存储类型 说明 持久性 用例
容器作用域存储 可用于正在运行的容器的临时存储 在容器关闭之前,数据始终可用 写入本地应用缓存。
副本作用域存储 用于在同一副本中的容器之间共享文件的临时存储 在副本关闭之前,数据始终可用 由挎斗容器处理的主应用容器写入日志文件。
Azure 文件 永久存储 数据持久保存到Azure 文件存储 将文件写入文件共享,使其他系统可以访问数据。

注意

Azure 容器应用 不支持从 Azure NetApp 文件 或 Azure Blob 存储 装载文件共享。

临时存储

容器应用可以读取临时数据并写入临时存储。 临时存储范围可以限定为容器或副本。 每个副本可用的容器范围和副本范围的存储总量取决于分配给副本的 vCPU 总数。

vCPU 临时存储总量
0.25 或更低 1 GiB
0.5 或更低 2 GiB
1 或更低 4 GiB
大于 1 8 GiB

容器范围的存储

容器可以写入其自身的文件系统。

容器文件系统存储具有以下特征:

  • 存储是临时的,当容器关闭或重启时会消失。
  • 只有当前容器中运行的进程才能看到写入此存储的文件。

副本限定存储

可以在 Kubernetes 中装载等效于 EmptyDir (空目录)的临时卷。 此存储的范围限定为单个副本。 使用 EmptyDir 卷在同一副本中的容器之间共享数据。

副本作用域存储具有以下特征:

  • 文件在副本的生存期内保留。
    • 如果复制副本中的容器重启,卷中的文件仍然保留。
  • 副本中的任何 init 容器或应用容器都可以装载相同的卷。
  • 一个容器可以装载多个EmptyDir卷。

若要配置副本范围存储,请先在修订中定义一个EmptyDir卷。 然后在修订中的一个或多个容器内定义卷装载。

先决条件

要求 说明
Azure 帐户 如果你没有帐户,请免费创建一个。
Azure 容器应用 环境 创建容器应用环境。

配置

使用 Azure CLI 配置副本作用域存储时,必须通过 YAML 定义创建或更新容器应用。

  1. 若要更新现有容器应用以使用副本范围的存储,请将应用的规范导出到名为 app.yaml 的 YAML 文件。

    az containerapp show -n <APP_NAME> -g <RESOURCE_GROUP_NAME> -o yaml > app.yaml
    
  2. 对容器应用规范进行以下更改。

    • 将一个 volumes 数组添加到容器应用定义的 template 部分,并定义一个卷。 如果已有一个 volumes 数组,请将新卷添加到该数组。
      • name 是卷的标识符。
      • 使用 EmptyDir 作为 storageType。
    • 对于模板中每个需要装载卷的容器,请在容器定义中的 volumeMounts 数组中定义卷装载。
      • volumeName 是 volumes 数组中定义的名称。
      • mountPath 是容器中卷的装载路径。
    properties:
      managedEnvironmentId: /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME>/providers/Microsoft.App/managedEnvironments/<ENVIRONMENT_NAME>
      configuration:
        activeRevisionsMode: Single
      template:
        containers:
        - image: <IMAGE_NAME1>
          name: my-container-1
          volumeMounts:
          - mountPath: /myempty
            volumeName: myempty
        - image: <IMAGE_NAME_2>
          name: my-container-2
          volumeMounts:
          - mountPath: /myempty
            volumeName: myempty
        volumes:
        - name: myempty
          storageType: EmptyDir
    
  3. 使用 YAML 文件更新容器应用。

    az containerapp update --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> \
        --yaml app.yaml
    

有关完整示例,请参阅 YAML 规范。

若要创建副本作用域的卷并将其装载到容器中,请对 ARM 模板中的容器应用资源进行以下更改:

  • 将一个 volumes 数组添加到容器应用定义的 template 部分,并定义一个卷。 如果已有一个 volumes 数组,请将新卷添加到该数组。
    • name 是卷的标识符。
    • 使用 EmptyDir 作为 storageType。
  • 对于模板中每个需要装载卷的容器,请在容器定义中的 volumeMounts 数组中定义卷装载。
    • volumeName 是 volumes 数组中定义的名称。
    • mountPath 是容器中卷的装载路径。

ARM 模板代码片段示例:

{
  "apiVersion": "2022-03-01",
  "type": "Microsoft.App/containerApps",
  "name": "[parameters('containerappName')]",
  "location": "[parameters('location')]",
  "properties": {

    ...

    "template": {
      "revisionSuffix": "myrevision",
      "containers": [
        {
          "name": "main",
          "image": "[parameters('container_image')]",
          "resources": {
            "cpu": 0.5,
            "memory": "1Gi"
          },
          "volumeMounts": [
            {
              "mountPath": "/myempty",
              "volumeName": "myempty"
            }
          ]
        },
        {
          "name": "sidecar",
          "image": "[parameters('sidecar_image')]",
          "resources": {
            "cpu": 0.5,
            "memory": "1Gi"
          },
          "volumeMounts": [
            {
              "mountPath": "/myempty",
              "volumeName": "myempty"
            }
          ]
        }
      ],
      "scale": {
        "minReplicas": 1,
        "maxReplicas": 3
      },
      "volumes": [
        {
          "name": "myempty",
          "storageType": "EmptyDir"
        }
      ]
    }
  }
}

有关完整示例,请参阅 ARM 模板 API 规范。

若要创建具备副本范围的卷并将其安装到容器中,请使用 Azure 门户部署容器应用的新版本。

  1. 在Azure门户中,转到容器应用。

  2. 在左侧菜单中选择“修订版管理”。

  3. 选择“创建新修订版”。

  4. 选择要在其中装载卷的容器。

  5. 在“编辑容器”上下文窗格中,选择“卷装载”选项卡。

  6. 在 临时存储 部分下,创建包含以下信息的新卷:

    • 卷名称:临时卷的名称。
    • 装载路径:容器中用于装载卷的绝对路径。
  7. 选择“保存”以保存更改并退出上下文窗格。

  8. 选择“创建”以创建新修订版。

Azure 文件存储卷

可以将来自 Azure 文件存储 的文件共享装载为容器中的卷。

Important

Azure 容器应用 只支持经典的 Azure 文件共享,这些文件共享是在存储账户(资源类型)Microsoft.Storage/storageAccounts/fileServices/shares内创建的。 容器应用不支持更新 Microsoft.FileShares 的顶层资源类型。 如果你尝试挂载资源 Microsoft.FileShares ,操作会失败。 要创建支持的文件共享,请参见创建经典的 Azure 文件共享。

Azure 文件存储存储具有以下特征:

  • 挂载位置下写入的文件将存储在文件共享中。
  • 通过装载位置访问共享中的文件。
  • 多个容器可以挂载同一个文件共享,包括位于其他副本、修订或容器应用中的文件共享。
  • 装载共享的所有容器都可以访问由任何其他容器或方法写入的文件。
  • 可以在单个容器中装载多个 Azure 文件存储 卷。

Azure 文件存储同时支持 SMB(服务器消息块)和 NFS(网络文件系统)协议。 您可以使用任一种协议挂载 Azure 文件存储 共享。 环境中定义的文件共享必须配置为存储帐户中文件共享使用的相同协议。

对于新的SMB文件挂载,请使用 托管身份认证(预览) 代替存储账户密钥。 容器应用使用系统分配或用户分配的管理身份,分配给容器应用环境,而非单个容器应用,来认证Azure 文件存储。 该模式消除了检索、存储或轮换存储账户密钥的需求。 您必须在存储定义中明确选择管理身份认证;现有的存储账户密钥挂载仍被支持。

托管身份认证仅适用于SMB共享。 NFS共享使用基于网络的访问控制,不使用SMB认证设置。

要在你的容器中启用 Azure 文件存储 存储,请按照以下方式设置你的环境和容器应用:

  • 在容器应用环境中创建存储定义。
  • 如果你在使用 NFS,则必须使用自定义 VNet 配置环境,并且必须将存储帐户配置为允许从 VNet 进行访问。 有关详细信息,请参阅 Azure 文件存储 中的 NFS 文件共享。
  • 如果你用的是NFS,存储账户应该不需要加密的NFS连接。 容器应用不支持NFS文件共享的传输加密。 如果存储帐户启用了 NFS 的传输中需要加密 设置,或者该设置未配置且启用了 需要安全传输,则挂载会失败,并显示类似 mount.nfs: access denied by server while mounting 的错误。 有关详细信息,请参阅 NFS Azure 文件共享的传输中加密。
  • 如果环境配置了自定义 VNet,则必须允许与子网关联的网络安全组 (NSG) 中的端口 445 和 2049。
  • 在修订中定义类型为AzureFile (SMB) 或NfsAzureFile (NFS) 的卷。
  • 在修订中的一个或多个容器内定义卷装载。
  • 必须可从容器应用的虚拟网络访问Azure 文件存储存储帐户。 有关详细信息,请参阅从虚拟网络授予访问权限。

先决条件

要求 说明
Azure 帐户 如果你没有帐户,请免费创建一个。
Azure 存储帐户 创建一个带有经典Azure文件共享的存储账户。
Azure 容器应用 环境 创建容器应用环境。
SMB认证的托管身份 启用环境的系统分配的托管标识,或为环境分配用户分配的托管标识。 参见 管理环境身份。
SMB 管理身份认证的存储账户设置 在存储账户上为 SMB 启用托管身份(SMBOAuth)。 其 SMB安全设置 还必须允许Kerberos认证。
用于 SMB 托管标识身份验证的 Azure RBAC 将存储文件数据 SMB MI 管理员角色分配给所选环境标识,范围为存储帐户范围。 参见“ 为托管身份分配内置RBAC角色”。 要分配角色,你需要在该范围具有 Microsoft.Authorization/roleAssignments/write 权限。 在挂载共享之前,等待角色分配生效。

配置

将容器应用配置为使用Azure CLI装载Azure 文件存储卷时,必须使用 YAML 定义来创建或更新容器应用。

安装最新的 Azure CLI 并更新 Container Apps 扩展:

az extension add --name containerapp --upgrade

有关挂载 SMB 文件共享的分步教程,请参阅 在 Azure 容器应用 中挂载 Azure 文件存储 存储。

  1. 将存储定义添加到容器应用环境。

    托管身份认证(推荐)

    要使用环境的系统分配托管身份,首先启用它:

    az containerapp env identity assign --name my-env --resource-group my-group \
        --system-assigned
    

    在您的存储账户上赋予该身份“Storage File Data SMB MI Admin”角色,并按照前置条件启用 Managed Identity for SMB。 然后创建存储定义:

    az containerapp env storage set --name my-env --resource-group my-group \
        --storage-name mystorage \
        --storage-type AzureFile \
        --azure-file-account-name <STORAGE_ACCOUNT_NAME> \
        --azure-file-identity system \
        --azure-file-share-name <STORAGE_SHARE_NAME> \
        --access-mode ReadWrite
    

    用你的存储帐户名称和文件共享名称替换 <STORAGE_ACCOUNT_NAME> 和 <STORAGE_SHARE_NAME>。 该值 system 指定环境的系统分配托管标识。

    要使用用户分配的托管身份,可以将其分配给环境:

    az containerapp env identity assign --name my-env --resource-group my-group \
        --user-assigned <MANAGED_IDENTITY_RESOURCE_ID>
    

    在存储账户上赋予该身份相同的角色。 在存储命令中,将 --azure-file-identity system 替换为 --azure-file-identity <MANAGED_IDENTITY_RESOURCE_ID>,并使用该标识的完整 Azure 资源 ID,而不是其客户端 ID 或主体 ID。

    不要将 --azure-file-identity 与 --azure-file-account-key 或 --azure-file-key-vault-secret-url 组合使用。 这些认证模式是互斥的。

    存储账户密钥认证(替代方案)

    如果你不能使用托管身份认证,你可以用存储账户密钥代替:

    az containerapp env storage set --name my-env --resource-group my-group \
        --storage-name mystorage \
        --storage-type AzureFile \
        --azure-file-account-name <STORAGE_ACCOUNT_NAME> \
        --azure-file-account-key <STORAGE_ACCOUNT_KEY> \
        --azure-file-share-name <STORAGE_SHARE_NAME> \
        --access-mode ReadWrite
    

    请将 <STORAGE_ACCOUNT_NAME> 和 <STORAGE_ACCOUNT_KEY> 替换为你的存储帐户的名称和密钥。 请将 <STORAGE_SHARE_NAME> 替换为存储帐户中文件共享的名称。

    --access-mode 的有效值为 ReadWrite 和 ReadOnly。

  2. 若要更新现有容器应用以装载文件共享,请将应用的规范导出到名为 app.yaml 的 YAML 文件。

    az containerapp show -n <APP_NAME> -g <RESOURCE_GROUP_NAME> -o yaml > app.yaml
    
  3. 对容器应用规范进行以下更改。

    • 将一个 volumes 数组添加到容器应用定义的 template 部分,并定义一个卷。 如果已有一个 volumes 数组,请将新卷添加到该数组。
      • name 是卷的标识符。
      • 对于storageType,请对 SMB 使用AzureFile,或对 NFS 使用NfsAzureFile。 此值必须与环境中定义的存储类型匹配。
      • 对于 storageName,请使用在环境中定义的存储的名称。
      • mountOptions 是一个逗号分隔的装载选项字符串。 有关详细信息,请参阅 在 Azure 文件存储 中使用 mountOptions 设置。
      • secrets 列表是要在卷中装载的机密列表。 有关详细信息,请参阅 在卷中挂载机密。
    • 对于要装载Azure 文件存储存储的模板中的每个容器,请在容器定义的 volumeMounts 数组中定义卷装载。
      • volumeName 是 volumes 数组中定义的名称。
      • mountPath 是容器中卷的装载路径。
      • subPath 是要在卷中装载的路径。 如果未指定此值,则会挂载卷的根目录。 更多信息请参见 子路径。
    properties:
      managedEnvironmentId: /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME>/providers/Microsoft.App/managedEnvironments/<ENVIRONMENT_NAME>
      configuration:
      template:
        containers:
        - image: <IMAGE_NAME>
          name: my-container
          volumeMounts:
          - volumeName: azure-files-volume
            mountPath: /my-files
            subPath: my-sub-path
        volumes:
        - name: azure-files-volume
          storageType: AzureFile
          storageName: mystorage
    
  4. 使用 YAML 文件更新容器应用。

    az containerapp update --name <APP_NAME> --resource-group <RESOURCE_GROUP_NAME> \
        --yaml app.yaml
    

有关完整示例,请参阅 YAML 规范。

以下 ARM 模板代码片段演示如何将Azure 文件存储共享添加到容器应用环境并在容器应用中使用它。 对于SMB托管身份认证,在部署存储定义前,先在环境中启用或分配身份,并完成存储账户的前置条件。

  1. 将 storages 子资源添加到容器应用环境。

    托管身份认证(推荐)

    首先,在 Microsoft.App/managedEnvironments 资源上启用托管身份,而不是在 Microsoft.App/containerApps 资源上启用。 要启用环境的系统分配身份,请在你的环境资源中添加以下顶层 identity 属性:

    {
      "identity": {
        "type": "SystemAssigned"
      }
    }
    

    将该片段合并到你现有的环境资源中,保留其其他配置。 使用支持托管身份的环境API版本,如 2026-03-02-preview。 关于资源架构,请参见 Microsoft.App/managedEnvironments。

    在存储账户上启用SMBOAuth(),并按照先决条件中的说明,在存储账户范围内将存储文件数据 SMB MI 管理员角色分配给环境标识。

    然后对该存储资源使用 API 版本 2026-03-02-preview。 将 properties.azureFile.identity 设置为 system,以选择环境的系统分配标识:

    {
      "type": "Microsoft.App/managedEnvironments/storages",
      "apiVersion": "2026-03-02-preview",
      "name": "[concat(parameters('environment_name'), '/myazurefiles')]",
      "properties": {
        "azureFile": {
          "accountName": "[parameters('storage_account_name')]",
          "identity": "system",
          "shareName": "[parameters('storage_share_name')]",
          "accessMode": "ReadWrite"
        }
      }
    }
    

    要改用用户分配的托管身份,应将其添加到环境的顶层 identity 属性中:

    {
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "[parameters('managed_identity_resource_id')]": {}
        }
      }
    }
    

    将 managed_identity_resource_id 参数定义为包含该标识完整 Azure 资源 ID 的 string。 在存储资源中,将 properties.azureFile.identity 设置为 [parameters('managed_identity_resource_id')],而不是 system。 在存储账户上赋予该身份相同的角色。

    保留已分配给环境的任何标识。 如果你启用了两种身份类型,就使用 SystemAssigned,UserAssigned 作为该环境的 identity.type,并保留其 userAssignedIdentities 条目。

    使用托管身份认证时不要包含 accountKey 或 accountKeyVaultProperties 使用。 关于存储资源架构,请参见 Microsoft.App/managedEnvironments/storages。

    存储账户密钥认证(替代方案)

    如果想用存储账户密钥,可以设置 accountKey 并省略 identity。 定义 storage_account_key 模板参数为 secureString。

    {
      "type": "Microsoft.App/managedEnvironments/storages",
      "apiVersion": "2022-03-01",
      "name": "[concat(parameters('environment_name'), '/myazurefiles')]",
      "properties": {
        "azureFile": {
          "accountName": "[parameters('storage_account_name')]",
          "accountKey": "[parameters('storage_account_key')]",
          "shareName": "[parameters('storage_share_name')]",
          "accessMode": "ReadWrite"
        }
      }
    }
    

    这些存储片段假设环境和文件共享已经存在。 如果你在同一模板中部署它们,将环境和文件共享资源添加到存储资源的 dependsOn 数组中。 对于托管身份验证,如果你在该模板中创建了角色分配,还要添加对角色分配的依赖。 部署依赖并不能消除角色分配传播的延迟。

  2. 更新容器应用资源以添加卷和卷装载。

    SMB 认证是在环境的存储定义中配置的。 应用层的卷配置在托管身份和存储账户密钥认证方面是相同的。 如果你在同一个模板中部署存储资源和容器应用,将存储资源添加到容器应用的 dependsOn 数组中。

    {
      "apiVersion": "2023-05-01",
      "type": "Microsoft.App/containerApps",
      "name": "[parameters('containerappName')]",
      "location": "[parameters('location')]",
      "properties": {
    
        ...
    
        "template": {
          "revisionSuffix": "myrevision",
          "containers": [
            {
              "name": "main",
              "image": "[parameters('container_image')]",
              "resources": {
                "cpu": 0.5,
                "memory": "1Gi"
              },
              "volumeMounts": [
                {
                  "mountPath": "/myfiles",
                  "volumeName": "azure-files-volume",
                  "subPath": "my-sub-path"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 3
          },
          "volumes": [
            {
              "name": "azure-files-volume",
              "storageType": "AzureFile",
              "storageName": "myazurefiles"
            }
          ]
        }
      }
    }
    
    • 将一个 volumes 数组添加到容器应用定义的 template 部分,并定义一个卷。 如果已有一个 volumes 数组,请将新卷添加到该数组。
      • name 是卷的标识符。
      • 对于storageType,请对 SMB 使用AzureFile,或对 NFS 使用NfsAzureFile。 此值必须与环境中定义的存储类型匹配。
      • 对于 storageName,请使用在环境中定义的存储的名称。
      • mountOptions 是一个逗号分隔的装载选项字符串。 有关详细信息,请参阅 在 Azure 文件存储 中使用 mountOptions 设置。
      • secrets 列表是要在卷中装载的机密列表。 有关详细信息,请参阅 在卷中挂载机密。
    • 对于要装载Azure 文件存储存储的模板中的每个容器,请在容器定义的 volumeMounts 数组中定义卷装载。
      • volumeName 是 volumes 数组中定义的名称。
      • mountPath 是容器中卷的装载路径。
      • subPath(可选)是要在卷中装载的路径。 如果未指定,则装载卷的根目录。 更多信息请参见 子路径。

有关完整示例,请参阅 ARM 模板 API 规范。

若要在Azure门户中为Azure 文件存储存储配置卷挂载,请先将文件共享添加到容器应用的环境中,然后通过创建新的版本,将卷挂载添加到容器应用。 对于新的 SMB 挂载,选择托管标识身份验证。

  1. 在Azure门户中,导航到容器应用环境。

  2. 对于SMB托管身份认证,选择 设置>身份 ,启用系统分配身份或向环境添加用户分配身份。 在添加共享之前,请完成 Azure 文件存储 前置条件中描述的存储账户设置和角色分配。

  3. 在导航窗格中的“设置”下,选择“卷装载”。

  4. 选择 添加 。

  5. 根据文件共享使用的协议,选择“服务器消息块 (SMB)”或“网络文件系统 (NFS)”。

  6. 在“添加文件共享”上下文菜单中输入以下信息:

    • 名称:环境存储定义的名称。
    • 存储帐户名称:包含文件共享的存储帐户的名称。
    • 认证:选择 托管身份 (推荐)。
    • 身份:从管理身份列表中选择环境的系统分配身份或用户分配给环境的身份。 选择存储账户中带有 存储文件数据SMB MI管理员 角色的身份。
    • 文件共享名称:SMB文件共享的名称。
    • 访问模式:文件共享的访问模式。 有效值为“读/写”和“只读”。

    要使用存储账户密钥认证,请在认证下选择存储账户密钥,然后输入存储账户的访问密钥。 选择一种存储定义的认证方法。

  7. 选择“添加”以退出上下文窗格。

  8. 选择“保存”以提交更改。

  9. 进入容器应用。

  10. 在导航窗格的“应用程序”下,选择“修订和副本”。

  11. 选择“创建新修订版”。

  12. 在“创建并部署新修订”页面中,选择“卷”选项卡。

  13. 选择 添加 。

  14. 在 “添加卷”上下文窗格中,设置以下值。

    • Volume 类型:Azure 文件卷。
    • 名称:输入卷名称。
    • 文件共享名称:选择之前创建的文件共享。
    • 装载选项:(可选)输入以逗号分隔的装载选项字符串。 有关详细信息,请参阅 在 Azure 文件存储 中使用 mountOptions 设置。
  15. 选择“添加”以退出上下文窗格。

  16. 在“创建并部署新修订版”页面,选择容器标签页。

  17. 选择要在其中装载卷的容器。

  18. 在“编辑容器”上下文窗格中,选择“卷装载”选项卡。

  19. 在“卷名称”下方,选择你之前创建的卷。

  20. 在“装载路径”中输入容器中用于装载卷的绝对路径。

  21. 在 子路径(可选)中,输入要装载的卷中的路径。 如果未指定此值,则会挂载卷的根目录。 更多信息请参见 子路径。

  22. 选择“保存”以保存更改并退出上下文窗格。

  23. 选择“创建”以创建新修订版。

子路径

从Azure 文件存储装载文件共享时,可以同时指定装载路径和子路径。

  • 装载路径: 你希望将卷装载到容器中的路径。
  • 子路径:要装载的卷中的路径。

子路径是可选的。 如果您未指定子路径,则会挂载卷的根目录。

子路径是卷根目录中的相对路径。 不要用 / 启动子路径。 如果指定以开头 /的子路径,则容器应用可能不会启动。 例如, my-volume-folder 是有效的子路径,但 /my-volume-folder 不是。

子路径可以引用卷中的文件夹或文件。

  • 如果子路径引用文件夹,装载路径应引用容器中的空文件夹。

  • 如果子路径引用文件,则装载路径应引用容器中尚不存在的文件。

    例如,假设子路径为 my-volume-folder/my-volume-file.txt,装载路径为 /my-container-folder/my-container-file.txt。 该文件夹 /my-container-folder 应已存在于容器中,但不应包含该文件 my-container-file.txt。

系统忽略任何子路径尾部斜杠。