你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure 容器应用自定义容器会话(预览版)

除 Azure 容器应用动态会话提供的内置代码解释器外,还可以使用自定义容器来定义自己的会话沙盒。

注意

Azure 容器应用动态会话目前以预览版提供。 有关详细信息,请参阅预览版限制

用于自定义容器会话

使用自定义容器,可以生成满足你需求的解决方案。 你可以通过自定义容器在快捷的临时环境中执行代码或运行应用程序,并使用 Hyper-V 提供安全的沙盒空间。 此外,还可以使用可选的网络隔离来配置自定义容器。 示例包括:

  • 代码解释器:需要使用内置解释器不支持的语言在安全沙盒中执行不受信任的代码时,或者需要完全控制代码解释器环境时。

  • 独立执行:需要在敌对的多租户场景中运行应用程序时,在这种场景下,每个租户或用户都有自己的沙盒环境。 这些环境彼此隔离,并且与主机应用程序也隔离。 一些例子包括运行用户提供的代码的应用程序、允许终端用户访问基于云的 shell 的代码、AI 代理和开发环境。

使用自定义容器会话

要使用自定义容器会话,首先应使用自定义容器映像创建会话池。 Azure 容器应用会使用提供的映像自动在其自己的 Hyper-V 沙盒中启动容器。 容器启动后,该容器可供会话池使用。

当应用程序请求会话时,系统会立即从池中分配实例。 会话保持活动状态,直到进入空闲状态,然后自动停止并销毁。

创建自定义容器会话池

若要创建自定义容器会话池,需要提供容器映像和池配置设置。

使用 HTTP 请求调用或与每个会话通信。 自定义容器必须在指定的端口上公开 HTTP 服务器才能响应这些请求。

若要使用 Azure CLI 创建自定义容器会话池,请使用以下命令确保安装最新版本的 Azure CLI 和 Azure 容器应用扩展:

az upgrade
az extension add --name containerapp --upgrade --allow-preview true -y

自定义容器会话池需要启用了工作负载配置文件的 Azure 容器应用环境。 如果没有环境,请使用 az containerapp env create -n <ENVIRONMENT_NAME> -g <RESOURCE_GROUP> --location <LOCATION> --enable-workload-profiles 命令创建一个。

使用 az containerapp sessionpool create 命令创建自定义容器会话池。

以下示例使用自定义容器映像 myregistry.azurecr.io/my-container-image:1.0 创建名为 my-session-pool 的会话池。

在发送请求之前,请将 <> 括号之间的占位符替换为适合你的会话池和会话标识符的值。

az containerapp sessionpool create \
    --name my-session-pool \
    --resource-group <RESOURCE_GROUP> \
    --environment <ENVIRONMENT> \
    --registry-server myregistry.azurecr.io \
    --registry-username <USER_NAME> \
    --registry-password <PASSWORD> \
    --container-type CustomContainer \
    --image myregistry.azurecr.io/my-container-image:1.0 \ 
    --cpu 0.25 --memory 0.5Gi \
    --target-port 80 \
    --cooldown-period 300 \
    --network-status EgressDisabled \
    --max-sessions 10 \
    --ready-sessions 5 \
    --env-vars "key1=value1" "key2=value2" \
    --location <LOCATION>

此命令使用以下设置创建会话池:

参数 价值 说明
--name my-session-pool 会话池的名称。
--resource-group my-resource-group 包含会话池的资源组。
--environment my-environment 容器应用环境的名称或资源 ID。
--container-type CustomContainer 会话池的容器类型。 必须为自定义容器会话的 CustomContainer
--image myregistry.azurecr.io/my-container-image:1.0 用于会话池的容器映像。
--registry-server myregistry.azurecr.io 容器注册表服务器主机名。
--registry-username my-username 用于登录容器注册表的用户名。
--registry-password my-password 用于登录容器注册表的密码。
--cpu 0.25 所需的 CPU 核心数。
--memory 0.5Gi 所需的内存。
--target-port 80 用于入口流量的会话端口。
--cooldown-period 300 会话终止之前会话可以空闲的秒数。 每次调用会话的 API 都会重置空闲时间。 值必须介于 3003600 之间。
--network-status 指定是否允许从会话发送出站网络流量。 有效值为 EgressDisabled(默认值)和 EgressEnabled
--max-sessions 10 可以同时分配的最大会话数。
--ready-sessions 5 会话池中始终处于就绪状态的目标会话数。 如果会话的分配速度快于池的补充速度,请增加此数字。
--env-vars "key1=value1" "key2=value2" 要在容器中设置的环境变量。
--location "Supported Location" 会话池的位置。

若要更新会话池,请使用 az containerapp sessionpool update 命令。

重要

如果会话用于运行不受信任的代码,请勿包含你不希望不受信任的代码访问的信息或数据。 假设代码是恶意的,并且对容器具有完全访问权限,包括其环境变量、机密和文件。

处理会话

应用程序使用会话池的管理 API 与会话交互。

自定义容器会话的池管理终结点遵循以下格式:https://<SESSION_POOL>.<ENVIRONMENT_ID>.<REGION>.azurecontainerapps.io

若要检索会话池的管理终结点,请使用 az containerapp sessionpool show 命令:

az containerapp sessionpool show \
    --name <SESSION_POOL_NAME> \
    --resource-group <RESOURCE_GROUP> \
    --query "properties.poolManagementEndpoint" \
    --output tsv

对池管理终结点的所有请求都必须包含具有持有者令牌的 Authorization 标头。 若要了解如何使用池管理 API 进行身份验证,请参阅身份验证

每个 API 请求还必须包含具有会话 ID 的查询字符串参数 identifier。 此唯一会话 ID 使应用程序能够与特定会话进行交互。 若要了解有关会话标识符的详细信息,请参阅会话标识符

重要

会话标识符是敏感信息,需要通过一个安全的过程来创建和管理它的值。 要保护此值,应用程序必须确保每个用户或租户仅有权访问其自己的会话。 如果未能保护对会话的访问,可能会导致滥用或未经授权地访问存储在用户会话中的数据。 有关详细信息,请参阅“会话标识符

将请求转发到会话的容器:

基础池管理终结点后面的路径中的任何内容都将转发到会话的容器。

例如,如果调用 <POOL_MANAGEMENT_ENDPOINT>/api/uploadfile,请求将路由到会话的容器 0.0.0.0:<TARGET_PORT>/api/uploadfile

连续会话交互:

可以继续向同一会话发出请求。 如果会话的请求时间超过冷却期,则会自动删除会话。

示例请求

以下示例展示了用户 ID 对自定义容器会话的请求。

在发送请求之前,请将 <> 括号之间的占位符替换为特定于你的请求的值。

POST https://<SESSION_POOL_NAME>.<ENVIRONMENT_ID>.<REGION>.azurecontainerapps.io/<API_PATH_EXPOSED_BY_CONTAINER>?identifier=<USER_ID>
Authorization: Bearer <TOKEN>
{
  "command": "echo 'Hello, world!'"
}

此请求将转发到具有用户 ID 标识符的自定义容器会话。 如果会话尚未运行,则 Azure 容器应用会在转发请求之前从池分配会话。

在此示例中,会话的容器在 http://0.0.0.0:<INGRESS_PORT>/<API_PATH_EXPOSED_BY_CONTAINER> 接收请求。

后续步骤