我正在运行一个由提供 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
–
–
|