如何预填充ReadOnlyMany永久卷

时间:2019-09-02 08:59:53

标签: kubernetes google-kubernetes-engine persistent-storage

我正在尝试在GKE中创建一个使用多个副本的部署。我有一些静态数据,希望在每个吊舱中都可用。此数据将不会更新,不需要写入。

我决定将PV与ReadOnlyMany存储类一起使用。问题是,我不知道如何将数据实际传输到该卷-因为它是只读的。我尝试使用

gcloud compute scp /local/path instance:/remote/path

但是,当然,我得到一个权限错误。然后,我尝试通过控制台创建新的PV。我使用

将其附加到VM
gcloud compute instances attach disk

安装并格式化磁盘,传输我的数据,卸载磁盘,将其与VM分离,最后在the documentation之后创建PVC。我将存储类更改为ReadOnlyMany,唯一的区别。

但是,尽管如此,当我尝试将部署扩展到多个副本时,我仍然收到错误消息,表明磁盘已经连接到另一个节点。

那么,如何创建要在ReadOnlyMany中使用的卷,并用数据填充磁盘?还是因为不需要写而有更好的方法?

预先感谢

3 个答案:

答案 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进行调度。可以通过此rwPod模式挂载它,因为 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