WaitForFirstConsumer PersistentVolumeClaim等待绑定之前创建第一个使用者

时间:2019-03-07 13:04:25

标签: kubernetes persistent-volumes

我在单个节点上安装了一个新的k8s,这很麻烦。但是,当我尝试创建简单的PostgreSQL时,无法成功创建PersistentVolume

下面有一些详细信息。


StorageClass是从官方页面上复制的:https://kubernetes.io/docs/concepts/storage/storage-classes/#local

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

StatefulSet是:

kind: StatefulSet
apiVersion: apps/v1beta1
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 1
  ...
  volumeClaimTemplates:
    - metadata:
        name: postgres-data
      spec:
        storageClassName: local-storage
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi

关于正在运行的StorageClass

$ kubectl describe storageclasses.storage.k8s.io
Name:            local-storage
IsDefaultClass:  No
Annotations:     kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{},"name":"local-storage"},"provisioner":"kubernetes.io/no-provisioner","volumeBindingMode":"WaitForFirstConsumer"}

Provisioner:           kubernetes.io/no-provisioner
Parameters:            <none>
AllowVolumeExpansion:  <unset>
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     WaitForFirstConsumer
Events:                <none>

关于正在运行的PersistentVolumeClaim

$ kubectl describe pvc
Name:          postgres-data-postgres-0
Namespace:     default
StorageClass:  local-storage
Status:        Pending
Volume:
Labels:        app=postgres
Annotations:   <none>
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode:    Filesystem
Events:
  Type       Reason                Age                            From                         Message
  ----       ------                ----                           ----                         -------
  Normal     WaitForFirstConsumer  <invalid> (x2 over <invalid>)  persistentvolume-controller  waiting for first consumer to be created before binding

K8s版本:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.4", GitCommit:"c27b913fddd1a6c480c229191a087698aa92f0b1", GitTreeState:"clean", BuildDate:"2019-02-28T13:37:52Z", GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.1", GitCommit:"eec55b9ba98609a46fee712359c7b5b365bdd920", GitTreeState:"clean", BuildDate:"2018-12-13T10:31:33Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}

6 个答案:

答案 0 :(得分:4)

应用程序正在等待Pod,而Pod正在等待PersistentVolumePersistentVolumeClaim之间。 但是,PersistentVolume应该由用户在使用前准备。

我以前的YAML缺少这样的PersistentVolume

kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-data
  labels:
    type: local
spec:
  storageClassName: local-storage
  capacity:
    storage: 1Gi
  local:
    path: /data/postgres
  persistentVolumeReclaimPolicy: Retain
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
          - key: app
            operator: In
            values:
              - postgres

使用前应准备好本地路径/data/postgres。 Kubernetes不会自动创建它。

答案 1 :(得分:2)

我自己碰到了这个问题,被彻底抛出一个循环,直到我意识到StorageClass的{​​{1}}设置为VolumeBindingMode代替了我的{{1} }。此值是不可变的,因此您必须:

  1. 获取存储类yaml:

    WaitForFirstConsumer

    ,或者您也可以只复制the docs here中的示例(确保元数据名称匹配)。这是我配置的:

    Immediate
  2. 并删除旧的kubectl get storageclasses.storage.k8s.io gp2 -o yaml > gp2.yaml ,然后使用新的apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: gp2 provisioner: kubernetes.io/aws-ebs parameters: type: gp2 reclaimPolicy: Delete allowVolumeExpansion: true mountOptions: - debug volumeBindingMode: Immediate 设置为StorageClass重新创建它。

注意:EKS客户端可能需要perms才能创建EBS或EFS之类的云资源。假设您使用EBS,volumeBindingMode应该不错。

完成此操作后,创建和使用dynamically provisioned PVs应该没有问题。

答案 2 :(得分:0)

接受的答案对我不起作用。我认为这是因为在部署 StatefulSet Pods 之前不会设置应用程序密钥,这会阻止 PersistentVolumeClaim 匹配< em> nodeSelector (防止 Pods 以错误didn't find available persistent volumes to bind.开头)。为了解决此僵局,我为每个节点定义了一个 PersistentVolume (这可能不是理想的方法,但它确实有效):

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-data-node1
  labels:
    type: local
spec:
[…]
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node1

答案 3 :(得分:0)

对我来说,问题是 PV 和 PVC 中的 accessModes 字段不匹配。 PVC 请求 RWX/ReadWriteMany 而 PV 提供 RWO/ReadWriteOnce

答案 4 :(得分:0)

waitforfirstconsumer-persistentvolumeclaim 即需要此 PVC 的 POD 未安排。描述豆荚可能会提供更多线索。在我的情况下,节点无法安排此 POD,因为节点中的 pod 限制为 110,并且部署超出了它。希望它有助于更​​快地识别问题。增加pod限制,在node中重启kubelet即可解决。

答案 5 :(得分:0)

就我而言,我有 claimRef 没有指定的命名空间。
正确的语法是:

  claimRef:
    namespace: default
    name: my-claim

StatefulSet 也阻止了初始化,我不得不用部署替换它
这真是一个令人头疼的问题