如何将一个持久卷声明的数据与另一个隔离

Posted

技术标签:

【中文标题】如何将一个持久卷声明的数据与另一个隔离【英文标题】:How to isolate data of one persistent volume claim from another 【发布时间】:2020-01-07 14:30:38 【问题描述】:

我使用以下 YAML 创建了一个持久卷

apiVersion: v1
kind: PersistentVolume
metadata:
  name: dq-tools-volume
  labels:
    name: dq-tools-volume
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: volume-class
  nfs:
    server: 192.168.215.83
    path: "/var/nfsshare"

创建后,我使用以下 YAMLS 创建了两个持久化卷声明

PVC1:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-volume-1
  labels:
    name: jenkins-volume-1
spec:
  accessMOdes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  storageClassName: volume-class
  selector:
    matchLabels:
      name: dq-tools-volume

PVC2:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-volume-2
  labels:
    name: jenkins-volume-2
spec:
  accessMOdes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  storageClassName: volume-class
  selector:
    matchLabels:
      name: dq-tools-volume

但我注意到这两个持久卷声明都在写入相同的后端卷。

如何将一个persistentvolumeclaim 的数据与另一个隔离。我将它用于 Jenkins 的多个安装。我希望隔离每个 Jenkins 的工作空间。

【问题讨论】:

【参考方案1】:

作为@D.T.解释了持久卷声明仅绑定到持久卷。您不能将 2 pvc 绑定到同一个 pv

Here你可以找到另一个讨论它的案例。

对于您的方案有一个更好的解决方案,它涉及使用nfs-client-provisioner。为了实现这一点,首先您必须在集群中安装 helm,然后按照我在 ServerFault 上为之前的 answer 创建的这些步骤进行操作。

我已经对其进行了测试,使用此解决方案您可以将一种 PVC 与另一种隔离开来。

1 - 在我的主节点上安装和配置 NFS 服务器(Debian Linux,这可能会根据您的 Linux 发行版而有所不同):

在安装 NFS Kernel 服务器之前,我们需要更新系统的存储库索引:

$ sudo apt-get update

现在,运行以下命令以在您的系统上安装 NFS 内核服务器:

$ sudo apt install nfs-kernel-server

创建导出目录

$ sudo mkdir -p /mnt/nfs_server_files

由于我们希望所有客户端都能访问该目录,我们将通过以下命令删除导出文件夹的限制性权限(这可能会根据您的安全策略而有所不同):

$ sudo chown nobody:nogroup /mnt/nfs_server_files
$ sudo chmod 777 /mnt/nfs_server_files

通过 NFS 导出文件将服务器访问权限分配给客户端

$ sudo nano /etc/exports

在此文件中,添加一个新行以允许其他服务器访问您的共享。

/mnt/nfs_server_files        10.128.0.0/24(rw,sync,no_subtree_check)

您可能希望在共享中使用不同的选项。 10.128.0.0/24是我的k8s内网。

导出共享目录并重启服务,确保所有配置文件正确。

$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server

检查所有活跃的共享:

$ sudo exportfs
/mnt/nfs_server_files
                10.128.0.0/24

2 - 在我的所有工作节点上安装 NFS 客户端:

$ sudo apt-get update
$ sudo apt-get install nfs-common

此时您可以进行测试以检查您是否可以从工作节点访问您的共享:

$ sudo mkdir -p /mnt/sharedfolder_client
$ sudo mount kubemaster:/mnt/nfs_server_files /mnt/sharedfolder_client

请注意,此时您可以使用主节点的名称。 K8s 在这里处理 DNS。 检查卷是否按预期安装,并为男性创建一些文件夹和文件,确保一切正常。

$ cd /mnt/sharedfolder_client
$ mkdir test
$ touch file

返回您的主节点并检查这些文件是否位于 /mnt/nfs_server_files 文件夹中。

3 - 安装 NFS 客户端配置器

使用 helm 安装配置器:

$ helm install --name ext --namespace nfs --set nfs.server=kubemaster --set nfs.path=/mnt/nfs_server_files stable/nfs-client-provisioner

请注意,我已经为它指定了一个命名空间。 检查它们是否正在运行:

$ kubectl get pods -n nfs
NAME                                         READY   STATUS      RESTARTS   AGE
ext-nfs-client-provisioner-f8964b44c-2876n   1/1     Running     0          84s

此时我们有了一个名为 nfs-client 的存储类:

$ kubectl get storageclass -n nfs
NAME         PROVISIONER                                AGE
nfs-client   cluster.local/ext-nfs-client-provisioner   5m30s

我们需要创建一个 PersistentVolumeClaim:

$ more nfs-client-pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: nfs 
  name: test-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: "nfs-client"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
$ kubectl apply -f nfs-client-pvc.yaml

检查状态(预计绑定):

$ kubectl get persistentvolumeclaim/test-claim -n nfs
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound    pvc-e1cd4c78-7c7c-4280-b1e0-41c0473652d5   1Mi        RWX            nfs-client     24s

4 - 创建一个简单的 pod 来测试我们是否可以读/写 NFS 共享:

使用这个 yaml 创建一个 pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod0
  labels:
    env: test
  namespace: nfs  
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-claim
$ kubectl apply -f pod.yaml

让我们列出 pod 上所有已挂载的卷:

$ kubectl exec -ti -n nfs pod0 -- df -h /mnt
Filesystem                                                                               Size  Used Avail Use% Mounted on
kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1   99G   11G   84G  11% /mnt

正如我们所见,我们在 /mnt 上挂载了一个 NFS 卷。 (重要注意路径kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1

让我们检查一下:

root@pod0:/# cd /mnt
root@pod0:/mnt# ls -la
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov  5 08:33 .
drwxr-xr-x 1 root   root    4096 Nov  5 08:38 ..

它是空的。让我们创建一些文件:

$ for i in 1 2; do touch file$i; done;
$ ls -l 
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov  5 08:58 .
drwxr-xr-x 1 root   root    4096 Nov  5 08:38 ..
-rw-r--r-- 1 nobody nogroup    0 Nov  5 08:58 file1
-rw-r--r-- 1 nobody nogroup    0 Nov  5 08:58 file2

现在让我们看看这些文件在 NFS 服务器(主节点)上的位置:

$ cd /mnt/nfs_server_files
$ ls -l 
total 4
drwxrwxrwx 2 nobody nogroup 4096 Nov  5 09:11 nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12
$ cd nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12/
$ ls -l 
total 0
-rw-r--r-- 1 nobody nogroup 0 Nov  5 09:11 file1
-rw-r--r-- 1 nobody nogroup 0 Nov  5 09:11 file2

这是我们刚刚在 pod 中创建的文件!

【讨论】:

【参考方案2】:

据我了解不可能将两个 PVC 绑定到同一个 PV

参考此链接>A PVC to PV binding is a one-to-one mapping

您可能需要查看Dynamic Provisioning option 进行设置。

通过创建一个 10G 的 PV 和两个具有 8Gi 的 PVC 和一个 2Gi 声明请求进行测试 PVC-2 进入挂起状态。

master $ kubectl get persistentvolume
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM         STORAGECLASS   REASON    AGE
pv        10Gi       RWX            Retain           Bound     default/pv1                            7m


master $ kubectl get persistentvolumeclaims
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1       Bound     pv        10Gi       RWX                           3m
pvc2       Pending                                                      8s

用于创建 PV 和 PVC 的文件如下

master $ cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /var/tmp/
master $ cat pvc1.ayml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 8Gi
master $ cat pvc2.ayml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

【讨论】:

以上是关于如何将一个持久卷声明的数据与另一个隔离的主要内容,如果未能解决你的问题,请参考以下文章

如何识别持久卷声明中剩余的存储空间?

k8s基础学习-介绍持久卷和持久卷声明

如何声明 NFS 持久卷? [关闭]

将文件放置在 GKE 上的 Kubernetes 持久卷存储中

为啥匹配的持久卷不绑定到匹配的持久卷声明(使用 k3s)?

Kubernetes 数据持久化之Persistent 数据卷类型