SStorpath
实验预计 60 分钟

实验:Rook 在 K8s 里跑 Ceph

存储与计算同集群的另一条路线,Operator 帮你做了什么、藏了什么。

学完这节你能做到

  • 用 Rook Operator 部署一套 CephCluster
  • 用 kubectl rook-ceph 执行日常运维命令
  • 判断什么场景该选 Rook、什么场景该选 cephadm

另一条路线:让 K8s 来管 Ceph

Rook 是一个 Kubernetes Operator,它把"部署和运维 Ceph"这件事翻译成了 CRD。你写一份 CephCluster 的 YAML,Operator 负责把 MON、OSD、MGR 拉起来并持续维持这个状态。

什么时候选 Rook:存储与计算在同一个 K8s 集群,团队已经熟悉 K8s,希望存储也纳入声明式管理。

什么时候选 cephadm:独立存储集群服务多个计算集群,或者存储节点不想装 K8s。

iOperator 帮你做了什么,又藏了什么

帮你做的:自动发现磁盘、自动拉起守护进程、节点故障时自动重建、配置漂移时自动纠正。

藏起来的:所有操作都隔了一层 CRD。当 OSD 起不来时,你要同时会看 K8s 的事件、Operator 的日志、以及 Ceph 自己的状态——排障链路比 cephadm 长。这是选择 Rook 必须接受的代价。

第 1 步:给存储节点打标签

Rook 通过节点标签决定把 Ceph 部署到哪些机器上。

kubectl label node sn-10-0-20-1 node-role.kubernetes.io/storage=true
kubectl label node sn-10-0-20-2 node-role.kubernetes.io/storage=true
kubectl label node sn-10-0-20-3 node-role.kubernetes.io/storage=true

第 2 步:部署 Operator

kubectl apply -k operator/

# 等 operator 就绪
kubectl wait -n rook-ceph --for=condition=ready pod -l app=rook-ceph-operator

第 3 步:CephCluster —— 这份 YAML 是核心

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: quay.io/ceph/ceph:v20.2.1

  network:
    provider: host                 # 用宿主机网络,性能好于 CNI
    addressRanges:
      public:
        - 172.18.0.0/20            # 客户端访问网段
      cluster:
        - 192.168.152.0/24         # 副本复制网段

  placement:
    all:                           # OSD 等数据面组件只上存储节点
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
            - matchExpressions:
                - key: node-role.kubernetes.io/storage
                  operator: Exists
      tolerations:
        - operator: Exists
          effect: NoSchedule
    mon:                           # MON 放到管理节点上
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
            - matchExpressions:
                - key: node-role.kubernetes.io/control-plane
                  operator: Exists

  resources:
    osd:
      limits:
        memory: "16Gi"
      requests:
        cpu: "4"
        memory: "8Gi"

三个要点:

  1. network.provider: host —— 走宿主机网络而不是 CNI,减少一层封装开销。生产环境几乎都这么配
  2. publiccluster 分离 —— 与上一阶段讲的道理完全一致。只有一条网络时要把整个 cluster 段删掉,而不是填成同一个网段
  3. resources.osd —— 这里的 memory limit 对应 cephadm 里的 osd_memory_target 概念。给少了恢复时会被 OOMKilled
kubectl apply -k cluster/
kubectl get cephclusters -n rook-ceph -w
kubectl describe cephcluster rook-ceph -n rook-ceph
!placement 写错的后果

如果不加 nodeAffinity,Operator 会尝试在所有节点上部署 OSD,包括没有数据盘的计算节点。结果是一堆 osd-prepare Pod 反复失败重启,日志刷屏。

同样,MON 如果没有反亲和约束而被调度到同一台机器上,那台机器一挂 quorum 就没了——K8s 层的调度错误会直接变成存储层的可用性事故。

第 4 步:运维入口

Rook 环境下不能直接敲 ceph 命令,有两个入口:

# 方式一(推荐):kubectl-rook-ceph 插件
kubectl krew install rook-ceph
kubectl rook-ceph ceph -s
kubectl rook-ceph ceph osd tree
kubectl rook-ceph ceph health detail

# 方式二:部署 toolbox Pod
kubectl apply -k toolbox/
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
# 进去之后就是熟悉的 ceph 命令了
ceph -s

第 5 步:排查 OSD 起不来

这是 Rook 环境最高频的问题,排查要顺着三层往下走:

# 第 1 层:K8s —— Pod 在不在,事件说了什么
kubectl -n rook-ceph get pod -o wide | grep osd
kubectl -n rook-ceph describe pod <osd-prepare-pod>

# 第 2 层:Operator —— 它在尝试做什么
kubectl -n rook-ceph logs -l app=rook-ceph-operator --tail=100

# 第 3 层:osd-prepare 作业 —— 为什么这块盘没被接受
kubectl -n rook-ceph logs <osd-prepare-pod>

# 最后回到 Ceph 自己
kubectl rook-ceph ceph osd tree

osd-prepare 的日志里最常见的拒绝原因和 cephadm 一样:盘上有残留的分区表、LVM 或文件系统签名。

# 在宿主机上确认并清理(务必先确认盘号)
lsblk
wipefs -a /dev/nvme1n1
dd if=/dev/zero of=/dev/nvme1n1 bs=1M count=100
Rook 与 cephadm 的能力对照
cephadmRook
部署方式命令式声明式 CRD
排障链路短,直接看 systemd 和 ceph长,要穿过 K8s → Operator → Ceph
自愈能力弱,靠人强,Operator 持续调谐
适合独立存储集群存算一体
CSI需单独部署 ceph-csiOperator 自带

两者管的是同一个 Ceph,底层概念完全通用。学会一个,另一个只是操作界面的差别。

检查点单选

Rook 集群里 osd-prepare Pod 反复失败,日志显示磁盘被拒绝。最可能的原因是?

检查点单选

某 Rook 集群只有一条物理网络。CephCluster 里该怎么配 network 段?

检查点多选

在 Rook 环境里想看集群健康状态,正确的做法是?(多选)

这节课的落点

  • Rook 用 CRD 声明式管理 Ceph,代价是排障链路变长
  • 节点标签 + placement 决定组件落在哪,写错会直接变成可用性事故
  • network.provider: host 是生产标配;只有一条网就删掉 cluster
  • 运维入口是 kubectl rook-ceph 或 toolbox,不能在宿主机直接敲 ceph
  • OSD 起不来按 K8s → Operator → prepare 作业 → Ceph 四层顺序排查
  • Rook 和 cephadm 管的是同一个 Ceph,概念完全通用

延伸资料

  • ·k8s-in-actionstorage/rook/README.md
  • ·k8s-in-actionstorage/rook/day-2.md