Keywords: Kubernetes | PersistentVolumeClaim | StorageClassName
Abstract: This article provides an in-depth analysis of the common causes for PersistentVolumeClaim (PVC) remaining indefinitely in Pending state in Kubernetes, focusing on the matching failure due to default value differences in the storageClassName field. Through detailed YAML configuration examples and step-by-step explanations, the article demonstrates how to properly configure PersistentVolume (PV) and PVC to achieve read-only data sharing across multiple pods on different nodes, offering complete solutions and best practice recommendations.
Problem Phenomenon and Background
When deploying applications requiring persistent storage in Kubernetes clusters, developers often encounter situations where PersistentVolumeClaim (PVC) remains stuck in Pending state. This typically occurs when attempting to mount pre-configured persistent disks (such as Google Compute Engine persistent disks) to multiple pods. In the user-provided case, the PV was successfully created and showed as Available, but the corresponding PVC failed to bind, remaining indefinitely in Pending state.
Core Problem Analysis
Through in-depth analysis of PV and PVC configurations, the root cause can be identified as the default value difference in the storageClassName field. In Kubernetes design, when PersistentVolumeClaim does not explicitly specify storageClassName, it defaults to using standard as the storage class name. However, when creating a PersistentVolume, the storageClassName field has no default value; if not explicitly set, this field remains empty.
This inconsistency in default values prevents the PVC's selector from correctly matching the PV. Even though the PVC specifies label matching conditions through selector.matchLabels, the binding process still fails due to storage class name mismatch. Below is a simplified representation of the problematic configuration:
# PV Configuration (Problematic Version)
kind: PersistentVolume
apiVersion: v1
metadata:
name: models-1-0-0
labels:
name: models-1-0-0
spec:
capacity:
storage: 200Gi
# storageClassName field missing
accessModes:
- ReadOnlyMany
gcePersistentDisk:
pdName: models-1-0-0
fsType: ext4
readOnly: true
# PVC Configuration
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: models-1-0-0-claim
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 200Gi
selector:
matchLabels:
name: models-1-0-0
# Implicitly uses storageClassName: standard
Solution
To resolve this issue, the storageClassName field must be explicitly set in the PersistentVolume configuration, ensuring its value matches the PVC's storage class name. Below is the corrected configuration example:
# PV Configuration (Corrected Version)
kind: PersistentVolume
apiVersion: v1
metadata:
name: models-1-0-0
labels:
name: models-1-0-0
spec:
capacity:
storage: 200Gi
storageClassName: standard # Explicitly set storage class name
accessModes:
- ReadOnlyMany
gcePersistentDisk:
pdName: models-1-0-0
fsType: ext4
readOnly: true
---
# PVC Configuration remains unchanged
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: models-1-0-0-claim
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 200Gi
selector:
matchLabels:
name: models-1-0-0
With this configuration, the PVC can correctly match the PV with the same storage class name, allowing the binding process to proceed smoothly. In actual deployments, it is recommended to always explicitly specify the storageClassName field to avoid issues caused by default value differences.
Technical Details and Best Practices
1. Storage Class Name Matching Mechanism: When binding PVC and PV, Kubernetes checks both the storage class name and label selector. Binding succeeds only when both match. If the storage class names don't match, the PVC remains in Pending state even if labels match.
2. Implementation of Cross-Node Read-Only Access: Using the ReadOnlyMany access mode combined with GCE persistent disks does enable multiple pods across different nodes to simultaneously read from the same data volume. This configuration is suitable for scenarios requiring shared static data, such as machine learning models or configuration files.
3. Configuration Verification Steps:
- Use
kubectl get pvto check PV status and storage class name - Use
kubectl get pvcto view detailed PVC status information - Obtain specific reasons for binding failure via
kubectl describe pvc <claim-name>
4. Preventive Measures:
- Always explicitly specify
storageClassNamein both PV and PVC configurations - Use consistent naming conventions and labeling strategies
- Implement configuration validation and testing procedures in production environments
Conclusion
PersistentVolumeClaim remaining indefinitely in Pending state is typically caused by storage configuration mismatches, particularly due to default value differences in the storageClassName field. By explicitly setting storage class names and ensuring consistency between PV and PVC configurations, this issue can be effectively resolved. The solution provided in this article applies not only to GCE persistent disks but also to other types of storage backends, offering universal reference value.