问题描述
我正在尝试了解 Kubernetes PersistentVolumes
的访问模式。
根据 Kubernetes 文档,访问模式是:
ReadWriteOnce -- the volume can be mounted as read-write by a single node
ReadOnlyMany -- the volume can be mounted read-only by many nodes
ReadWriteMany -- the volume can be mounted as read-write by many nodes
Volume Plugin HostPath
支持 ReadWriteOnce
我有一个 1 controlplane and 1 worker1 node
的 K8s 集群,我按照以下配置将两个 Pod 部署到同一个 namespace
中的每个节点、pv、pvc。运行在不同节点上的两个 Pod 都能够读写本地路径 /tmp/test
。
根据我的理解,这不应该发生。只有一个节点可以读写,另一个节点应该只能读。
有人可以解释这里发生的事情吗?如果可能,请向我提供示例/博客以了解 RWO,RWX,ROX
之间的差异?大部分博客,只是简单的说一下PV、PVC和访问方式。
apiVersion: v1
kind: Pod
Metadata:
name: pod2
spec:
nodeName: controlplane
containers:
- image: Nginx
name: pod2
volumeMounts:
- name: vol
mountPath: /usr/share/Nginx/html
volumes:
- name: vol
persistentVolumeClaim:
claimName: pvc
---
apiVersion: v1
kind: Pod
Metadata:
name: pod1
spec:
nodeName: worker1
containers:
- image: Nginx
name: pod1
volumeMounts:
- name: vol
mountPath: /usr/share/Nginx/html
volumes:
- name: vol
persistentVolumeClaim:
claimName: pvc
---
apiVersion: v1
kind: PersistentVolume
Metadata:
name: pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/test
---
apiVersion: v1
kind: PersistentVolumeClaim
Metadata:
name: pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
解决方法
-
请注意,您不应在控制平面上运行 Pod,因此您应将 yaml 文件中的
nodeName: controlplane
替换为nodeName: worker2
。通常你需要使用toleration
在控制平面上运行 pod,因为它有一个污点阻止在它上面运行常规 pod... -
我在 Google Kubernetes Engine (gke) 上尝试了您的 yaml,我必须替换
nodeName
字段才能使其正常工作:
diff example.yaml example-gke.yaml
6c6
< nodeName: controlplane
---
> nodeName: gke-qserv-dev-worker-pool-a64a-01bc5238-3zl9
23c23
< nodeName: worker1
---
> nodeName: gke-qserv-dev-worker-pool-a64a-01bc5238-23t3
如您所见,k8s 拒绝创建 pod2
:
kubectl get pods
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 6m27s
pod2 0/1 ContainerCreating 0 6m27s
这是我收到的消息:
kubectl describe pod pod2 | tail -n 1
Warning FailedAttachVolume 7m28s attachdetach-controller Multi-Attach error for volume "pvc-2fb657ce-4678-4e92-9f64-e4b46b9a3ec7" Volume is already used by pod(s) pod1
因此,如您所见,您无法在两个不同节点上运行的两个不同 Pod 上安装 PV。所以你得到的不是常规的 k8s 行为。这可能是您的存储类别的副作用,尤其是在您使用 minikube
或 kind
时。