我有一个三节点的GCE集群和一个带有三个副本的单pod GKE部署。我创建了PV和PVC这样:
# Create a persistent volume for web content
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-content
labels:
type: local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadOnlyMany
hostPath:
path: "/usr/share/nginx/html"
--
# Request a persistent volume for web content
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-content-claim
annotations:
volume.alpha.kubernetes.io/storage-class: default
spec:
accessModes: [ReadOnlyMany]
resources:
requests:
storage: 5Gi
字符串
它们在容器规范中引用如下:
spec:
containers:
- image: launcher.gcr.io/google/nginx1
name: nginx-container
volumeMounts:
- name: nginx-content
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: nginx-content
persistentVolumeClaim:
claimName: nginx-content-claim
型
即使我将卷创建为ReadOnlyMany,但在任何给定时间只有一个pod可以挂载卷。其余给予“错误400:RESOURCE_IN_USE_BY_ANOTHER_RESOURCE”。如何才能使所有三个副本都从同一卷读取相同的Web内容?
5条答案
按热度按时间eh57zj3b1#
首先我想指出你们的配置中的一个基本缺陷。请注意,当您使用示例中定义的
PersistentVolumeClaim
时,您根本没有使用nginx-content
PersistentVolume
。您可以通过运行以下命令轻松验证它:字符串
在您的GKE集群上。您会注意到,除了您手动创建的
nginx-content
PV
之外,还有一个基于您应用的PVC
自动配置的nginx-content
。请注意,在
PersistentVolumeClaim
定义中,您明确地引用了default
存储类,它与手动创建的PV
无关。实际上,即使你完全省略注解:型
它将以完全相同的方式工作,即无论如何都将使用
default
存储类。如果在GKE上使用默认存储类,则意味着GCE持久磁盘将用作您的卷调配器。你可以在这里阅读更多关于它:gcePersistentDisk等卷实现是通过StorageClass资源配置的。GKE为您创建一个默认的StorageClass,它使用标准持久磁盘类型(ext4)。当PersistentVolumeClaim未指定StorageClassName时,将使用默认StorageClass。您可以将提供的默认StorageClass替换为您自己的。
但让我们继续讨论你面临的问题的解决方案。
解决方案:
首先,我想强调您不必使用任何类似NFS的文件系统来实现您的目标。
如果您需要
PersistentVolume
在ReadOnlyMany
模式下可用,GCE持久磁盘是完全满足您需求的完美解决方案。它可以安装在
ro
模式由多个Pods
在同一时间和什么是更重要的多个Pods
,调度在不同的GKEnodes
。此外,它的配置非常简单,而且它可以在GKE上运行。如果你想在
ReadWriteMany
模式下使用你的存储,我同意像NFS这样的东西可能是唯一的解决方案,因为GCE持久磁盘不提供这样的功能。让我们仔细看看如何配置它。
我们需要从定义
PVC
开始。这一步实际上已经由你自己完成了,但你在接下来的步骤中迷失了一点。让我解释一下它是如何工作的。以下配置是正确的(正如我提到的
annotations
部分可以省略):型
不过,我想补充一点重要的评论。你说:
即使我将卷创建为ReadOnlyMany,但在任何给定时间只有一个pod可以挂载卷。
其实你没有。我知道这看起来有点棘手,有点令人惊讶,但这并不是定义
accessModes
的方式。事实上,这是一个被广泛误解的概念。首先,你不能在PVC
中定义访问模式,这是你想要的约束。支持的访问模式是特定存储类型的固有特性。它们已由存储提供商定义。在
PVC
定义中实际做的是请求支持特定访问模式的PV
。请注意,它的形式是a list**,这意味着您可以提供许多不同的访问模式,您希望您的PV
支持。基本上就像是在说:* “嘿!存储提供商!请给予我一个支持
ReadOnlyMany
模式的卷。"* 您要求的存储以满足您的要求。但是请记住,你可以得到比你要求的更多的东西。这也是我们在GCP中要求PV
支持ReadOnlyMany
模式时的场景。它为我们创建了一个PersistentVolume
,满足了我们在accessModes
部分列出的要求,但它也支持ReadWriteOnce
模式。虽然我们没有要求支持ReadWriteOnce
的东西,但你可能会同意我的看法,内置支持这两种模式的存储完全满足了我们对支持ReadOnlyMany
的东西的要求。所以基本上这就是它的工作方式。您的
PV
由GCP自动配置以响应您的PVC
支持这两个accessModes
,如果您在Pod
或Deployment
定义中没有明确指定您要以只读模式挂载,则默认情况下,它将以**读写 * 模式挂载。您可以通过连接到能够成功挂载
PersistentVolume
的Pod
来轻松验证它:型
并试图在挂载的文件系统上写些东西。
您收到的错误消息:
型
特别关注GCE持久磁盘,它已经由一个GKE
node
在ReadWriteOnce
模式下挂载,而它不能由另一个node
挂载,而你的Pods
的其余部分则被安排在该Pods
上。如果你想在
ReadOnlyMany
模式下挂载,你需要在Deployment
定义中通过在Pod's
模板规范下的volumes
部分添加readOnly: true
语句来明确指定它,如下所示:型
但是请记住,为了能够在
readOnly
模式下挂载它,首先我们需要用数据预先填充这样的卷。否则,您将看到另一个错误消息,说未格式化的卷不能在只读模式下挂载。最简单的方法是创建一个
Pod
,该Pod
只用于将已经上传到我们的某个GKE节点的数据复制到目标PV
。请注意,预先填充
PersistentVolume
的数据可以通过许多不同的方式完成。您可以在这样的Pod
中装载您将在Deployment
中使用的PersistentVolume
,并使用curl
或wget
从某个外部位置获取数据,将其直接保存在您的目标PV
上。你决定吧在我的示例中,我展示了如何使用额外的本地卷来实现这一点,该卷允许我们装载到我们的
Pod
directory
,partition
或disk
(在我的示例中,我使用位于我的一个GKE节点上的目录/var/tmp/test
),在我们的一个kubernetes节点上可用。这是比hostPath
灵活得多的解决方案,因为我们不需要关心调度这样的Pod
到特定的节点,其中包含数据。PersistentVolume
中已经定义了特定的节点亲和性**规则,Pod
会自动调度到特定节点上。要创建它,我们需要三件事:
StorageClass
:型
PersistentVolume
定义:型
最后是
PersistentVolumeClaim
:型
然后我们可以创建临时
Pod
,它只用于将数据从我们的GKE节点复制到我们的GCE持久磁盘。型
上面看到的路径并不重要。此
Pod
的任务只是允许我们将数据复制到目标PV
。最终,我们的PV
将安装在完全不同的路径上。创建
Pod
并成功装载了两个卷后,我们可以通过运行以下命令来附加到它:型
使用
Pod
简单地运行:型
就这样了。现在我们可以删除
exit
并删除临时Pod
:型
一旦它消失了,我们就可以应用我们的
Deployment
,我们的PersistentVolume
最终可以被位于各个**GKE节点上的所有Pods
以readOnly
模式挂载:型
顺便说一句,如果你对你的
Pods
将只在一个特定的节点上调度的事实没有意见,你可以完全给予使用GCE持久磁盘,切换到上面提到的本地卷。这样,所有的Pods
不仅可以读取它,还可以同时写入它。唯一需要注意的是,所有这些Pods
都将在单个节点上运行。e3bfsja22#
您可以使用类似NFS的文件系统来实现这一点。在Google Cloud上,Filestore是合适的产品(NFS托管)。您有一个教程here来实现您的配置
wbgh16ku3#
如果您想在不同节点之间共享卷并提供高度可扩展的解决方案,则需要使用读写多(RWX)类型的共享卷声明。就像使用NFS服务器。
您可以在此处了解如何部署NFS服务器:
https://www.shebanglabs.io/run-nfs-server-on-ubuntu-20-04/
然后,您可以按如下方式挂载卷(NFS服务器中的目录):
https://www.shebanglabs.io/how-to-set-up-read-write-many-rwx-persistent-volumes-with-nfs-on-kubernetes/的
我已经使用这种方式在+8 k8s部署(+200 pod)之间提供共享静态内容,每月通过Nginx服务10亿次请求。而且它确实在NFS设置下工作得很好:)
cidc1ykv4#
Google提供了类似NFS的文件系统,称为Google Cloud Filestore。您可以将其安装在多个Pod上。
66bbxpm55#
我通过将部署策略从“滚动”更改为“重新创建”解决了此问题。