我在单个节点上安装了一个新的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"}
答案 0 :(得分:4)
应用程序正在等待Pod,而Pod正在等待PersistentVolume
到PersistentVolumeClaim
之间。
但是,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} }。此值是不可变的,因此您必须:
获取存储类yaml:
WaitForFirstConsumer
,或者您也可以只复制the docs here中的示例(确保元数据名称匹配)。这是我配置的:
Immediate
并删除旧的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 也阻止了初始化,我不得不用部署替换它
这真是一个令人头疼的问题