各组件在哪里运行
| Azure 服务 | 本地替代方案 | 本地工作流 |
|---|---|---|
| Container Apps | Docker Compose 搭配应用镜像 | 配合健康检查和已发布端口,一起运行各服务 |
| Blob Storage | Azurite | 在端口 10000 使用本地 Blob Storage |
| Azure Functions(容器) | Functions 基础镜像 | 通过 Rosetta 运行 amd64 Functions 镜像 |
| AKS | kubectl 和 k9s 连接 AKS;kwok 提供本地 API | 本地构建和测试,再用 kubectl 和 k9s 操作集群 |
Container Apps:直接测试容器,不依赖模拟器
Container App 运行一个或多个容器,并配置环境变量、机密、入口端口、探针和伸缩规则。容器是容易出问题的部分;使用相同镜像时,它们在 Mac 上和 Azure 中的行为一致。伸缩规则、修订版本和托管身份仍由 Azure 处理;容器内部的一切都可以在本地测试。
用 Compose 和 Azurite 在本地运行 Azure Container App 的容器
- 用 Compose 描述应用。 为 Container App 中的每个容器(主容器及所有边车容器)编写一个 Compose 服务,使用相同镜像、环境变量、入口端口和健康探针。
- 添加 Azurite 存储。 添加基于
mcr.microsoft.com/azure-storage/azurite的服务,发布端口 10000(Blob)、10001(Queue)和 10002(Table),并将应用的存储连接字符串指向该服务。 - 必要时固定为 amd64。 对没有 arm64 构建的镜像(如 Azure Functions 基础镜像),为其服务设置
platform: linux/amd64。它会通过 Rosetta 运行。 - 启动并等待。 运行
docker compose up -d --wait。所有设有健康检查的服务都健康后,命令才会返回。 - 测试后再推送。 通过
localhost调用应用。确认运行正常后,用az acr login --name REGISTRY登录,为镜像打标签,再用docker push推送到 Container Apps 或 AKS 使用的仓库。
services:
web:
image: myregistry.azurecr.io/web:2.1.0
environment:
AZURE_STORAGE_CONNECTION_STRING: >-
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=REPLACE_WITH_AZURITE_DEV_KEY;BlobEndpoint=http://azurite:10000/devstoreaccount1;
ports: ["8080:8080"]
depends_on: [azurite]
azurite:
image: mcr.microsoft.com/azure-storage/azurite
ports: ["10000:10000", "10001:10001", "10002:10002"] Azurite 的通用开发账户密钥位于 Microsoft 的 Azurite 文档中,请从那里复制。在 Compose 网络内,应用通过服务名(azurite:10000)访问 Azurite;从 Mac 上则通过 localhost:10000 访问。
Oxcart 上的 Azurite
Azurite 是 Microsoft 的开源 Azure Storage 模拟器,在端口 10000 至 10002 提供 Blob、Queue 和 Table(Table 为预览版)。我们启动了 Blob 服务并从 Mac 调用:
docker run -d -p 10000:10000 mcr.microsoft.com/azure-storage/azurite \
azurite-blob --blobHost 0.0.0.0
curl -i "http://127.0.0.1:10000/devstoreaccount1?comp=list"
# 403 AuthorizationFailure, Server: Azurite-Blob/3.37.0 (expected for an unsigned request) 未签名请求返回 403 是正确结果:端点已启动且可访问。SDK 使用开发连接字符串后,会为请求签名。
在容器中运行 Azure Functions
我们测试的 Azure Functions 基础镜像仅提供 amd64 构建,因此在 Apple 芯片 Mac 上直接构建会报“no match for platform in manifest”。请以 linux/amd64 构建并运行,Oxcart 会通过 Rosetta 执行:
# Dockerfile
FROM mcr.microsoft.com/azure-functions/python:4-python3.12
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
AzureWebJobsFeatureFlags=EnableWorkerIndexing
COPY . /home/site/wwwroot
docker build --platform linux/amd64 -t my-func .
docker run -d --platform linux/amd64 -p 7071:80 my-func
curl localhost:7071/api/hello 测试中,一个 HTTP 触发函数在 docker run 后约 13 秒,从 x86_64 环境返回响应,Functions 主机日志显示路由已映射且调用成功。运行 docker run 时也要传入 --platform linux/amd64:本地构建的 amd64 专用镜像只有指定平台后才能找到。之后 Azure Functions Core Tools 可通过 func azurecontainerapps deploy 或 func kubernetes deploy 部署同一镜像。
推送到 Azure Container Registry
az acr login --name myregistry
docker buildx build --platform linux/amd64 --load -t myregistry.azurecr.io/web:2.1.0 .
docker push myregistry.azurecr.io/web:2.1.0 按 Container Apps 环境或 AKS 节点池运行的架构构建。Oxcart 不支持推送多平台镜像,因此请为每种架构推送一个标签,或通过 CI 发布多架构清单。
从 Mac 使用 AKS
az aks get-credentials --resource-group RG --name CLUSTER 将 AKS 添加到 kubeconfig,让你能从 macOS 使用 kubectl 和 k9s。用 Oxcart 在本地开发服务,再将相同镜像部署到 AKS。对于本地 API 和控制器测试,kwok 可在 Oxcart 上运行,提供真实控制平面和模拟节点。相关工作流请参见 Mac 上的 Kubernetes 指南。
为什么在 Oxcart 上运行
只有迭代周期足够短,本地测试才有价值。Oxcart 实测 docker run --rm 为 42 ms,停止并移除 20 个容器为 77 ms,是我们测试的三款运行时中最快的。容器的出站连接由 Mac 发起,因此通往 Azure 网络的 VPN 或私有端点路由同样适用。参见 Mac 上的容器网络。
常见问题
Azure Container Apps 有本地模拟器吗?
截至 2026 年 10 月,我们未在 Microsoft 文档中找到官方本地 Container Apps 模拟器;Microsoft 建议用 az containerapp up 从本地源代码部署,并用 Aspire 进行本地编排。Container App 是一组容器,因此实用的本地替代方案是在 Compose 项目中运行相同容器,并用 Azurite 提供存储。
Azurite 能在 Apple 芯片 Mac 上运行吗?
可以。在 Oxcart 上,docker run -d -p 10000:10000 mcr.microsoft.com/azure-storage/azurite azurite-blob --blobHost 0.0.0.0 启动了 Azurite 3.37.0,其 Blob 端点在 localhost:10000 返回响应。
能在 Mac 上的容器中运行 Azure Functions 吗?
可以,使用 --platform linux/amd64。我们测试的 Azure Functions Python 基础镜像(mcr.microsoft.com/azure-functions/python:4-python3.12)没有 arm64 构建,因此直接构建会报“no match for platform in manifest”。在 Oxcart 上以 linux/amd64 构建并运行后,它通过 Rosetta 执行,HTTP 触发函数在 localhost 返回响应。
如何从 Mac 推送到 Azure Container Registry?
运行 az acr login --name REGISTRY,然后运行 docker tag 和 docker push REGISTRY.azurecr.io/app:TAG。在 Oxcart 中,通过 docker login 存储的凭据会保存在 macOS 钥匙串中。
如何在 Mac 上为 AKS 开发?
用 Oxcart 在本地构建和测试应用及其依赖。通过 az aks get-credentials 将 kubectl 和 k9s 连接到 AKS,并在 Oxcart 上用 kwok 对带模拟节点的本地 Kubernetes API 检查清单。参见 Mac 上的 Kubernetes。
Cosmos DB 模拟器呢?
Microsoft 提供基于 Linux 的 Cosmos DB 模拟器镜像(vNext,API for NoSQL)。我们尚未在 Oxcart 上测试,因此请在免费试用期间用自己的项目验证,再决定是否依赖它。
来源与方法
- 示例于 2026-10-10 使用 Oxcart 0.1.2、Mac17,14、macOS 27.2 测试(Azurite 3.37.0 Blob、以 linux/amd64 运行的 Azure Functions Python 4 镜像、Compose)。
- Azurite: https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite。Azure Functions Core Tools: https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local。Container Apps(未找到本地模拟器): https://learn.microsoft.com/en-us/azure/container-apps/quickstart-code-to-cloud。Cosmos DB Linux 模拟器: https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux。核实日期:2026-10-10。
- 容器速度:Oxcart 0.1.2,2026-10-10,Apple M5 Max,8 个 CPU 和 12 GiB,五次采样取中位数;其他运行时于同日较早时间,使用同一台 Mac、同一套测试工具和 docker 29.4 客户端测量。