我正在尝试在GKE中创建一个使用多个副本的部署。我有一些静态数据,希望在每个吊舱中都可用。此数据将不会更新,不需要写入。
我决定将PV与ReadOnlyMany存储类一起使用。问题是,我不知道如何将数据实际传输到该卷-因为它是只读的。我尝试使用
gcloud compute scp /local/path instance:/remote/path
但是,当然,我得到一个权限错误。然后,我尝试通过控制台创建新的PV。我使用
将其附加到VMgcloud compute instances attach disk
安装并格式化磁盘,传输我的数据,卸载磁盘,将其与VM分离,最后在the documentation之后创建PVC。我将存储类更改为ReadOnlyMany,唯一的区别。
但是,尽管如此,当我尝试将部署扩展到多个副本时,我仍然收到错误消息,表明磁盘已经连接到另一个节点。
那么,如何创建要在ReadOnlyMany中使用的卷,并用数据填充磁盘?还是因为不需要写而有更好的方法?
预先感谢
答案 0 :(得分:3)
为我工作。在Pod模板中使用持续批量声明时,您是否指定了readOnly: true
?
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-readonly-pvc
readOnly: true
在此处查看详细信息 https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks
答案 1 :(得分:0)
你好,尼古拉斯,
您要遵循的方法在很大程度上取决于您的用例。
当您将分布式文件系统用作CEPH,GlusterFS或GCP Cloud Filestore或将远程文件系统用作NFS时,遵循的方法非常普遍。
使用分布式FS或远程FS时,方法是:
1.--将AccessMode设置为RWO并将回收策略设置为RETAIN来创建PV。
2.-创建PVC
3.-将PVC附加到POD上
4.-通过POD将数据传输到卷中。
5.-删除pod,pvc和pv。
6.-对于要附加数据的EACH部署或POD,将AccessMode设置为ROX并将Reclaim Policy设置为RETAIN来创建一个新的PV。如果POD副本数大于1,则此方法不适用,因为Pod会附加相同的PV。
7.-为每个PV创建一个PVC。 PV和PVC的关系是1:1 8.-将PVC附加到要使用的每个POD或部署中。
您的问题似乎是您试图将同一PV附加到多个PVC上,但不允许这样做,关系PVC <-> PV是一对一的。
关于其他问题,是否有更好的方法,很大程度上取决于您的用例。 Google Cloud Platform提供了许多存储选项[1]。例如,如果您正在使用对象,则可以使用Google Cloud Storage [2]代替永久磁盘。
[1] https://cloud.google.com/kubernetes-engine/docs/concepts/storage-overview
[2] https://cloud.google.com/filestore/docs/accessing-fileshares
答案 2 :(得分:0)
我们可以简化整个过程。在 GKE 上,您实际上不需要基于 GCE永久磁盘手动创建PV
。您所需要做的就是定义正确的PVC
,其外观如下:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: webserver-content-claim
spec:
accessModes: [ReadOnlyMany]
resources:
requests:
storage: 5Gi
请记住,就某种特定的约束而言,您无法在PVC
中定义访问模式。您基本上要做的就是简单地请求支持此特定访问模式的存储。请注意,它采用列表的形式,这意味着您可以提供您希望PV
支持的许多不同的访问模式。我在this答案中对其进行了更详细的说明。但是这里的关键是通过在ReadOnlyMany
定义中设置PVC
访问模式,您仅请求支持这种访问类型的卷,但这并不意味着它不支持其他访问。模式。
如果您没有按照模板的{Ievgen Goichuk的建议,在readOnly: true
模板的volumes
部分中指定Pod
,则默认情况下它将以rw
模式挂载。由于 GCE永久磁盘不支持ReadWriteMany
访问模式,因此,该卷不能被其他Pods
装入,一旦已安装在其他nodes
rw
模式以一个Pod
的一个node
进行调度。可以通过此rw
以Pod
模式挂载它,因为 GCE永久磁盘还支持ReadWriteOnce
访问模式,根据the official docs的说法,该模式>“该卷可以通过单个节点以读写方式安装” 。这就是在其他节点上调度的Pods
无法挂载的原因。
但是让我们继续进行实际的解决方案。
创建上述PVC
后,您会看到相应的PV
也已创建(kubectl get pv
),其STATUS
为{{1} }。
现在,在开始以Bound
访问模式使用它之前,只需要以某种方式预填充它即可。我将分享最适合我的东西。
如果您已经在一个 Compute Engine 实例上上传了数据,并构成了工作节点的 node-pool ,则可以跳过下一步。
我假设您在本地计算机上安装了 gcloud 。
ReadOnlyMany
是实现此目标的正确方法。 @Nikolaos Paschos,如果出现gcloud compute scp /local/path instance:/remote/path
错误,则可能意味着您所捍卫的permission denied
是一些受限制的目录,您无法以非root用户身份访问。如果您尝试从本地文件系统复制内容,则会看到此错误。到远程计算机上的/remote/path
目录。最安全的方法是将文件复制到您有权访问的主目录:
/etc
如果要从源目录复制所有文件和目录及其内容,请使用gcloud compute scp --recurse /home/<username>/data/* <instance-name>:~ --zone <zone-name>
选项。
将数据上传到我们的一个工作节点后,我们需要将其复制到新创建的--recurse
中。可以通过几种不同的方式完成。
我决定为它使用临时PersistentVolume
且容量为local。
要使已经存在于 GKE工作节点之一上的数据也可用于我们的临时Pod
,让我们创建以下内容:
Pod
:
storage-class-local.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
:
pv-local.yaml
和apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /home/<username>
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- <gke-node-name>
:
pvc-local.yaml
在下一步中,我们创建临时apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Gi
storageClassName: local-storage
,这将使我们能够将数据Pod
(作为本地卷安装到node
)复制到基于Pod
在 GCE永久磁盘上。定义可能如下所示:
PV
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/mnt/source"
name: local-volume
- mountPath: "/mnt/destination"
name: gce-pd-volume
volumes:
- name: local-volume
persistentVolumeClaim:
claimName: myclaim
- name: gce-pd-volume
persistentVolumeClaim:
claimName: webserver-content-claim
启动并运行后,我们可以通过以下方式将其连接:
Pod
并复制我们的文件:
kubectl exec -ti mypod -- /bin/bash
现在,我们可以删除临时pod,本地pv和pvc。我们的cp -a /mnt/source/* /mnt/destination/
已经预先填充了数据,可以在PersistentVolume
模式下进行标记。
为了对其进行测试,我们可以运行以下ro
:
Deployment