例如在以下示例中:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: exmaple-pvc
spec:
accessModes:
- ReadOnlyMany
- ReadWriteMany
storageClassName: standard
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
Run Code Online (Sandbox Code Playgroud)
为什么这是允许的?在这种情况下,卷的实际行为是什么?只读?读和写?
为了能够完全理解为什么在特定的yaml定义领域中使用某种结构,首先我们需要了解这个特定领域的目的。我们需要问它是做什么的,它在这个特定的kubernetes api-resource 中的功能是什么。
我努力找到了对accessModesin的正确解释,PersistentVolumeClaim我必须承认我在官方 kubernetes 文档中发现的内容并没有让我满意:
A
PersistentVolume可以以资源提供者支持的任何方式挂载在主机上。如下表所示,提供者将具有不同的能力,并且每个 PV 的访问模式被设置为该特定卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能会在服务器上以只读形式导出。每个 PV 都有自己的一组访问模式来描述该特定 PV 的功能。
幸运的是,这次我设法在openshift 文档中找到了对这个主题的非常好的解释。我们可以在那里阅读:
声明与具有类似访问模式的卷相匹配。仅有的两个匹配标准是访问模式和大小。声明的访问模式代表一个请求。因此,您可能会获得更多,但绝不会更少。例如,如果声明请求 RWO,但唯一可用的卷是 NFS PV (RWO+ROX+RWX),则该声明将匹配 NFS,因为它支持 RWO。
总是首先尝试直接匹配。卷的模式必须匹配或包含比您请求的更多的模式。大小必须大于或等于预期的大小。如果两种类型的卷(例如 NFS 和 iSCSI)具有相同的访问模式集,则它们中的任何一个都可以将声明与这些模式匹配。卷类型之间没有排序,也无法选择一种类型而不是另一种类型。
所有具有相同模式的卷被分组,然后按大小排序,从最小到最大。活页夹获取具有匹配模式的组,并按大小顺序迭代每个组,直到一个大小匹配。
现在可能是最重要的部分:
卷
AccessModes是卷功能的描述符。它们不是强制约束。存储提供程序负责因无效使用资源而导致的运行时错误。
我强调了这部分,因为AccessModes很容易被误解。让我们看一下这个例子:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: exmaple-pvc-2
spec:
accessModes:
- ReadOnlyMany
storageClassName: standard
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
Run Code Online (Sandbox Code Playgroud)
我们在PersistentVolumeClaim定义中指定onlyReadOnlyMany访问模式的事实并不意味着它不能用于accessModes我们的存储提供商支持的其他模式。重要的是要理解,我们不能在这里对我们的Pods. 如果我们的存储提供程序隐藏在我们的standard存储类后面,也支持ReadWriteOnce,那么它也可以使用。
回答您的特定问题...
为什么这是允许的?在这种情况下,卷的实际行为是什么?只读?读和写?
它根本没有定义卷的行为。卷将根据其功能运行(我们没有定义它们,它们是预先强加的,是存储规范的一部分)。换句话说,我们将能够以我们Pods允许使用的所有可能方式使用它。
假设我们的standard存储配置器,在GKE 的情况下恰好是Google Compute Engine Persistent Disk:
$ kubectl get storageclass
NAME PROVISIONER AGE
standard (default) kubernetes.io/gce-pd 10d
Run Code Online (Sandbox Code Playgroud)
目前支持两种AccessModes:
ReadWriteOnceReadOnlyMany因此,无论我们在声明中指定了什么,我们都可以使用它们,例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 1
selector:
matchLabels:
app: debian
template:
metadata:
labels:
app: debian
spec:
containers:
- name: debian
image: debian
command: ['sh', '-c', 'sleep 3600']
volumeMounts:
- mountPath: "/mnt"
name: my-volume
readOnly: true
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: example-pvc-2
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'echo "Content of my file" > /mnt/my_file']
volumeMounts:
- mountPath: "/mnt"
name: my-volume
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,使用了两种功能。首先我们的卷被挂载到rw模式中,init container它保存了一些文件,然后它被挂载到main container只读文件系统。即使我们PersistentVolumeClaim只指定了一种访问模式,我们仍然可以这样做:
spec:
accessModes:
- ReadOnlyMany
Run Code Online (Sandbox Code Playgroud)
回到你在标题中提出的问题:
为什么可以在持久卷上设置多个访问模式?
答案是:您根本无法设置它们,因为它们已经由存储提供商设置,您只能通过这种方式请求您想要的存储、它必须满足的要求以及这些要求之一是它支持的访问模式。
基本上通过键入:
spec:
accessModes:
- ReadOnlyMany
- ReadWriteOnce
Run Code Online (Sandbox Code Playgroud)
在我们的PersistentVolulmeClaim定义中,我们说:
“嘿!存储提供商!给我一个卷支持这套accessModes我不在乎。它是否支持任何其他的像ReadWriteMany,因为我不需要他们给我的东西,符合我的要求!”
我相信这里不需要进一步解释为什么使用数组。
| 归档时间: |
|
| 查看次数: |
847 次 |
| 最近记录: |