K8s PersistentVolume 在多个 PersistentVolumeClaims 之间共享,用于本地测试

K8s PersistentVolume shared among multiple PersistentVolumeClaims for local testing

有人可以帮我指出我的用例应该做什么配置吗?

我正在构建一个开发 k8s 集群,其中一个步骤是生成安全文件(私钥),这些文件在部署期间 pods 中生成(假设我有一个简单的设置6 pods 每个人都构建自己的安全密钥)。我需要访问所有这些文件,而且它们必须在 pod 关闭后保持不变。

我现在正在尝试弄清楚如何在本地设置它以进行内部测试。据我了解,本地 PersistentVolumes 仅允许 1:1 具有 PersistentVolumeClaims,因此我必须为每个已配置的 Pod 创建一个单独的 PersistentVolume 和 PersistentVolumeClaim。我宁愿取消它并为所有人使用一个 PersistentVolume。

有人可以帮助我或指出应该使用的正确设置吗?

-- 更新:26/11/2020 所以这是我的设置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hlf-nfs--server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hlf-nfs--server
  template:
    metadata:
      labels:
        app: hlf-nfs--server
    spec:
      containers:
        - name: hlf-nfs--server
          image: itsthenetwork/nfs-server-alpine:12
          ports:
            - containerPort: 2049
              name: tcp
            - containerPort: 111
              name: udp
          securityContext:
            privileged: true
          env:
            - name: SHARED_DIRECTORY
              value: "/opt/k8s-pods/data"
          volumeMounts:
            - name: pvc
              mountPath: /opt/k8s-pods/data
      volumes:
        - name: pvc
          persistentVolumeClaim:
            claimName: shared-nfs-pvc
apiVersion: v1
kind: Service
metadata:
  name: hlf-nfs--server
  labels:
    name: hlf-nfs--server
spec:
  type: ClusterIP
  selector:
    app: hlf-nfs--server
  ports:
    - name: tcp-2049
      port: 2049
      protocol: TCP
    - name: udp-111
      port: 111
      protocol: UDP
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  resources:
    requests:
      storage: 1Gi

这三个正在一次创建,之后,我正在读取服务的 IP 并将其添加到最后一个:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: shared-nfs-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s-pods/data
    server: <<-- IP from `kubectl get svc -l name=hlf-nfs--server`

我遇到并试图解决的问题是 PVC 没有与 PV 绑定并且部署保持在 READY 模式。

我错过了什么吗?

您可以创建 NFS 并让 pods 使用 NFS 卷。这是创建此类集群内 NFS 服务器的清单文件(确保修改 STORAGE_CLASS 和下面的其他变量):

export NFS_NAME="nfs-share"
export NFS_SIZE="10Gi"
export NFS_IMAGE="itsthenetwork/nfs-server-alpine:12"
export STORAGE_CLASS="thin-disk"

kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: ${NFS_NAME}
  labels:
    app.kubernetes.io/name: nfs-server
    app.kubernetes.io/instance: ${NFS_NAME}
spec:
  ports:
  - name: tcp-2049
    port: 2049
    protocol: TCP
  - name: udp-111
    port: 111
    protocol: UDP
  selector:
    app.kubernetes.io/name: nfs-server
    app.kubernetes.io/instance: ${NFS_NAME}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    app.kubernetes.io/name: nfs-server
    app.kubernetes.io/instance: ${NFS_NAME}
  name: ${NFS_NAME}
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: $STORAGE_CLASS
  volumeMode: Filesystem
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${NFS_NAME}
  labels:
    app.kubernetes.io/name: nfs-server
    app.kubernetes.io/instance: ${NFS_NAME}
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: nfs-server
      app.kubernetes.io/instance: ${NFS_NAME}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nfs-server
        app.kubernetes.io/instance: ${NFS_NAME}
    spec:
      containers:
      - name: nfs-server
        image: ${NFS_IMAGE}
        ports:
        - containerPort: 2049
          name: tcp
        - containerPort: 111
          name: udp
        securityContext:
          privileged: true
        env:
        - name: SHARED_DIRECTORY
          value: /nfsshare
        volumeMounts:
        - name: pvc
          mountPath: /nfsshare
      volumes:
      - name: pvc
        persistentVolumeClaim:
          claimName: ${NFS_NAME}
EOF

下面是如何将另一个 pods 指向此 NFS 的示例。特别是,请参阅 YAML 末尾的 volumes 部分:

export NFS_NAME="nfs-share"
export NFS_IP=$(kubectl get --template={{.spec.clusterIP}} service/$NFS_NAME)

kubectl apply -f - <<EOF
kind: Deployment
apiVersion: apps/v1
metadata:
  name: apache
  labels:
    app: apache
spec:
  replicas: 2
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
      containers:
        - name: apache
          image: apache
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /var/www/html/
              name: nfs-vol
              subPath: html
      volumes:
        - name: nfs-vol
          nfs: 
            server: $NFS_IP
            path: /
EOF

PersistentVolumeClaimPersistentVolume 之间存在 1:1 关系是正确的。

但是,Pods 运行 在同一个节点上可以同时挂载同一个卷,例如使用相同的 PersistentVolumeClaim.

如果使用Minikube进行本地开发,只有一个节点,所以同样可以使用PersistentVolumeClaim。由于您想为每个应用程序使用不同的文件,您可以为该共享卷中的每个应用程序使用一个 唯一目录

所以最后,我通过使用动态提供程序做到了。

我用 helm 安装了 stable/nfs-server-provisioner。通过适当的配置,它成功地创建了一个名为 nfs two 的 pv,我的 pvc 能够绑定 :)

helm install stable/nfs-server-provisioner --name nfs-provisioner -f nfs_provisioner.yaml

nfs_provisioner.yaml如下

persistence:
  enabled: true
  storageClass: "standard"
  size: 20Gi

storageClass:
  # Name of the storage class that will be managed by the provisioner
  name: nfs
  defaultClass: true