跨集群资源联邦:把远端集群的剩余算力变成一个可调度的虚拟节点
Liqo(Liquid Computing)是一个开源的跨集群资源联邦项目,由都灵理工大学(Politecnico di Torino) 发起,采用 Apache-2.0 许可,当前最新版本为 v1.2.0(2026-07-03),项目仍在活跃开发(仓库每日都有提交)。
一点澄清:Liqo 常被误标为「CNCF Sandbox 项目」。它的实现基于 CNCF 的 Virtual Kubelet 项目,社区也活跃在 CNCF 生态中,但官方仓库与站点并未标注 CNCF 成熟度级别,引用时不要想当然地写成 CNCF 项目。
Liqo 要解决的问题与 Karmada 不同。Karmada 问的是「应用的副本怎么分发到多个集群」,Liqo 问的是**「怎么把别的集群的闲置算力借过来用」**:
Karmada 应用分发:副本拆分、差异化配置、故障迁移,应用需要感知多集群
Liqo 资源联邦:远端集群变成一个虚拟节点,应用完全无感
在 Liqo 里,消费者集群(consumer)会把提供者集群(provider)的容量聚合成一个 VirtualNode,原生的 Kubernetes 调度器可以直接往上调度 Pod;被调度到虚拟节点上的 Pod 会真正运行在远端集群的节点上。
Peering 两个集群自动协商建立对等关系,无需手工配 VPN 与证书
Offloading 把命名空间「卸载」到远端,Pod 落到虚拟节点上
Network Fabric 跨集群的 Pod-to-Pod / Pod-to-Service 连通,与底层 CNI 无关
Storage Fabric 远端执行有状态工作负载,倾向「数据不动、计算动」
ForeignCluster discovery.liqo.io/v1alpha1 对端集群的抽象,记录 peering 状态
NamespaceOffloading offloading.liqo.io/v1beta1 命名空间的卸载策略
VirtualNode 以节点形式暴露远端容量(标签 liqo.io/type=virtual-node)
ResourceSlice authentication.liqo.io/v1beta1 资源申请与授权
Tenant authentication.liqo.io/v1beta1 在 provider 侧代表一个 consumer
GatewayServer/Client networking.liqo.io/v1beta1 网关配置模板与实例
TunnelEndpoint net.liqo.io 集群间隧道的落点信息
ForeignCluster 是理解 Liqo 的入口 —— 它代表「另一个集群」,其 status 里会汇总 peering、网络、认证各模块的状态:
kubectl get foreignclusters
kubectl get foreignclusters -o wide
# 虚拟节点
kubectl get nodes -l liqo.io/type=virtual-node
kubectl describe node liqo-<cluster-id>
# 安装 liqoctl(macOS / Linux 二进制见 release 页面)
liqoctl version
# 在集群上安装 Liqo(按发行版选择子命令)
liqoctl install k3s --kubeconfig cluster-a.config
liqoctl install kind --kubeconfig cluster-a.config
liqoctl install eks --eks-cluster-name my-cluster --region eu-west-1
liqoctl install aks / gke / openshift
# 查看状态
liqoctl status
kubectl get pods -n liqo
两种方式,取决于能否同时访问两个集群的 kubeconfig:
# in-band:一条命令,同时访问两个集群(最简单)
liqoctl peer in-band --context=consumer --remote-context=provider
# in-band 双向(两端互相可用)
liqoctl peer in-band --context=consumer --remote-context=provider --bidirectional
# out-of-band:两端网络不通、靠人工传递凭证时使用
# 在 provider 侧生成命令
liqoctl generate peer-command
# 在 consumer 侧执行生成的命令
liqoctl peer out-of-band <cluster-name> \
--auth-url <url> --cluster-id <id> --auth-token <token>
# 断开
liqoctl unpeer in-band --context=consumer --remote-context=provider
liqoctl unpeer out-of-band
peering 成功后,consumer 侧会多出一个虚拟节点,以及一个 ResourceSlice 记录从 provider 申请到的资源量。
默认情况下虚拟节点不参与调度 —— 只有明确卸载的命名空间,其 Pod 才会落到远端:
# 命令行方式
liqoctl offload namespace demo
liqoctl unoffload namespace demo
声明式方式:
apiVersion: offloading.liqo.io/v1beta1
kind: NamespaceOffloading
metadata:
name: offloading
namespace: demo
spec:
namespaceMappingStrategy: DefaultName # 或 EnforceSameName
podOffloadingStrategy: LocalAndRemote # 或 Local / Remote
clusterSelector:
nodeSelectorTerms: []
字段含义:
podOffloadingStrategy: LocalAndRemote 本地与远端都可调度(默认)
podOffloadingStrategy: Local 只调度到本地节点
podOffloadingStrategy: Remote 只调度到远端虚拟节点
namespaceMappingStrategy: DefaultName provider 侧的命名空间名会加后缀,避免冲突
namespaceMappingStrategy: EnforceSameName 要求两侧同名,适合已经约定好命名的场景
NamespaceOffloading 的 status 里可以看到每个远端集群的 offloadingPhase(Ready / NoClusterSelected / SomeFailed / AllFailed)。
liqo-gateway 每个集群一个,负责跨集群隧道
liqo-ipam IP 地址管理与映射
WireGuard / Geneve 隧道封装方式(v1.2 起 liqo-gateway 内嵌 wireguard-go)
internal fabric 更轻量的集群内互联模式
网络模块会为每个对端生成网关与隧道配置,并在必要时做地址映射,使得即使两侧的 CNI 不同、Pod CIDR 规划不同,Pod 之间也能互通。
provider 共享多少资源是可以定制的。默认行为是「共享当前可用资源的一个可配置比例」,需要更精细的控制时用资源插件:
fixed-resources 按固定量共享,例如 --resource=cpu=2000m --resource=memory=2G --resource=pods=10
node-labels-resources 按节点标签决定共享哪些节点的资源
插件通过安装参数接入:
liqoctl install k3s \
--set controllerManager.config.resourcePluginAddress=<plugin-address>
consumer 侧的资源申请以 ResourceSlice 表达:liqoctl peer 会创建一个默认的 ResourceSlice,后续可以追加更多以申请额外资源。相关开关:
--create-virtual-node false 只建立 peering 与认证,不创建虚拟节点
--create-resource-slice false 不自动创建 ResourceSlice
--resource-slice-class <class> 指定 ResourceSlice 类别,默认 default
v1.2 起还引入了可定制的 ResourceSlice 类别(Custom ResourceSlice classes),用于把资源按类别区分共享。
两者常被放在一起比较,实际的差异在「谁感知多集群」:
维度 Liqo Karmada
解决的问题 借算力(资源联邦) 分应用(应用分发)
应用是否感知 不感知,Pod 落到虚拟节点即可 需要 PropagationPolicy 描述分发策略
副本控制 交给原生调度器 跨集群副本拆分与权重
故障迁移 不做,虚拟节点 NotReady 即止 支持集群失联后的自动迁移
资源归属 远端集群的节点承载 Pod 副本落在成员集群,各自调度
一个常见的组合是:Karmada 负责「应用该跑在哪些集群」,Liqo 负责「某个集群算力不够时向外借」。但这两层同时引入会让排障路径变长,小规模场景通常只选其中一层。
fixed-resources、node-labels-resources)来定制共享多少。此外虚拟节点带有 taint,需要 Liqo 的 webhook 自动加 toleration 才能被调度。NamespaceOffloading 必须早于 Pod 调度创建。官方明确警告:如果 Pod 已经在命名空间里被创建后再去开启卸载,这些 Pod 可能永久停在 Pending。正确的顺序是先建 NamespaceOffloading,再部署工作负载。offloading.liqo.io 从 v1alpha1 到 v1beta1),Tenant / ResourceSlice 这层模型也在快速调整。把 Liqo 的 CRD 写进生产清单前,先核对目标版本的 API 与字段。kubectl — Kubernetes集群管理工具karmada — 多集群应用分发,与 Liqo 互补而非竞争cluster-api — 集群生命周期管理,可与 Liqo 叠加vcluster — 虚拟集群,与本地的「虚拟节点」概念不同cilium — 常见的底层 CNI,Liqo 文档中也有对应的安装说明multi-tenancy — 单集群内的多租户取舍