Stateful sets are similar to deployments, they can scale up and scale down, they can perform rolling updates etc. All most it performs similar functions like replica sets and deployment sets. but there some difference as well, in stateful sets pods are created in a sequential order, that means when the pods are deployed, 1st pod should be in running and ready state after that new pod will be created to match the desired replicas. So that makes our life easy to understand which pod is created 1st and coming pods are cloned out of it. Stateful sets assign a sequential ordinal index to each pod.
Numbers will be assigned to each pod starting from 0 to n. by this each pod will get a unique name by combining the stateful set name and ordinal index number. For example, if your creating stateful set with the name mongo-db then 1st pod will be mongodb-0 and next will be mongodb-1 n mongodb-2 and so that no more random names for the pods. even if the mongodb-0 terminated, new pod will be replicated with the same name. so that we can relay on pod names for future purposes, with that continuous replication is also possible.
It’s not mandatory that you always need a stateful set, its depend on what kind of application you are deploying, for example a application that doesn’t care about networking and it doesn’t need permanent storage like Nginx, apache, tomcat these type of application don’t need to be stateful sets , they are called stateless application, so first try to evaluate client needs and requirements and suggest the stateful sets.
Creation of stateful set
Creation of stateful set through declarative approach is as simple as creating a deployment. All the configuration strings are same except kind and two additional strings. YAML for stateful set is as follows
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: mongo-h replicas: 2 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - name: mongo-container image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 name: mongo
the only difference when compare with the deployment yaml are kind set to stateful set and you must specify the name of headless service which is mongo-h
I will be giving a new blog on headless service with details including screenshots of hands-on, so that you will get clear picture. This is the YAML to create a headless service, this is as similar as creating a normal service, only thing you will change here is setting ClusterIP to none.
apiVersion: v1 kind: Service metadata: name: mongo-h spec: clusterIP: None # <-- Don't forget!! selector: app: api ports: - protocol: TCP port: 80 targetPort: 3000
volume management in stateful sets
we know that with persistent volumes and volumes claim objects in Kubernetes and will use claims in pod definition files, that is simple in using single volume with single claim and using that claim in pod definition file. Even multiple pods can read and write into a shared volume based on type of the volume they are using what if each pod needs its own data , for that dynamic provisioning of volumes is needed, to do that instead of creating a volume claim template manually and using that in a stateful set definition file, move that entire definition of claim right from metadata into the stateful set definition under volume claim templates , since it is an array you can specify multiple claim templates here. With that we can create stable storage for the particular pods. complete YAMl looks as below
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: mongo-h replicas: 2 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - name: mongo-container image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 name: mongo volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
I will be writing a new blog on volume management in Kubernetes, with that you will understand better this stateful sets and dynamic provisioning of volumes as well