Kubernetes Learning Part V
Table of content
- Introduction
- StatefulSets
- Usecase for choosing StatefulSet
- What makes a StatefulSet config
- How to deploy a StatefulSet
- Deploy Database using Kubectl command
- Verify Deployed Database
- Notable other details
- Conclusion
- Further Reference
Introduction
- This is article is In this blog, we will continue discuss  Workload Resource-StatefulSets
- Topics and definitions are hand picked from Kubernetes documentation for the purpose of learning.
- This blog is part of the Kubernetes Learning series
StatefulSets
- StatefulSet helps to create/manage one or more related Pods that requires to track the state of the Pods
- For example, if any workload needs to store data persistently, then we can run it as a StatefulSet that matches each Pod with a PersistentVolume.
- Our code, running in the Pods for that StatefulSet, can replicate data to other Pods in the same StatefulSet to improve overall resilience.
Usecase for choosing StatefulSet
- Major use case of StatefulSet is, If we want to use storage volumes to provide persistence for our workload, a StatefulSet can be chosen.
- Even though individual Pods in a StatefulSet is failed, the persistent Pod identifiers make it easier to match existing volumes to the new Pods, that replace any pods that have failed earlier.
- As mentioned in the docs,
StatefulSets are valuable for applications that require one or more of the following.
- Stable, unique network identifiers.
- Stable, persistent storage.
- Ordered, graceful deployment and scaling.
- Ordered, automated rolling updates.
What makes a StatefulSet config
- There are few important concepts we need to know, for creating StatefulSet
- Persistent volume - Storage definition, A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes.
- Persistent volume claim - Storage definition identifier request by user. It is similar to a Pod. Pods consume node resources and PVCs consume PV resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes. As we discussed earlier, StatefulSet is suitable for apps with persistent storage. So we need to have config defined for Persistent volume and Persistent volume claim. Refer the persistent-volumes docs for more details
 
- Also we require below configs as well,
- Service config - Definition of application service
- StatefulSet config - Definition of application deployment
 
How to deploy a StatefulSet
- Let us now try to create a MySqldatabase using theStatefulSetconfiguration
Step 1 Define Database Storage as Persistent volume
- Create config for PV and PVC for DB storage
- We create a PVC requesting 20gig of storage and hence the PV creates a storage for 20gig of storage in the cluster
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
Step 2 Define Database Creds as Secret
- Create config mysqldatabase,usernameandpasswordas secret
- Below example shows the creation of credentials using secretconfig, using thebase64encoded string
- For the purpose of demo, it is not recommended to expose username and password in config yamls, it is recommended to integrate secret management tools for this purpose.
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-password
type: Opaque
# Run `echo -n 'admin' | base64` to get the base64 encoded value
data:
  password: YWRtaW4=
  user: YWRtaW4K
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-user
type: Opaque
# Run `echo -n 'admin' | base64` to get the base64 encoded value
data:
  user: YWRtaW4K
Step 3 Define Database Service
- We are creating a service that configures port 3306 as portandtargetPort
- What is the difference between port and targetPort
- Applications running inside the
 
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
    - name: mysql-ports
      port: 3306
      targetPort: 3306
  selector:
    app: mysql
  clusterIP: None
Step 4 Define StatefulSet for Database deployment
In the below example:
- The StatefulSet, named mysql, has a Spec that indicates that 2 replicas of themysqlcontainer will be launched in Pods.
- The volumessection of config will provide stable storage usingPersistentVolumesprovisioned by a PersistentVolume Provisioner.
- Pod Selector should match with the .spec.selectorfield of a StatefulSet to match the labels of its.spec.template.metadata.labels. Failing to specify a matching Pod Selector will result in a validation error during StatefulSet creation.
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 2
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.7
          name: mysql
          env:
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: mysql-user
                  key: user
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: password
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: password
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pv-claim
Deploy Database using Kubectl command
- Let us now execute kubectlcommand and see what is created
- First execute the PV and PVC to create storage config
$ kubectl apply -f mysql_pv_pvc.yml 
persistentvolume/mysql-pv-volume created
persistentvolumeclaim/mysql-pv-claim created
- Then execute stateful set creation config for database
$ kubectl apply -f mysql_statefulset_app.yml 
secret/mysql-password created
secret/mysql-user created
service/mysql created
statefulset.apps/mysql created
- We can also check the deployed pods using the command below,
$ kubectl get pods
NAME                          READY   STATUS    RESTARTS        AGE
mysql-0                       1/1     Running   0               11s
mysql-1                       1/1     Running   0               10s
- Since we deployed the pods in default namespace, we can use the get podscommand without any namespaces
Pod Replica Behavior
- It shows the 2 replicas of mysqlpods. In case if any healthy replica is failed, replica config make sure that, it spins up new pods and terminating other
Verify Deployed Database
- We can test the deployed database server by running a MySQL client to connect to the server
- This command creates a new Pod in the cluster running a MySQL client and connects it to the server through the Service.
$ kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -padmin
- If it connects, we can see the mysql>prompt. This shows our stateful MySQL database is up and running.
If you don't see a command prompt, try pressing enter.
mysql> 
Notable other details
Deployment and Scaling Guarantees
For a StatefulSet with N replicas, 
- When Pods are being deployed, they are created sequentially, in order from {0..N-1}.
- When Pods are being deleted, they are terminated in reverse order, from {N-1..0}.
- Before a scaling operation is applied to a Pod, all of its predecessors must be Running and Ready.
- Before a Pod is terminated, all of its successors must be completely shutdown.
Update strategies
- A StatefulSet's .spec.updateStrategyfield allows you to configure and disable automated rolling updates for containers, labels, resource request/limits, and annotations for the Pods in aStatefulSet. There are two possible values:
- OnDelete
When a StatefulSet's .spec.updateStrategy.typeis set to OnDelete, the StatefulSet controller will not automatically update the Pods in a StatefulSet. Users must manually delete Pods to cause the controller to create new Pods
- RollingUpdate
The RollingUpdateupdate strategy implements automated, rolling update for the Pods in a StatefulSet. This is thedefault update strategy.
Conclusion
Hope this article is helpful to people getting started with kubernetes concepts on StatefulSets
Thanks for reading!
Further Reference
Workload Resources
StatefulSet
Persistent Volumes
Configure Persistent Volumes
Basics of StatefulSet
https://kubernetes.io/docs/concepts/workloads/
Full Source of Tutorial
- The full source code can be accessible in this GitHub repo
 
 
              
 
                       
    
Top comments (0)