kubernetes go-client PersistentVolumeClaim 未按要求提供,卡在 Pending 状态
kubernetes go-client PersistentVolumeClaim not provisioned on request, stuck in Pending state
在我使用 api.PersistentVolumeClaims(namespace).Create(createOpts)
调用后使用 go-client API 时,PersistentVolumeClaim 显示为资源,但仍处于 Pending 状态。使用 kubectl describe pvc
时我没有看到任何事件,我也没有看到正在创建任何卷等
$ kubectl describe pvc --namespace=test -R
Name: 93007732-9d8c-406e-be99-f48faed3a061
Namespace: test
StorageClass: microk8s-hostpath
Status: Pending
Volume: 93007732-9d8c-406e-be99-f48faed3a061
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 0
Access Modes:
VolumeMode: Filesystem
Events: <none>
Mounted By: <none>
我使用的代码如下:
volume, errGo := uuid.NewRandom()
if errGo != nil {
job.failed = kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())
return job.failed
}
job.volume = volume.String()
fs := v1.PersistentVolumeFilesystem
createOpts := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: job.volume,
Namespace: job.namespace,
UID: types.UID(job.volume),
},
Spec: v1.PersistentVolumeClaimSpec{
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
},
},
VolumeName: job.volume,
VolumeMode: &fs,
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
Capacity: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
},
},
}
api := Client().CoreV1()
if _, errGo = api.PersistentVolumeClaims(namespace).Create(createOpts); errGo != nil {
job.failed = kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())
return job.failed
}
我试图找到将 Create API 与持久卷一起使用的好示例,但大多数示例似乎是针对观察者等的,因此我花了相当长的时间尝试对代码进行逆向工程,导致我明确设置 Status
但这似乎影响为零。我还尝试在规范中默认设置 VolumeMode,但没有帮助。
我看过的例子来自:
https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/volume/persistentvolume/framework_test.go
https://godoc.org/k8s.io/api/core/v1#PersistentVolumeSpec
https://github.com/vladimirvivien/k8s-client-examples/tree/master/go/pvcwatch
https://medium.com/programming-kubernetes/building-stuff-with-the-kubernetes-api-part-4-using-go-b1d0e3c1c899
有没有人知道这些 API 的实际示例代码超出了 _test.go 文件中的单元测试范围,或者任何人都可以提供任何关于如何使创建过程实际运行的提示在集群内?我假设当我尝试创建 Claim 资源时,所需的下游资源(例如 Volume 等)会自动配置。
非常感谢您看到这里...
您在代码中所做的看起来是正确的。但是,看起来您的 PVC 找不到匹配的 PV 来绑定在一起。
您似乎在使用 hostPath
PV (with a storage class) that doesn't support dynamic provisioning. Also, documented here。
因此您很可能必须创建一个 hostPath PV,以便您的 PVC 可以绑定到它。该卷的大小必须等于或大于您在 PVC 中请求的大小。
另一种选择是使用支持不同于 hostPath 的动态配置的 Local 卷。
您可以通过查看 K8s 控制平面领导者上的 kube-controller-manager 日志来调试 PVC/PV 的动态配置和绑定。
在我使用 api.PersistentVolumeClaims(namespace).Create(createOpts)
调用后使用 go-client API 时,PersistentVolumeClaim 显示为资源,但仍处于 Pending 状态。使用 kubectl describe pvc
时我没有看到任何事件,我也没有看到正在创建任何卷等
$ kubectl describe pvc --namespace=test -R
Name: 93007732-9d8c-406e-be99-f48faed3a061
Namespace: test
StorageClass: microk8s-hostpath
Status: Pending
Volume: 93007732-9d8c-406e-be99-f48faed3a061
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 0
Access Modes:
VolumeMode: Filesystem
Events: <none>
Mounted By: <none>
我使用的代码如下:
volume, errGo := uuid.NewRandom()
if errGo != nil {
job.failed = kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())
return job.failed
}
job.volume = volume.String()
fs := v1.PersistentVolumeFilesystem
createOpts := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: job.volume,
Namespace: job.namespace,
UID: types.UID(job.volume),
},
Spec: v1.PersistentVolumeClaimSpec{
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
},
},
VolumeName: job.volume,
VolumeMode: &fs,
},
Status: v1.PersistentVolumeClaimStatus{
Phase: v1.ClaimBound,
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
Capacity: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10Gi"),
},
},
}
api := Client().CoreV1()
if _, errGo = api.PersistentVolumeClaims(namespace).Create(createOpts); errGo != nil {
job.failed = kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime())
return job.failed
}
我试图找到将 Create API 与持久卷一起使用的好示例,但大多数示例似乎是针对观察者等的,因此我花了相当长的时间尝试对代码进行逆向工程,导致我明确设置 Status
但这似乎影响为零。我还尝试在规范中默认设置 VolumeMode,但没有帮助。
我看过的例子来自:
https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/volume/persistentvolume/framework_test.go
https://godoc.org/k8s.io/api/core/v1#PersistentVolumeSpec
https://github.com/vladimirvivien/k8s-client-examples/tree/master/go/pvcwatch
https://medium.com/programming-kubernetes/building-stuff-with-the-kubernetes-api-part-4-using-go-b1d0e3c1c899
有没有人知道这些 API 的实际示例代码超出了 _test.go 文件中的单元测试范围,或者任何人都可以提供任何关于如何使创建过程实际运行的提示在集群内?我假设当我尝试创建 Claim 资源时,所需的下游资源(例如 Volume 等)会自动配置。
非常感谢您看到这里...
您在代码中所做的看起来是正确的。但是,看起来您的 PVC 找不到匹配的 PV 来绑定在一起。
您似乎在使用 hostPath
PV (with a storage class) that doesn't support dynamic provisioning. Also, documented here。
因此您很可能必须创建一个 hostPath PV,以便您的 PVC 可以绑定到它。该卷的大小必须等于或大于您在 PVC 中请求的大小。
另一种选择是使用支持不同于 hostPath 的动态配置的 Local 卷。
您可以通过查看 K8s 控制平面领导者上的 kube-controller-manager 日志来调试 PVC/PV 的动态配置和绑定。