gpt4 book ai didi

kubernetes - 如何在多个 Pod 上安装相同的持久卷?

转载 作者:行者123 更新时间:2023-12-02 11:55:20 28 4
gpt4 key购买 nike

我有一个三节点 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 内容?

最佳答案

首先,我想指出您的配置中的一个基本差异。请注意,当您使用 PersistentVolumeClaim 时在您的示例中定义,您不使用 nginx-content PersistentVolume根本。您可以通过运行轻松验证它:

kubectl get pv
在您的 GKE 集群 .您会注意到,除了您手动创建的 nginx-content PV ,还有另一个是基于 PVC 自动配置的。你申请的。
请注意,在您的 PersistentVolumeClaim您明确指的是 default 的定义与您手动创建的存储类无关 PV .实际上,即使您完全省略注释:
annotations:
volume.alpha.kubernetes.io/storage-class: default
它将以完全相同的方式工作,即 default无论如何都会使用存储类。在 上使用默认存储类GKE 意味着 GCE 永久磁盘 将用作您的卷供应商。您可以阅读更多相关信息 here :

Volume implementations such as gcePersistentDisk are configuredthrough StorageClass resources. GKE creates a default StorageClass foryou which uses the standard persistent disk type (ext4). The defaultStorageClass is used when a PersistentVolumeClaim doesn't specify aStorageClassName. You can replace the provided default StorageClasswith your own.


但是让我们继续解决您面临的问题。
解决方案:
首先,我想强调 您不必使用任何类似 NFS 的文件系统来实现您的目标 .
如果您需要您的 PersistentVolume可在 ReadOnlyMany 中使用模式, GCE 永久磁盘 是完全满足您要求的完美解决方案。
它可以安装在 ro多人模式 Pods同时还有很多人认为更重要的事情 Pods , 安排在不同的 GKE nodes .此外,它的配置非常简单,它适用于 GKE 盒子外面。
如果您想在 ReadWriteMany 中使用您的存储空间模式,我同意像 NFS 这样的东西可能是唯一的解决方案,因为 GCE 永久磁盘 不提供这样的能力。
让我们仔细看看如何配置它。
我们需要从定义我们的 PVC 开始.这一步实际上已经由你自己完成了,但你在进一步的步骤中有点迷失了。让我解释一下它是如何工作的。
以下配置是正确的(正如我提到的 annotations 部分可以省略):
# Request a persistent volume for web content
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-content-claim
spec:
accessModes: [ReadOnlyMany]
resources:
requests:
storage: 5Gi
但是,我想对此添加一项重要评论。你说:

Even though I created the volumes as ReadOnlyMany, only one pod canmount the volume at any given time.


嗯,实际上 你没有 .我知道这看起来有点棘手,有点令人惊讶,但这不是定义 accessModes 的方式。真的有效。事实上,这是一个被广泛误解的概念。首先 您不能在 PVC 中定义访问模式从某种意义上说,将您想要的约束放在那里。支持 访问模式是特定存储类型的固有特征。它们已经由存储提供者定义。
你实际上在做什么 PVC定义正在请求 PV支持特定的访问模式或访问模式。注意它的形式是 列表这意味着您可以提供许多不同的访问模式,您希望您的 PV支持。
基本上就像说:“嘿!存储提供商!给我一个支持 ReadOnlyMany 模式的卷。”您要求以这种方式获得满足您要求的存储。但是请记住,您可以得到的比您要求的更多。这也是我们要求 PV 时的场景。支持 ReadOnlyMany模式在 GCP .它为我们创建了一个 PersistentVolume满足我们在 accessModes中列出的要求部分但它也支持 ReadWriteOnce模式。虽然我们没有要求也支持 ReadWriteOnce 的东西您可能会同意我的观点,内置支持这两种模式的存储完全满足我们对支持 ReadOnlyMany 的要求。 .所以基本上这就是它的工作方式。
您的 PV由 GCP 自动配置以响应您的 PVC支持这两个 accessModes如果您没有在 Pod 中明确指定或 Deployment您想将其安装在 中的定义只读 模式,默认安装在 读写模式。
您可以通过附加到 Pod 轻松验证它。能够成功挂载 PersistentVolume :
kubectl exec -ti pod-name -- /bin/bash
并试图在挂载的文件系统上写一些东西。
你得到的错误信息:
"Error 400: RESOURCE_IN_USE_BY_ANOTHER_RESOURCE"
特别关注 GCE 永久磁盘 已经被一个 挂载了GKE nodeReadWriteOnce模式并且它不能被另一个 node 挂载剩下的你的 Pods被安排。
如果您希望它安装在 ReadOnlyMany模式,您需要在 Deployment 中明确指定它通过添加 readOnly: true 定义 volumes 中的声明部分下 Pod's模板规范如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-content
volumes:
- name: nginx-content
persistentVolumeClaim:
claimName: nginx-content-claim
readOnly: true
但是请记住,要能够将其安装在 readOnly 中模式,首先我们需要用数据预先填充这样的卷。否则,您将看到另一条错误消息,指出无法以只读模式安装未格式化的卷。
最简单的方法是创建一个 Pod仅用于复制已上传到我们的 之一的数据。 GKE 节点 到我们的目的地 PV .
请注意,预填充 PersistentVolume可以通过许多不同的方式处理数据。您可以安装在这样的 Pod只有您的 PersistentVolume您将在 Deployment 中使用的并使用 curl 获取您的数据或 wget从某个外部位置直接将其保存在您的目的地 PV .由你决定。
在我的例子中,我展示了如何使用额外的 local 来做到这一点。允许我们安装到我们的 Pod 的卷 directory , partitiondisk (在我的示例中,我使用位于我的 GKE 节点之一上的目录 /var/tmp/test)在我们的 kubernetes 节点之一上可用。它比 hostPath 更灵活的解决方案因为我们不必关心调度这样的 Pod到包含数据的特定节点。具体 节点亲和性 规则已在 PersistentVolume 中定义和 Pod在特定节点上自动调度。
要创建它,我们需要 3 件事: StorageClass :
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
PersistentVolume定义:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /var/tmp/test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- <gke-node-name>
最后 PersistentVolumeClaim :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Gi
storageClassName: local-storage
然后我们可以创建我们的临时 Pod仅用于从我们的 复制数据GKE 节点 到我们的 GCE 永久磁盘 .
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/mnt/source"
name: mypd
- mountPath: "/mnt/destination"
name: nginx-content
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
- name: nginx-content
persistentVolumeClaim:
claimName: nginx-content-claim
您可以在上面看到的路径并不重要。本次任务 Pod只是为了让我们将数据复制到目的地 PV .最终我们的 PV将安装在完全不同的路径中。
曾经 Pod创建并成功挂载两个卷,我们可以通过运行来附加到它:
kubectl exec -ti my-pod -- /bin/bash
Pod只需运行:
cp /mnt/source/* /mnt/destination/
就这样。现在我们可以 exit并删除我们的临时 Pod :
kubectl delete pod mypod
一旦它消失了,我们可以申请我们的 Deployment和我们的 PersistentVolume终于可以安装在 readOnly模式由所有 Pods位于各种 GKE 节点 :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-content
volumes:
- name: nginx-content
persistentVolumeClaim:
claimName: nginx-content-claim
readOnly: true
顺便提一句。如果您同意您的 Pods将只安排在一个特定的节点上,您可以放弃使用 GCE 永久磁盘 并切换到上述 local体积。这样你所有的 Pods不仅可以读取它,还可以同时写入它。唯一需要注意的是,所有这些 Pods将在单个节点上运行。

关于kubernetes - 如何在多个 Pod 上安装相同的持久卷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62309755/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com