我正在运行一个由提供 RBD 块设备的 Ceph 服务支持的 OpenShift 环境。当同一卷映射到多个节点时(例如,使用时),我看到了意外行为:对卷所做的更改不会反映在也映射同一 rbd 卷的其他节点上。

注意:为了避免混淆,因为有很多人问的是不同的问题,我没有尝试从这些设备挂载文件系统。我直接与块设备交互。

例如,考虑这样的 PersistentVolumeClaim:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: blockvol
spec:
  accessModes:
  - ReadWriteMany
  volumeMode: Block
  resources:
    requests:
      storage: 1Gi

该卷作为块设备映射到多个 pod 中,部署如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bvexample
spec:
  replicas: 2
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - blockvol
            topologyKey: kubernetes.io/hostname
      containers:
      - name: blockvol
        image: docker.io/python:3.12
        env:
        - name: NODE
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        resources:
          requests:
            cpu: 100m
            memory: 512Mi
          limits:
            cpu: 100m
            memory: 1Gi
        volumeDevices:
        - devicePath: /dev/blockvol
          name: blockvol
        command:
        - sleep
        - inf
      volumes:
        - name: blockvol
          persistentVolumeClaim:
            claimName: blockvol

当一切正常运行时,我们会看到 pod 在集群中的两个不同节点上运行:

$ kubectl get pod -l app=blockvol -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
bvexample-6f64cffc5f-5f5jc   1/1     Running   0          6m27s   10.128.17.189   wrk-29   <none>           <none>
bvexample-6f64cffc5f-k8bjr   1/1     Running   0          6m27s   10.131.17.137   wrk-35   <none>           <none>

/dev/blockvol该设备在吊舱内部暴露如下:

$ kubectl get pod -l app=blockvol -o name |
  xargs -IPOD sh -c 'echo === POD ===; kubectl exec POD -- ls -l /dev/blockvol'
=== pod/bvexample-6f64cffc5f-5f5jc ===
brw-rw-rw-. 1 root disk 252, 16 Sep 25 01:09 /dev/blockvol
=== pod/bvexample-6f64cffc5f-k8bjr ===
brw-rw-rw-. 1 root disk 252, 16 Sep 25 01:09 /dev/blockvol

最初,该设备只有零:

1000820000@bvexample-6f64cffc5f-k8bjr:/$ od -N16 -xa /dev/blockvol
0000000    0000    0000    0000    0000    0000    0000    0000    0000
        nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul
0000020

如果我向此设备写入数据,我希望这些更改能够立即在其他节点上可见。但是,如果我在一个 pod 中运行:

1000820000@bvexample-6f64cffc5f-k8bjr:/$ echo this is a test. > /dev/blockvol
1000820000@bvexample-6f64cffc5f-k8bjr:/$ od -N16 -xa /dev/blockvol
0000000    6874    7369    6920    2073    2061    6574    7473    0a2e
          t   h   i   s  sp   i   s  sp   a  sp   t   e   s   t   .  nl
0000020

另一个 pod(位于不同的节点上)继续查看原始数据:

1000820000@bvexample-6f64cffc5f-5f5jc:/$ od -N16 -xa /dev/blockvol
0000000    0000    0000    0000    0000    0000    0000    0000    0000
        nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul nul
0000020

如果我杀死这些 pod,迫使它们在新节点上重新安排:

$ kubectl delete pod -l app=blockvol

然后,更改将在两个位置的块设备上可见:

=== pod/bvexample-6f64cffc5f-bkb5q ===
0000000    6874    7369    6920    2073    2061    6574    7473    0a2e
          t   h   i   s  sp   i   s  sp   a  sp   t   e   s   t   .  nl
0000020
=== pod/bvexample-6f64cffc5f-vv595 ===
0000000    6874    7369    6920    2073    2061    6574    7473    0a2e
          t   h   i   s  sp   i   s  sp   a  sp   t   e   s   t   .  nl
0000020

看起来 rbd 驱动程序正在本地缓存更改,直到 rbd 设备与节点分离,此时更改才真正被写回到磁盘。这是……rbd 设备的正常行为吗?某种配置设置?这是出乎意料的,意味着该模式实际上ReadWriteMany是一个谎言(当然,您可以写入它,但您实际上无法在任何地方读取该数据)。

2

  • 我不是 k8s 专家,但根据 ReadWriteMany 不在 RBD 的涵盖范围内。这是设计使然,如果您需要 ReadWriteMany,还有其他几个线程建议使用 CephFS。


    – 

  • 您正在查看。使用 cephfs 涵盖了不同的情况(基于 RWX 文件的卷,而不是原始块设备)。


    – 


0