4. Virtual Kubelet 与 Serverless 容器:架构、云厂商对接与混合节点池
在 Kubernetes 集群中引入 Serverless 容器,核心挑战在于如何让标准 Kubernetes 控制平面感知并调度到非节点形态的计算资源。Virtual Kubelet(VK)正是解决这一问题的关键组件——它通过模拟 kubelet 行为,将云厂商的 Serverless 容器实例(如 AWS Fargate、Azure Container Instances)无缝接入集群,实现混合节点池架构。
4.1 Virtual Kubelet 架构原理
Virtual Kubelet 是一个轻量级 Kubernetes kubelet 实现,它不运行在真实节点上,而是作为 Pod 或 Deployment 部署在集群中。其核心职责是:
- 节点注册:向 API Server 注册一个虚拟节点(Virtual Node),该节点拥有自定义的容量、标签和污点。
- Pod 生命周期管理:监听分配到该虚拟节点的 Pod,将 Pod 创建/更新/删除请求转换为对应云厂商 API 调用。
- 状态上报:定期从云厂商获取容器实例状态,同步回 Pod 状态和节点条件。
关键设计点: Virtual Kubelet 不运行容器运行时(如 containerd),不执行 CNI 网络插件,也不管理本地存储。它完全依赖云厂商的 Serverless 容器服务来执行这些底层操作。
4.2 对接 AWS Fargate
AWS Fargate 是 AWS 提供的 Serverless 容器计算引擎,与 EKS 集成时通过 EKS Fargate Profile 定义哪些命名空间或标签的 Pod 运行在 Fargate 上。Virtual Kubelet 的 AWS Fargate Provider 自动完成以下映射:
| Kubernetes 概念 | AWS Fargate 映射 | 说明 |
|---|---|---|
| Pod | Fargate Task | 每个 Pod 对应一个 Fargate Task,共享 ENI |
| Container | Task Definition 中的 Container | 支持多容器 Pod,但 Sidecar 需在同一个 Task 内 |
| Volume | EFS / EmptyDir | 支持 EFS 持久卷,EmptyDir 使用临时存储 |
| Service | ALB / NLB 集成 | 通过 AWS Load Balancer Controller 自动配置 |
| Network | VPC + Security Group | Pod 直接获得 VPC 内 IP,支持网络策略 |
最佳实践: 在 EKS 集群中创建
fargate 命名空间,通过 Fargate Profile 将整个命名空间的 Pod 调度到 Fargate。同时保留普通节点池运行 DaemonSet 和有状态服务,形成混合架构。
4.3 对接 Azure Container Instances
Azure 通过 Virtual Kubelet ACI Provider 将 ACI 作为虚拟节点接入 AKS。与 AWS Fargate 不同,ACI 支持更灵活的容器组(Container Group)配置:
- 容器组:一个 Pod 对应一个 ACI Container Group,组内容器共享网络和存储。
- GPU 实例:ACI 提供 GPU 优化实例,适合 AI/ML 推理场景。
- 虚拟网络集成:ACI 容器组可以部署到 Azure VNet 中,获得私有 IP。
- Windows 容器:ACI 原生支持 Windows Server 容器,弥补 AKS Windows 节点池的弹性短板。
4.4 混合节点池策略
混合节点池的核心价值在于:普通节点池承载稳态工作负载,Serverless 虚拟节点池承载弹性突发工作负载。实现这一目标需要以下策略:
4.4.1 调度策略配置
| 策略 | Kubernetes 机制 | 配置示例 |
|---|---|---|
| 强制调度到虚拟节点 | 节点选择器 + 容忍度 | nodeSelector: type: virtual-kubelet + tolerations |
| 优先使用虚拟节点 | 节点亲和性 + Pod 优先级 | preferredDuringScheduling 权重设置 |
| 禁止调度到虚拟节点 | 节点反亲和性 | requiredDuringSchedulingIgnoredDuringExecution |
| 按命名空间隔离 | Fargate Profile / ACI 配置 | 特定命名空间自动路由到虚拟节点 |
4.4.2 成本优化策略
- 突发优先:Deployment 设置
replicas基线运行在普通节点,HPA 触发扩容时新增副本调度到虚拟节点。 - Spot 实例混合:普通节点池使用 Spot 实例降低成本,虚拟节点处理 Spot 中断后的补充容量。
- 批处理作业:CronJob 或 BatchJob 直接调度到虚拟节点,避免预留节点资源。
- GPU 工作负载:AI 推理任务调度到 ACI GPU 实例,训练任务使用普通 GPU 节点池。
注意事项: 虚拟节点不支持 DaemonSet、HostNetwork、HostPort 模式。在混合架构中,需将监控、日志采集等 DaemonSet 固定在普通节点池,通过 Prometheus 联邦或日志代理转发虚拟节点上的 Pod 数据。
4.5 实践:部署 Virtual Kubelet 并创建混合节点池
以下步骤演示如何在 AKS 集群中部署 Virtual Kubelet ACI Provider:
# 1. 安装 Virtual Kubelet Helm Chart
helm repo add virtual-kubelet https://virtual-kubelet.github.io/charts
helm install vk-aci virtual-kubelet/virtual-kubelet \
--namespace virtual-kubelet \
--create-namespace \
--set provider=azure \
--set providers.azure.clientId=<SP_CLIENT_ID> \
--set providers.azure.clientSecret=<SP_SECRET> \
--set providers.azure.tenantId=<TENANT_ID> \
--set providers.azure.subscriptionId=<SUB_ID> \
--set providers.azure.resourceGroup=<RG_NAME> \
--set providers.azure.location=eastus
# 2. 验证虚拟节点已注册
kubectl get nodes -o wide
# 输出示例:virtual-kubelet-aci-0 Ready agent 30d v1.27.3-virtual-kubelet
# 3. 部署测试 Pod 到虚拟节点
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: serverless-nginx
spec:
nodeSelector:
type: virtual-kubelet
tolerations:
- key: virtual-kubelet.io/provider
operator: Exists
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
cpu: "0.5"
memory: "1Gi"
EOF
# 4. 查看 Pod 运行状态
kubectl get pod serverless-nginx -o wide
# 预期:Pod 运行在虚拟节点上,无对应 Node 的 kubelet 进程
4.6 性能与限制对比
| 维度 | 普通节点池 | Virtual Kubelet + Serverless |
|---|---|---|
| Pod 启动时间 | 秒级(镜像已缓存) | 10-30 秒(冷启动) |
| 最大 Pod 数 | 取决于节点规格 | 无硬限制(按需创建) |
| 持久存储 | CSI 驱动(EBS/磁盘) | 有限支持(EFS/EmptyDir) |
| 网络延迟 | 低(同 VPC) | 中(需经过 Provider 网关) |
| GPU 支持 | 完整 | 有限(ACI 部分支持) |
| 计费粒度 | 按节点小时 | 按 Pod 秒级 |
架构决策要点: 当工作负载对启动延迟不敏感、无持久化需求、且需要秒级弹性时,优先选择 Virtual Kubelet + Serverless 容器。对于延迟敏感、有状态、需要 GPU 训练的场景,保留普通节点池。混合节点池不是替代关系,而是互补关系。