第4章 容器编排层:Kubernetes集群设计、节点规划、网络方案与存储方案

好,咱们进入容器编排层。说白了,这就是整个PaaS平台的心脏。Kubernetes选型、集群怎么搭、节点怎么分、网络怎么通、数据怎么存——这些搞不定,上层应用全是空中楼阁。

我这些年见过太多团队,K8s集群搭起来就跑个demo,一上生产就崩。为什么?因为前期规划没做好。今天我把这些坑一个一个给你讲透。

4.1 Kubernetes集群设计原则

先聊集群设计。很多人一上来就问:我用kubeadm还是二进制?用单Master还是多Master?

我的建议是:生产环境必须用高可用架构。单Master集群,你想想看,etcd挂了怎么办?API Server挂了怎么办?整个集群就瘫痪了。

核心设计原则:

  • 控制平面高可用:至少3个Master节点,etcd集群奇数节点
  • 工作节点弹性:Worker节点按业务需求动态扩缩
  • 组件冗余:关键组件(如CoreDNS、Ingress Controller)多副本部署
  • 故障域隔离:Master节点分散在不同物理机架或可用区

我记得有一次帮客户排查问题,他们的集群只有2个Master。结果一台机器宕机,etcd选举失败,整个集群不可用。嗯,这就是血的教训。

4.2 节点规划与资源分配

节点规划这事儿,很多人觉得简单——买几台服务器装上就行。其实不然。

我习惯把节点分成三类:

节点类型 推荐配置 用途
Master节点 4C8G以上,SSD磁盘 运行etcd、API Server、Scheduler、Controller Manager
Worker节点 8C16G起步,按业务调整 运行业务容器、DaemonSet
基础设施节点 4C8G 运行监控、日志、Ingress等组件

避坑指南:我曾经遇到过客户把所有组件都塞到Worker节点上,结果业务高峰期节点资源被监控组件吃光,Pod被驱逐。建议把监控、日志这类基础设施单独部署,或者用节点亲和性打散。

节点数量怎么定?我有个经验公式:

  • 小规模(< 50节点):3 Master + N Worker
  • 中规模(50-200节点):3-5 Master + N Worker
  • 大规模(> 200节点):5-7 Master + 分区域Worker

你想想看,etcd的写入性能跟节点数强相关。节点越多,选举越慢。所以Master节点不是越多越好。

4.3 网络方案:Calico vs Flannel

网络方案是K8s里最容易踩坑的地方。我见过有人用Flannel跑生产,结果跨节点通信延迟高得离谱。

先说说两者的区别:

特性 Flannel Calico
网络模型 Overlay(VXLAN/Host-GW) 纯三层路由(BGP)
性能 中等,有封装开销 高,接近物理网络
网络策略 不支持 原生支持,功能强大
复杂度 简单 中等,需BGP配置
适用场景 小规模、开发测试 生产环境、大规模、需网络隔离

我个人习惯:生产环境首选Calico。为什么?

  • 性能好:没有VXLAN封装,直接走BGP路由
  • 安全:原生支持NetworkPolicy,可以做微隔离
  • 灵活:支持IPIP、VXLAN、BGP多种模式

但Calico也有坑。我记得有一次,客户用了Calico的BGP模式,但底层交换机不支持BGP,结果路由无法同步。最后只能切回IPIP模式。

注意:如果你们公司网络团队不允许动交换机配置,那就老老实实用Flannel的VXLAN模式,或者Calico的IPIP模式。别硬上BGP,否则运维起来很痛苦。

Flannel什么时候用?我建议:

  • 开发测试环境,图省事
  • 小规模集群(< 20节点),对性能不敏感
  • 网络团队不配合,没法改底层网络

4.4 存储方案:Rook/Ceph实战

存储是K8s里最头疼的问题。无状态应用好办,有状态应用怎么办?数据库、消息队列、缓存——这些都需要持久化存储。

我推荐Rook + Ceph的组合。Rook是K8s的Operator,负责管理Ceph集群。说白了,就是把Ceph的运维工作自动化了。

先看一个Rook部署Ceph集群的示例:

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
    allowMultiplePerNode: false
  storage:
    useAllNodes: false
    useAllDevices: false
    config:
      databaseSizeMB: "1024"
      journalSizeMB: "1024"
    nodes:
    - name: node1
      devices:
      - name: sdb
      - name: sdc
    - name: node2
      devices:
      - name: sdb
      - name: sdc
    - name: node3
      devices:
      - name: sdb
      - name: sdc

这个配置干了什么?

  • 部署3个MON(监控节点),保证高可用
  • 每个节点用两块盘(sdb、sdc)作为OSD
  • 数据目录放在宿主机的/var/lib/rook

个人经验:我曾经在生产环境部署Rook,一开始用了所有节点所有磁盘(useAllDevices: true),结果系统盘被Ceph占用了,导致节点无法启动。所以一定要显式指定磁盘,别偷懒。

部署完成后,怎么给Pod用?通过StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph
  pool: replicapool
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
reclaimPolicy: Delete
allowVolumeExpansion: true

然后PVC直接引用这个StorageClass就行:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

你想想看,有了这套方案,MySQL、Redis、Kafka这些有状态应用,都能在K8s上跑得稳稳的。

4.5 避坑指南与最佳实践

最后,我总结几个实战中容易踩的坑:

网络方案避坑:

  • Calico的BGP模式需要交换机支持,否则用IPIP
  • Flannel的Host-GW模式性能好,但只支持同二层网络
  • 跨机房场景,建议用Calico的VXLAN模式

存储方案避坑:

  • Ceph OSD节点至少3个,否则数据无法自愈
  • 磁盘建议用SSD,HDD性能太差
  • 网络带宽要够,Ceph复制数据很吃带宽
  • 别把Ceph和业务混部,IO会互相干扰

我记得有一次,客户把Ceph和业务Pod混部在同一台机器上。业务高峰期,Ceph的OSD进程把CPU吃满,业务Pod直接OOMKilled。嗯,这就是典型的资源隔离没做好。

好了,这一章的内容就到这里。Kubernetes集群设计、节点规划、网络方案、存储方案——这些是PaaS平台的基石。搞定了这些,上层应用才能跑得稳、跑得快。

下一章,咱们聊聊服务网格和API网关。到时候见。