摘要:随着云原生技术的快速发展,越来越多的企业希望在现有VMware vSphere虚拟化基础设施上平滑引入Kubernetes,实现传统应用与云原生应用的统一调度与管理。本文基于Kubernetes v1.28+ 与 vSphere 7.0 U3c/8.0+,采用外部云控制器(External Cloud Provider)架构,从零开始详细讲解如何构建高可用、安全、可运维、具备拓扑感知能力的生产级Kubernetes集群。涵盖架构设计、网络规划、存储集成、认证授权、监控告警等关键环节,并提供完整、可复用的部署脚本、配置模板与验证清单。

一、背景与价值

1.1 为什么选择 vSphere + Kubernetes?

  • 保护既有投资:利用成熟的vSphere平台(HA、DRS、vMotion、备份)

  • 混合工作负载支持:VM运行传统应用,Pod运行云原生服务

  • 统一基础设施:通过K8s API调度容器,底层由vSphere保障SLA

  • 合规与安全:满足金融、政务等行业对数据本地化与审计的要求

1.2 技术栈选型(截至2025年12月)

组件

推荐版本

最低兼容版本

说明

VMware vSphere

8.0 U2 / 7.0 U3c

7.0 U3c

必须支持 CSI 3.0+

Kubernetes

v1.28.0

v1.26+

CPI/CSI 需严格对齐

vSphere CPI

v1.28.0

External Cloud Provider

vSphere CSI

v3.0.0

支持拓扑感知、快照、扩容

CNI

Calico v3.25+ / Antrea v1.13+

VXLAN 或 BGP 模式

节点 OS

Ubuntu 22.04 LTS / RHEL 9.2+

内核 ≥ 5.15

容器运行时

containerd v1.6+

SystemdCgroup = true

部署工具

kubeadm / Cluster API (CAPI)

本文以 kubeadm 为主

💡 重要提示:自 Kubernetes v1.20 起,in-tree vSphere provider 已废弃,必须使用 External CPI + CSI 架构。


二、架构设计

2.1 整体拓扑

+-----------------------------------------------------+
|                  vCenter Server                     |
|  - Tags: k8s-zone=zone-a, zone-b                    |
|  - Folders: /Datacenter/vm/K8s-Cluster              |
+-----------------------------------------------------+
         |                |                 |
+--------v----+   +-------v------+   +------v--------+
|  ESXi Host  |   |  ESXi Host   |   |  ESXi Host    |
| (Control)   |   | (Worker)     |   | (Worker)      |
| - VM: kube1 |   | - VM: node1  |   | - VM: node2   |
| - VM: kube2 |   | - VM: node3  |   | - VM: node4   |
| - VM: kube3 |   +--------------+   +---------------+
+-------------+
        ↑
   VIP: 10.10.20.100 (kube-vip 或 NSX-T LB)
  • 控制平面:3节点 HA(etcd + kube-apiserver)

  • 工作节点:按需扩展,打标签 node-role.kubernetes.io/worker=

  • 网络:独立 VLAN 用于 Pod/Service(建议)

  • 存储:共享 vSAN/NFS Datastore,供 CSI 动态供给 PV

  • 拓扑:通过 vSphere Tag 实现 Zone 感知(如机架/站点)

2.2 关键组件交互

  • CPI (Cloud Provider Interface):将 K8s Node 映射为 vSphere VM,自动注入 providerIDzone/region 标签。

  • CSI (Container Storage Interface):动态创建 VMDK、挂载、快照、扩容。

  • vCenter 权限模型:最小权限原则,专用服务账号。


三、前置准备

3.1 环境要求

  • vSphere 7.0 U3c 或 8.0+

  • vCenter Server 可通过 HTTPS 访问(建议启用证书)

  • 至少 3 台 ESXi 主机(跨故障域更佳)

  • 共享存储(vSAN / NFS / VMFS)

  • DNS 解析(如 kube1.lab.local → 10.10.20.11

  • NTP 同步(所有 VM 时间误差 < 1s)

3.2 创建 vCenter 专用账号与权限

  1. 在 vCenter 中创建角色 K8s-Operator,包含以下权限:

    • Datastore: Allocate space, Browse datastore

    • Network: Assign network

    • Resource: Assign VM to resource pool

    • vApp: Import, Export

    • Virtual machine:

      • Interaction (Power On/Off)

      • Configuration (Add/remove device, Disk lease)

      • Provisioning (Clone, Customize)

    • Host: Local operations

    • Folder: Create/Delete folder

    • vSphere Tagging: Read-only(用于拓扑)

  2. 创建用户:k8s-svc@vsphere.local

  3. 将角色分配至:数据中心、集群、数据存储、端口组、VM 文件夹

🔐 安全建议:生产环境应使用 vCenter SSO 集成 LDAP,避免本地账号。


四、部署 Kubernetes 集群(基于 kubeadm)

4.1 准备 VM 模板(Ubuntu 22.04 示例)

# 基础配置
sudo hostnamectl set-hostname k8s-template
sudo apt update && sudo apt upgrade -y

# 安装依赖
sudo apt install -y curl wget vim net-tools nfs-common open-iscsi

# 加载内核模块
echo 'br_netfilter' | sudo tee /etc/modules-load.d/k8s.conf
sudo modprobe br_netfilter

# 配置 sysctl
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system

# 安装 containerd
sudo apt install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd

# 安装 kubeadm/kubelet/kubectl v1.28
curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet=1.28.0-00 kubeadm=1.28.0-00 kubectl=1.28.0-00
sudo apt-mark hold kubelet kubeadm kubectl

# 预检脚本(可选)
cat <<'EOF' > /tmp/pre-check.sh
#!/bin/bash
sysctl net.bridge.bridge-nf-call-iptables | grep -q 1 || echo "❌ bridge-nf not enabled"
lsmod | grep -q br_netfilter || echo "❌ br_netfilter not loaded"
systemctl is-active containerd >/dev/null || echo "❌ containerd not running"
EOF
chmod +x /tmp/pre-check.sh

# 关机,转为模板
sudo shutdown -h now

📌 RHEL 9 用户注意:需额外放行防火墙端口或关闭 firewalld:

sudo systemctl stop firewalld && sudo systemctl disable firewalld

4.2 部署控制平面节点(3台)

从模板克隆 3 台 VM(kube1, kube2, kube3),配置静态 IP 和主机名。

创建 kubeadm 配置文件(禁用 in-tree provider)

# kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "10.10.20.100:6443"  # VIP 地址
networking:
  podSubnet: "192.168.0.0/16"
  serviceSubnet: "10.96.0.0/12"
controllerManager:
  extraArgs:
    cloud-provider: external  # 关键:启用外部云控制器
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  kubeletExtraArgs:
    cloud-provider: external  # 所有节点均需此参数

kube1 执行:

sudo kubeadm init --config=kubeadm-config.yaml --upload-certs

配置 kubectl:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

4.3 安装 CNI(Calico VXLAN 模式)

kubectl apply -f https://docs.projectcalico.org/manifests/calico-vxlan.yaml

若跨子网通信,VXLAN 是更简单选择;同子网可考虑 BGP。

4.4 加入其他控制平面节点

kube2kube3 执行(命令由 kubeadm init 输出提供):

sudo kubeadm join 10.10.20.100:6443 \
  --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash> \
  --control-plane \
  --certificate-key <key> \
  --config kubeadm-config.yaml  # 需提前复制

4.5 部署工作节点

克隆 Worker 模板,执行普通 join 命令(不含 --control-plane)。


五、集成 vSphere Cloud Provider(CPI)

5.1 创建 CPI 配置(Secret 方式)

# cpi-config.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vsphere-config-secret
  namespace: kube-system
stringData:
  vsphere.conf: |
    [Global]
    insecure-flag = "true"          # 生产环境应设为 false 并配置 CA
    cluster-id = "prod-k8s-cluster" # 必须全局唯一

    [VirtualCenter "vcenter.lab.local"]
    user = "k8s-svc@vsphere.local"
    password = "SecurePass!2025"
    port = "443"
    datacenters = "Datacenter"
kubectl apply -f cpi-config.yaml

5.2 部署 vSphere CPI

kubectl apply -f https://github.com/kubernetes/cloud-provider-vsphere/releases/download/v1.28.0/cloud-provider-vsphere.yaml

5.3 验证 CPI

# 检查节点是否注册 providerID
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.providerID}{"\n"}{end}'

# 应输出类似:kube1	vsphere://4234abcd-...

六、集成 vSphere CSI(存储 + 拓扑感知)

6.1 部署 CSI 驱动

kubectl apply -f https://github.com/kubernetes-sigs/vsphere-csi-driver/releases/download/v3.0.0/vsphere-csi-driver.yaml

6.2 (可选)启用拓扑感知

在 vCenter 为 ESXi 主机打标签:

  • Key: k8s-zone,Value: zone-a(主机1/2)

  • Key: k8s-zone,Value: zone-b(主机3/4)

CPI 会自动将标签同步为 Node Label:

kubectl get nodes --show-labels | grep topology.csi.vmware.com/k8s-zone

6.3 创建拓扑感知 StorageClass

# sc-vsan-topo.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vsan-sc-topo
provisioner: csi.vsphere.vmware.com
volumeBindingMode: WaitForFirstConsumer  # 避免跨 zone 调度
allowVolumeExpansion: true
allowedTopologies:
- matchLabelExpressions:
  - key: topology.csi.vmware.com/k8s-zone
    values: ["zone-a", "zone-b"]
parameters:
  storagepolicyname: "vSAN Default Storage Policy"
  fstype: ext4

kubectl apply -f sc-vsan-topo.yaml

6.4 测试 PVC

# test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 10Gi
  storageClassName: vsan-sc-topo
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["sleep", "3600"]
    volumeMounts:
    - mountPath: "/data"
      name: vol
  volumes:
  - name: vol
    persistentVolumeClaim:
      claimName: test-pvc


kubectl apply -f test-pvc.yaml
# 观察 vCenter 是否自动创建 VMDK 并挂载到对应 VM

七、高可用与运维增强

7.1 控制平面 VIP:kube-vip 部署

# 生成 DaemonSet(替换 YOUR_VIP)
VIP=10.10.20.100
INTERFACE=eth0

kubectl apply -f https://kube-vip.io/manifests/rbac.yaml

curl -sL https://kube-vip.io/kube-vip-daemonset.yaml | \
  sed "s/192.168.0.1/$VIP/g" | \
  sed "s/eth0/$INTERFACE/g" | \
  kubectl apply -f -

✅ 验证:ping $VIP,停一台 master 后 VIP 应漂移。

7.2 监控与日志

  • Prometheus + Grafana:Helm 部署 kube-prometheus-stack

  • vSphere 指标:部署 vsphere-graphite 或 Tanzu Observability

  • 日志:Fluent Bit + Loki 或对接 vRealize Log Insight

7.3 备份与恢复

  • Velero:备份 K8s 资源 + Restic 备份 PV 数据

  • vSphere Replication:VM 级容灾(适用于整个集群灾难恢复)


八、安全加固建议

  1. 网络策略:默认拒绝,按需放行(kubectl apply -f https://projectcalico.docs.tigera.io/manifests/policy-demo.yaml

  2. PodSecurity Admission:启用 restricted 策略

# psa.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
  1. Secrets 加密:启用 EncryptionConfiguration(参考官方文档)

  2. 凭据管理:使用 secrets-store-csi-driver + Vault/AKS Key Vault 引用 vCenter 密码

  3. 镜像安全:Harbor + Trivy 扫描,OPA/Gatekeeper 策略校验


九、部署后验证清单

检查项

验证命令/方法

节点注册正确

kubectl get nodes -o wide,检查 PROVIDER ID

Pod 网络互通

kubectl run test --image=busybox --rm -it --restart=Never -- ping <other-pod-ip>

PV 动态供给

创建 PVC,检查 vCenter 是否生成 VMDK

控制平面 HA

停一台 master,kubectl get nodes 应正常

CPI 日志无 error

kubectl logs -n kube-system -l component=cloud-controller-manager

CSI 拓扑标签

kubectl get nodes --show-labels | grep k8s-zone

VIP 高可用

ping 10.10.20.100,逐台关闭 master 测试漂移


十、常见问题排查

问题

排查命令

Node NotReady

kubectl describe node <name>journalctl -u kubelet -n 100

PV 无法挂载

kubectl logs -n vmware-system-csi vsphere-csi-controller-xxx -c vsphere-csi-controller

CPI 未注册 ProviderID

检查 Secret 内容、vCenter 连通性、时间同步

Calico VXLAN 不通

tcpdump -i any -nn port 4789,检查防火墙

StorageClass 无绑定

确认 volumeBindingMode: WaitForFirstConsumer 与 Pod 调度匹配


十一、总结与演进方向

本文提供了一套生产就绪、安全合规、具备拓扑感知能力的 Kubernetes + vSphere 混合部署方案,已在多个行业客户落地验证。

未来演进建议:

  • 声明式集群管理:迁移到 Cluster API Provider for vSphere (CAPV)

  • 企业级发行版:采用 VMware Tanzu Kubernetes Grid (TKG) 简化生命周期管理

  • 网络深度集成:对接 NSX-T 实现微隔离、服务网格、L7 策略

  • GitOps 运维:使用 FluxCD/ArgoCD 管理集群配置

附录

  • vSphere CPI 官方文档

  • vSphere CSI GitHub

  • 完整部署脚本仓库(示例):https://github.com/your-org/k8s-vsphere-deploy

  • Kubernetes 安全基线:NSA/CISA Kubernetes Hardening Guide


作者:IT Online
更新日期:2025年12月12日
版权声明:本文可自由转载,需保留出处及作者信息。