迁移 Azure Function 到 Kubernetes
在 Azure 上运行 Azure Function 和在 AKS 上运行存在显著差异。因此,如果可能,应该优先采用主流的 Web 框架(如 Express.js)来实现 HTTP API,或者使用 Kubernetes CronJob 实现定时任务。强烈不建议先开发 Azure Function 应用再迁移到 AKS,而是建议直接采用如 Express.js 这类主流框架进行 NodeJS 应用开发。
通用改动
以非 root 用户身份运行容器
作为一个安全实践,大部分的 Kubernetes 集群都不允许使用 root 用户运行容器。大多数现代的 Docker 镜像都内置了一个 UID 为 1000 的非 root 用户。如果没有,那么在 Dockerfile 中创建一个非 root 用户,并通过 USER 指令设置运行用户。
Linux 用户信息记录在 /etc/passwd 文件中。要检查镜像中是否有内置用户,可以启动容器并查看该文件的最后一行。例如:
docker run --it --rm --entrypoint /bin/sh <docker image> cat /etc/passwd日志
Azure Function App 默认使用 Application Insights 进行日志记录。因此需要禁用它,并将日志打印到控制台,或者在应用代码中将日志写入第三方日志服务器。
在 host.json 中禁用 ApplicationInsights(将 isEnabled 设为 false):
{ "version": "2.0", "logging": { "applicationInsights": { "samplingSettings": { "isEnabled": false, "excludedTypes": "Request" } } }, "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" }}HTTP API
使用非特权端口
Azure Function 应用默认监听 80 端口,这需要 root 权限。应将监听端口改为非特权端口(如 5000),可在 Dockerfile 设置环境变量 ASPNETCORE_URLS:
ENV ASPNETCORE_URLS="http://+:5000"虽然环境变量名看似用于 ASP .NET 应用,但对于 NodeJS 应用同样适用。可能是因为运行时本身为 ASP .NET 应用。
认证
在 AKS 上运行 Function 时,无法复用 Azure 提供的认证机制,需自行实现认证。
简单场景下可以将静态 API Key 注入环境变量,通过函数校验请求头中的 API Key。例如使用如下的认证函数:
import { HttpRequest } from '@azure/functions'const FUNCTION_KEY = process.env.FUNCTION_KEY;
export function validateFunctionKey(req: HttpRequest): boolean { const providedKey = req.headers.get("api-key"); if (!FUNCTION_KEY) return false; return FUNCTION_KEY === providedKey;}注意事项:
- 不要尝试从请求头
x-functions-key获取 API Key,否则运行时会在函数处理前直接返回 500 错误。
定时任务
使用 Kubernetes 中的 CronJob 运行定时任务,并在 CronJob 的定义中设置调度时间。