others-how to solve 'error validating data: ValidationError(Deployment.spec): unknown field volumeClaimTemplates in io.k8s.api.apps.v1.DeploymentSpec ' error?
Problem
When we install application in kubernetes(k8s), sometimes, we get the following error:
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:
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
Environment
-
Docker: Server Version: 19.03.13
-
Kubectl version
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
volumeClaimTemplates can ONLY be used in StatefulSets
-
Deployment - PersistentVolumeClaim is shared by all pod replicas. In other words, shared volume.
-
StatefulSet - You specify a volumeClaimTemplates so that each replica pod gets a unique PersistentVolumeClaim associated with it. In other words, no shared volume.
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:
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