饮墨

子安饮墨馀三斗,留与卿儿作赋来

用 vCluster 实现 Kubernetes 多租户隔离:3 步搭建轻量虚拟集群

痛点

团队规模增长后,多个开发组共用一套 K8s 集群,资源冲突频发:A 组的 CRD 升级把 B 组搞挂、测试环境互相踩 Namespace、RBAC 配置复杂且容易漏权。传统方案要么拉多套物理集群(成本翻倍),要么靠 Namespace 级隔离(隔离不彻底,CRD/Webhook 级别无法隔离)。

vCluster 是 Loft Labs 开源的轻量级虚拟集群方案——在一个 Host 集群的 Namespace 里跑一个完整的 K8s Control Plane(API Server + etcd/SQLite),租户看到的是独立集群,但 Pod 实际调度在宿主集群节点上。资源开销极低(每个 vCluster 仅需 ~128MB 内存),隔离度远超 Namespace。

方案概览

┌─── Host Cluster ──────────────────────────────────┐
│                                                    │
│  ┌── ns: team-a ─────────┐  ┌── ns: team-b ────┐ │
│  │  vCluster A            │  │  vCluster B       │ │
│  │  ┌─ API Server ──┐    │  │  ┌─ API Server ─┐ │ │
│  │  │  syncer        │    │  │  │  syncer       │ │ │
│  │  │  backing store │    │  │  │  backing store│ │ │
│  │  └────────────────┘    │  │  └───────────────┘ │ │
│  └────────────────────────┘  └────────────────────┘ │
│                                                    │
│  实际 Pod 调度在 Host 节点上                         │
└────────────────────────────────────────────────────┘

核心优势:

对比维度 Namespace 隔离 独立集群 vCluster
CRD 隔离
资源开销 极低 低(~128MB/集群)
运维复杂度
租户自主度
创建速度 秒级 分钟级 秒级

实操步骤

第 1 步:安装 vCluster CLI

# Linux amd64
curl -L -o vcluster "https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64"
chmod +x vcluster
sudo mv vcluster /usr/local/bin/

# 验证
vcluster --version

第 2 步:创建虚拟集群

# 在 host 集群中为 team-a 创建一个虚拟集群
# 默认使用 k3s 作为内部 control plane(轻量)
vcluster create team-a-dev \
  --namespace team-a \
  --connect=false

# 查看状态
vcluster list

如需自定义资源配额,创建 vcluster.yaml

# vcluster.yaml
controlPlane:
  backingStore:
    etcd:
      embedded:
        enabled: true
  resources:
    limits:
      memory: 256Mi
      cpu: 200m

sync:
  toHost:
    pods:
      enabled: true
    services:
      enabled: true
    persistentVolumeClaims:
      enabled: true
  fromHost:
    nodes:
      enabled: true
      selector:
        labels:
          team: team-a
vcluster create team-a-dev \
  --namespace team-a \
  -f vcluster.yaml \
  --connect=false

第 3 步:连接虚拟集群并分发 kubeconfig

# 生成独立 kubeconfig(给开发团队使用)
vcluster connect team-a-dev \
  --namespace team-a \
  --print > /tmp/team-a-kubeconfig.yaml

# 开发者拿到 kubeconfig 后操作虚拟集群
export KUBECONFIG=/tmp/team-a-kubeconfig.yaml
kubectl get ns          # 看到的是虚拟集群的 namespace
kubectl create ns staging
kubectl apply -f my-app.yaml  # 自由部署,不影响其他团队

开发者可以在虚拟集群里自由安装 CRD、配置 Webhook、创建 ClusterRole,完全不影响宿主集群和其他租户。

避坑指南

坑 1:Pod 网络互通问题

vCluster 的 Pod 实际运行在宿主集群,网络默认互通。如果需要租户间网络隔离,必须配合 NetworkPolicy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: isolate-team-a
  namespace: team-a
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]
  ingress:
  - from:
    - podSelector: {}
  egress:
  - to:
    - podSelector: {}
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53

坑 2:资源不设 Limit 导致宿主集群被打满

vCluster 租户默认可调度到宿主所有节点。务必在宿主 Namespace 上加 ResourceQuota:

kubectl -n team-a apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "50"
EOF

坑 3:存储卷回收遗漏

vCluster 删除时默认不清理 PVC。使用 --delete-namespace 参数清理,或设置 PV 回收策略为 Delete:

# 删除 vCluster 时一并清理 namespace
vcluster delete team-a-dev --namespace team-a --delete-namespace

总结

场景 推荐方案
2-3 人小团队 Namespace + RBAC 足够
5+ 团队共享集群 vCluster,隔离度高、成本低
强合规/金融级隔离 独立物理集群

vCluster 最佳适用场景:CI/CD 临时环境(跑完即删)、多团队开发测试(每组独立集群体验)、SaaS 多租户(客户级别隔离)。相比独立集群方案,一台 8C32G 节点可以轻松跑 20+ 个虚拟集群,成本仅为物理多集群的 1/10。

落地建议:先在测试环境验证 vCluster + NetworkPolicy 的隔离效果,确认网络和存储行为符合预期后再推广到生产环境。

您还没有登录,请登录后发表评论。