简体   繁体   English

如何使用 PersistentVolumeClaim 在 Deployment/Pod 上挂载持久卷?

[英]How to mount a persistent volume on a Deployment/Pod using PersistentVolumeClaim?

I am trying to mount a persistent volume on pods (via a deployment).我正在尝试在 pod 上挂载一个持久卷(通过部署)。

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - image: ...
        volumeMounts:
        - mountPath: /app/folder
          name: volume
      volumes:
      - name: volume
        persistentVolumeClaim:
          claimName: volume-claim
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: volume-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

However, the pod stays in "ContainerCreating" status and the events show the following error message.但是,pod 仍处于“ContainerCreating”状态,并且事件显示以下错误消息。

Unable to mount volumes for pod "podname": timeout expired waiting for volumes to attach or mount for pod "namespace"/"podname". list of unmounted volumes=[volume]. list of unattached volumes=[volume]

I verified that the persistent volume claim is ok and bound to a persistent volume.我确认持久卷声明没问题并且绑定到持久卷。

What am I missing here?我在这里缺少什么?

If doing this in a cloud provider, the storageClass object will create the respective volume for your persistent volume claim.如果在云提供商中执行此操作, storageClass 对象将为您的持久卷声明创建相应的卷。

If you are trying to do this locally on minikube or in a self managed kubernetes cluster, you need to manually create the storageClass that will provide the volumes for you, or create it manually like this example:如果您尝试在 minikube 或自我管理的 kubernetes 集群中本地执行此操作,则需要手动创建将为您提供卷的 storageClass,或者像此示例一样手动创建:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

The hostPath variable will mount this data in the current pod node. hostPath 变量会将这些数据挂载到当前的 pod 节点中。

When you create a PVC without specifying a PV or type of StorageClass in GKE clusters it will fall back to default option:当您在 GKE 集群中未指定PVStorageClass类型的情况下创建PVC ,它将回退到默认选项:

  • StorageClass: standard
  • Provisioner: kubernetes.io/gce-pd
  • Type: pd-standard

Please take a look on official documentation: Cloud.google.com: Kubernetes engine persistent volumes请查看官方文档:Cloud.google.com:Kubernetes 引擎持久卷

There could be a lot of circumstances that can produce error message encountered.可能有很多情况会产生遇到的错误消息。

As it's unknown how many replicas are in your deployment as well as number of nodes and how pods were scheduled on those nodes, I've tried to reproduce your issue and I encountered the same error with following steps (GKE cluster was freshly created to prevent any other dependencies that might affect the behavior).由于不知道您的部署中有多少副本以及节点数量以及如何在这些节点上安排 pod,我尝试重现您的问题,但我在执行以下步骤时遇到了相同的错误(GKE 集群是新创建的以防止可能影响行为的任何其他依赖项)。

Steps :步骤

  • Create a PVC创建一个 PVC
  • Create a Deployment with replicas > 1创建replicas > 1的部署
  • Check the state of pods检查 Pod 的状态
  • Additional links附加链接

Create a PVC创建一个 PVC

Below is example YAML definition of a PVC the same as yours:以下是与您相同的PVC的示例YAML定义:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: volume-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

After applying above definition please check if it created successfully.应用上述定义后,请检查它是否创建成功。 You can do it by using below commands:您可以使用以下命令来完成:

  • $ kubectl get pvc volume-claim
  • $ kubectl get pv
  • $ kubectl describe pvc volume-claim
  • $ kubectl get pvc volume-claim -o yaml

Create a Deployment with replicas > 1创建replicas > 1的部署

Below is example YAML definition of deployment with volumeMounts and replicas > 1:以下是使用volumeMountsreplicas > 1 的部署的示例YAML定义:

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: ubuntu-deployment
spec:
  selector:
    matchLabels:
      app: ubuntu
  replicas: 10 # amount of pods must be > 1
  template:
    metadata:
      labels:
        app: ubuntu
    spec:
      containers:
      - name: ubuntu
        image: ubuntu
        command:
        - sleep
        - "infinity"
        volumeMounts:
        - mountPath: /app/folder
          name: volume
      volumes:
      - name: volume
        persistentVolumeClaim:
          claimName: volume-claim

Apply it and wait for a while.应用它并等待一段时间。

Check the state of pods检查 Pod 的状态

You can check the state of pods with below command:您可以使用以下命令检查 Pod 的状态:

$ kubectl get pods -o wide

Output of above command:上述命令的输出:

NAME                      READY   STATUS              RESTARTS   AGE     IP            NODE                              
ubuntu-deployment-2q64z   0/1     ContainerCreating   0          4m27s   <none>        gke-node-1  
ubuntu-deployment-4tjp2   1/1     Running             0          4m27s   10.56.1.14    gke-node-2   
ubuntu-deployment-5tn8x   0/1     ContainerCreating   0          4m27s   <none>        gke-node-1   
ubuntu-deployment-5tn9m   0/1     ContainerCreating   0          4m27s   <none>        gke-node-3  
ubuntu-deployment-6vkwf   0/1     ContainerCreating   0          4m27s   <none>        gke-node-1  
ubuntu-deployment-9p45q   1/1     Running             0          4m27s   10.56.1.12    gke-node-2  
ubuntu-deployment-lfh7g   0/1     ContainerCreating   0          4m27s   <none>        gke-node-3  
ubuntu-deployment-qxwmq   1/1     Running             0          4m27s   10.56.1.13    gke-node-2 
ubuntu-deployment-r7k2k   0/1     ContainerCreating   0          4m27s   <none>        gke-node-3   
ubuntu-deployment-rnr72   0/1     ContainerCreating   0          4m27s   <none>        gke-node-3

Take a look on above output:看看上面的输出:

  • 3 pods are in Running state 3 个 Pod 处于Running状态
  • 7 pods are in ContainerCreating state 7 个 Pod 处于ContainerCreating状态

All of the Running pods are located on the same gke-node-2所有正在Running pod 都位于同一个gke-node-2

You can get more detailed information why pods are in ContainerCreating state by:您可以通过以下方式获得更多详细信息,为什么 Pod 处于ContainerCreating状态:

$ kubectl describe pod NAME_OF_POD_WITH_CC_STATE

The Events part in above command shows:上述命令中的Events部分显示:

Events:
  Type     Reason              Age                From                                             Message
  ----     ------              ----               ----                                             -------
  Normal   Scheduled           14m                default-scheduler                                Successfully assigned default/ubuntu-deployment-2q64z to gke-node-1
  Warning  FailedAttachVolume  14m                attachdetach-controller                          Multi-Attach error for volume "pvc-7d756147-6434-11ea-a666-42010a9c0058" Volume is already used by pod(s) ubuntu-deployment-qxwmq, ubuntu-deployment-9p45q, ubuntu-deployment-4tjp2
  Warning  FailedMount         92s (x6 over 12m)  kubelet, gke-node-1  Unable to mount volumes for pod "ubuntu-deployment-2q64z_default(9dc28e95-6434-11ea-a666-42010a9c0058)": timeout expired waiting for volumes to attach or mount for pod "default"/"ubuntu-deployment-2q64z". list of unmounted volumes=[volume]. list of unattached volumes=[volume default-token-dnvnj]

Pod cannot pass ContainerCreating state because of failed mounting of a volume .由于volume安装失败,Pod 无法通过ContainerCreating状态。 Mentioned volume is already used by other pods on a different node.提到的volume已被其他节点上的其他 pod 使用。

ReadWriteOnce: The Volume can be mounted as read-write by a single node. ReadWriteOnce:卷可以由单个节点以读写方式挂载。

Additional links附加链接

Please take a look at: Cloud.google.com: Access modes of persistent volumes .请查看: Cloud.google.com:持久卷的访问模式

There is detailed answer on topic of access mode: Stackoverflow.com: Why can you set multiple accessmodes on a persistent volume有关于访问模式主题的详细答案: Stackoverflow.com: Why can you set multiple accessmodes on a persistent volume

As it's unknown what you are trying to achieve please take a look on comparison between Deployments and Statefulsets: Cloud.google.com: Persistent Volume: Deployments vs statefulsets .由于不知道您要实现什么,请查看 Deployments 和 Statefulsets 之间的比较: Cloud.google.com: Persistent Volume: Deployments vs statefulsets

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM