本文探讨传统VMware虚拟化环境如何拥抱云原生,实现容器化改造与混合部署的融合创新方案。
前言
很多企业的现状是:
- 核心业务跑在VMware vSphere上,稳定运行多年
- 新项目想用Kubernetes,享受云原生的敏捷
- 完全推倒重来?成本太高,风险太大
云原生和VMware不是对立的,而是可以融合的。
今天来聊聊如何在VMware环境中落地云原生,实现平滑过渡。
一、架构选型
1.1 三种融合方案
| 方案 | 说明 | 适用场景 |
|---|---|---|
| VM上跑K8s | 在虚拟机里部署K8s节点 | 快速试水,资源隔离 |
| vSphere with Tanzu | VMware原生K8s支持 | 企业级,深度集成 |
| 混合架构 | VM + 物理机/云K8s混合 | 多云多集群 |
1.2 方案对比
方案1:VM上跑K8s(最常见)
┌─────────────────────────────────────────┐
│ vSphere集群 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ VM-K8s │ │ VM-K8s │ │ VM-K8s │ │
│ │ Master │ │ Worker1 │ │ Worker2 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ K8s Cluster │
└─────────────────────────────────────────┘
方案2:vSphere with Tanzu
┌─────────────────────────────────────────┐
│ vSphere 7.0+ │
│ ┌─────────────────────────────────┐ │
│ │ Supervisor Cluster │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ TKG │ │ vSphere │ │ │
│ │ │ Cluster │ │ Pods │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
二、VM上部署K8s实战
2.1 虚拟机规划
Master节点:
- CPU: 4 vCPU
- 内存: 8GB
- 磁盘: 100GB
- 网络: 固定IP
- 数量: 3台(高可用)
Worker节点:
- CPU: 8 vCPU
- 内存: 16GB
- 磁盘: 200GB
- 网络: 固定IP
- 数量: 按需扩展
2.2 VM模板制作
# 基础系统配置
# 1. 安装CentOS/Ubuntu最小化
# 2. 关闭swap
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab# 3. 关闭SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config# 4. 配置内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system# 5. 安装containerd
apt install containerd -y
containerd config default > /etc/containerd/config.toml
systemctl enable containerd# 6. 安装kubeadm/kubelet/kubectl
# ... 根据官方文档安装
2.3 使用kubeadm部署
# Master初始化
kubeadm init \--apiserver-advertise-address=192.168.1.100 \--pod-network-cidr=10.244.0.0/16 \--service-cidr=10.96.0.0/12# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config# 安装网络插件(Calico)
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml# Worker加入集群
kubeadm join 192.168.1.100:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx
2.4 vSphere CSI存储集成
让K8s使用vSphere的存储:
# vsphere-csi-driver配置
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: vsphere-sc
provisioner: csi.vsphere.vmware.com
parameters:datastoreurl: "ds:///vmfs/volumes/datastore1/"fstype: ext4
reclaimPolicy: Delete
volumeBindingMode: Immediate
这样Pod可以直接使用vSphere的存储,数据持久化。
三、vSphere with Tanzu
3.1 架构优势
vSphere 7.0+原生支持Kubernetes:
- Supervisor Cluster:管理层K8s
- TKG Cluster:业务K8s集群
- vSphere Pods:直接在ESXi上运行容器(无需VM)
3.2 部署要求
- vSphere 7.0 Update 1+
- vCenter Server
- NSX-T 或 vSphere分布式交换机
- vSAN/NFS/iSCSI存储
- 企业Plus许可证
3.3 启用Workload Management
1. vCenter → Workload Management → 启用
2. 选择网络模式(NSX-T或vDS)
3. 配置存储策略
4. 设置控制平面大小
5. 等待Supervisor Cluster就绪
四、多集群管理挑战
4.1 常见场景
当K8s集群分布在多个位置时:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 总部机房 │ │ 分支机房 │ │ 公有云 │
│ K8s集群A │ │ K8s集群B │ │ K8s集群C │
│ VMware环境 │ │ VMware环境 │ │ EKS/AKS │
└──────────────┘ └──────────────┘ └──────────────┘
挑战:
- 网络互通:各集群网络如何打通?
- 统一管理:如何集中管理多集群?
- 服务发现:跨集群服务如何调用?
4.2 网络互联方案
传统方案:
- 专线/MPLS:成本高
- Site-to-Site VPN:配置复杂
- SD-WAN:需要专业设备
轻量方案:
使用组网软件(如星空组网)快速打通多集群网络:
# 场景:打通3个K8s集群的网络# 在每个集群选一台节点安装组网客户端
# 总部节点:10.10.0.1
# 分支节点:10.10.0.2
# 云上节点:10.10.0.3# 所有节点登录同一账号后自动组网
# 各集群通过组网IP互通
效果:
# 从总部ping分支的K8s节点
ping 10.10.0.2
64 bytes from 10.10.0.2: icmp_seq=1 ttl=64 time=15.3 ms# kubectl管理远程集群
kubectl --kubeconfig=remote-cluster.conf get nodes
4.3 多集群管理工具
| 工具 | 特点 |
|---|---|
| Rancher | Web界面,易上手 |
| KubeSphere | 国产,功能全面 |
| Lens | 桌面客户端 |
| kubectl + kubeconfig | 原生方式 |
配合组网使用,可以在任何地点管理所有集群。
五、容器化改造实践
5.1 改造原则
1. 先易后难:先改无状态应用
2. 渐进式:不要一次性全改
3. 保留回滚:VM和容器并行一段时间
4. 数据分离:有状态服务谨慎处理
5.2 改造路径
阶段1:开发测试环境容器化↓
阶段2:无状态应用(Web/API)容器化↓
阶段3:中间件容器化(有状态,需要PV)↓
阶段4:核心系统评估(可能保留VM)
5.3 Dockerfile最佳实践
# 多阶段构建
FROM maven:3.8-jdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests# 运行镜像
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar# 非root用户
RUN useradd -r appuser
USER appuser# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost:8080/health || exit 1EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
5.4 K8s部署配置
apiVersion: apps/v1
kind: Deployment
metadata:name: my-app
spec:replicas: 3selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-appimage: registry.example.com/my-app:v1.0ports:- containerPort: 8080resources:requests:cpu: 500mmemory: 512Milimits:cpu: 1000mmemory: 1GireadinessProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 10periodSeconds: 5livenessProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 30periodSeconds: 10
六、混合架构运维
6.1 监控统一
# Prometheus联邦,聚合多集群监控
# prometheus-federation.yaml
scrape_configs:- job_name: 'federate-cluster-a'honor_labels: truemetrics_path: '/federate'params:'match[]':- '{job=~".+"}'static_configs:- targets:- '10.10.0.1:9090' # 集群A Prometheus- job_name: 'federate-cluster-b'honor_labels: truemetrics_path: '/federate'params:'match[]':- '{job=~".+"}'static_configs:- targets:- '10.10.0.2:9090' # 集群B Prometheus
6.2 日志聚合
# 使用Loki聚合多集群日志
# 各集群部署Promtail,推送到中心Loki# promtail-config.yaml
clients:- url: http://10.10.0.1:3100/loki/api/v1/pushexternal_labels:cluster: cluster-a
6.3 CI/CD跨集群部署
# GitLab CI示例
stages:- build- deploydeploy-to-all:stage: deployscript:# 部署到集群A- kubectl --kubeconfig=$KUBE_CONFIG_A apply -f k8s/# 部署到集群B- kubectl --kubeconfig=$KUBE_CONFIG_B apply -f k8s/
七、总结
VMware + 云原生融合要点:
- 架构选型:根据规模选择VM上K8s或Tanzu
- 渐进改造:先无状态,后有状态
- 存储集成:使用vSphere CSI
- 多集群互联:组网软件快速打通网络
- 统一运维:监控、日志、CI/CD全覆盖
我的建议:
- 小规模:VM上部署K8s足够
- 中大规模:考虑Tanzu或Rancher
- 多站点:先解决网络互通问题
不要为了云原生而云原生,根据实际需求选择合适方案。
参考资料
- VMware vSphere with Tanzu官方文档
- Kubernetes官方文档
- vSphere CSI Driver
💡 实践建议:先在测试环境搭建一套,跑通流程后再推广到生产环境。