在 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 数组中定义卷装载。
      • volumeNamevolumes 数组中定义的名称。
      • 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 数组中定义卷装载。
    • volumeNamevolumes 数组中定义的名称。
    • 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 文件存储中的文件共享装载为容器中的卷。

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

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

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

要在容器中启用 Azure 文件存储,需要设置环境和容器应用,如下所示:

  • 在容器应用环境中创建存储定义。
  • 如果你在使用 NFS,则必须使用自定义 VNet 配置环境,并且必须将存储帐户配置为允许从 VNet 进行访问。 有关详细信息,请参阅Azure 文件存储中的 NFS 文件共享
  • 如果环境配置了自定义 VNet,则必须允许与子网关联的网络安全组 (NSG) 中的端口 445 和 2049。
  • 在修订中定义类型为AzureFile (SMB) 或NfsAzureFile (NFS) 的卷。
  • 在修订中的一个或多个容器内定义卷装载。
  • 使用的 Azure 文件存储帐户必须可以从容器应用的虚拟网络访问。 有关详细信息,请参阅从虚拟网络授予访问权限

先决条件

要求 说明
Azure 帐户 如果没有,请创建一个试用版订阅
Azure 存储帐户 创建存储帐户
Azure 容器应用环境 创建容器应用环境

配置

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

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

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

    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 的有效值为 ReadWriteReadOnly

  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 数组中定义卷装载。
      • volumeNamevolumes 数组中定义的名称。
      • mountPath 是容器中卷的装载路径。
      • subPath 是要在卷中装载的路径。 如果未指定,则会装载卷的根目录。 有关详细信息,请参阅(#sub-path)。
    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 文件存储共享添加到容器应用环境,并在容器应用中使用该共享。

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

    {
      "type": "Microsoft.App/managedEnvironments",
      "apiVersion": "2022-03-01",
      "name": "[parameters('environment_name')]",
      "location": "[parameters('location')]",
      "properties": {
        "daprAIInstrumentationKey": "[parameters('dapr_ai_instrumentation_key')]",
        "appLogsConfiguration": {
          "destination": "log-analytics",
          "logAnalyticsConfiguration": {
            "customerId": "[parameters('log_analytics_customer_id')]",
            "sharedKey": "[parameters('log_analytics_shared_key')]"
          }
        }
      },
      "resources": [
        {
          "type": "storages",
          "name": "myazurefiles",
          "apiVersion": "2022-03-01",
          "dependsOn": [
            "[resourceId('Microsoft.App/managedEnvironments', parameters('environment_name'))]"
          ],
          "properties": {
            "azureFile": {
              "accountName": "[parameters('storage_account_name')]",
              "accountKey": "[parameters('storage_account_key')]",
              "shareName": "[parameters('storage_share_name')]",
              "accessMode": "ReadWrite"
            }
          }
        }
      ]
    }
    
  2. 更新容器应用资源以添加卷和卷装载。

    {
      "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 数组中定义卷装载。
      • volumeNamevolumes 数组中定义的名称。
      • mountPath 是容器中卷的装载路径。
      • subPath(可选)是要在卷中装载的路径。 如果未指定,则会装载卷的根目录。 有关详细信息,请参阅(#sub-path)。

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

若要在 Azure 门户中为 Azure 文件存储配置卷装载,请将一个文件共享添加到容器应用环境,然后通过创建新修订版将卷装载添加到容器应用。

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

  2. 在导航窗格中的 设置 下,选择 Azure 文件

  3. 选择 添加

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

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

    • 名称:文件共享的名称。
    • 存储帐户名称:包含文件共享的存储帐户的名称。
    • 存储帐户密钥:存储帐户的访问密钥。
    • 文件共享:文件共享的名称。
    • 访问模式:文件共享的访问模式。 有效值为“读/写”和“只读”
  6. 选择“添加”退出上下文窗格。

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

  8. 导航到你的容器应用。

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

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

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

  12. 选择 添加

  13. 在“添加卷”上下文面板中,设置以下内容。

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

  15. 在“创建和部署新修订”页中,选择“容器”选项卡。

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

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

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

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

  20. 子路径(可选)中,输入要装载的卷中的路径。 如果未指定,则会装载卷的根目录。 有关详细信息,请参阅(#sub-path)。

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

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

子路径

从 Azure 文件存储装载文件共享时,除了装载路径之外,还可以指定子路径。

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

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

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

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

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

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

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

忽略所有子路径的尾随斜杠。