Skip to content

k8s

1 post with the tag ā€œk8sā€

How to solve ValidationError(Deployment.spec): unknown field volumeClaimTemplates error?

Problem

When we install application in kubernetes(k8s), sometimes, we get the following error:

Terminal window
root@launch-advisor:~# kubectl apply -f deployment-redis.yaml
error: error validating "deployment-redis.yaml": error validating data: ValidationError(Deployment.spec): unknown field "volumeClaimTemplates" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false

The content of deployment-redis.yaml is:

deployment-redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: ns-bswen
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:6.0.9
ports:
- containerPort: 6379
command: ["redis-server", "/etc/redis/redis.conf"]
volumeMounts:
- name: "redis-conf"
mountPath: /etc/redis/redis.conf
subPath: redis_conf
- name: "redis-data"
mountPath: "/var/lib/redis"
volumes:
- name: "redis-conf"
configMap:
name: "redis"
- name: "redis-data"
persistentVolumeClaim:
claimName: redis-pvc
volumeClaimTemplates:
- metadata:
name: redis-pvc
annotations:
volume.beta.kubernetes.io/storage-class: "my-nfs-storage"
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Mi

Notice that the above yaml is using the kubernetes resource type Deployment.

Environment

  • Docker: Server Version: 19.03.13

  • Kubectl version

    Terminal window
    Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-13T18:06:54Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"darwin/amd64"}
    Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.6", GitCommit:"dff82dc0de47299ab66c83c626e08b245ab19037", GitTreeState:"clean", BuildDate:"2020-07-15T16:51:04Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}

Reason

In Kubernetes (K8s), volumeClaimTemplates is a resource template used within StatefulSets to dynamically create persistent storage volumes (Persistent Volumes, PVs). VolumeClaimTemplates allow each Pod within a StatefulSet to have its own independent persistent storage, and PVCs (Persistent Volume Claims) corresponding to them can be automatically created through the template.

The role of volumeClaimTemplates:

  • Automate PVC creation: VolumeClaimTemplates enable you to automatically create PVCs for each Pod in a StatefulSet without manually configuring a PVC for each Pod. This is particularly useful for applications that require each Pod to have its own independent storage.
  • Ensure persistent storage: StatefulSets are primarily used for stateful applications (such as databases, distributed systems, etc.), which require ensuring that storage is not lost in cases of Pod restarts, migrations, etc. With volumeClaimTemplates, each Pod has its own PVC and mounted PV, ensuring data persistence.
  • Automatic binding of Persistent Volume (PV): Kubernetes automatically creates PVCs based on volumeClaimTemplates, and these PVCs are automatically bound to a suitable PV. This means that users do not need to manually manage the relationship between PVCs and PVs; Kubernetes automatically selects the appropriate PV based on storage resources and configured StorageClass.
  • Templated storage configuration: When using volumeClaimTemplates, you can define a template for PVCs (such as storage size, storage class, etc.), and Kubernetes will create corresponding PVCs for each Pod. This ensures that all Pods use the same storage configuration without the need to define storage details for each Pod individually.

But,

StatefulSet is useful for running things in cluster e.g Hadoop cluster, MySQL cluster, where each node has its own storage.

Solution

You can switch from Deployment to StatefulSet as follows:

deployment-redis.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: ns-bswen
labels:
app: redis
spec:
serviceName: redis
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:6.0.9
ports:
- containerPort: 6379
command: ["redis-server", "/etc/redis/redis.conf"]
volumeMounts:
- name: "redis-conf"
mountPath: /etc/redis/redis.conf
subPath: redis_conf
- name: "redis-data"
mountPath: "/var/lib/redis"
volumes:
- name: "redis-conf"
configMap:
name: "redis"
- name: "redis-data"
persistentVolumeClaim:
claimName: redis-pvc
volumeClaimTemplates:
- metadata:
name: redis-pvc
annotations:
volume.beta.kubernetes.io/storage-class: "my-nfs-storage"
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Mi