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
MySql
database using theStatefulSet
configuration
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
mysql
database,username
andpassword
as secret - Below example shows the creation of credentials using
secret
config, using thebase64
encoded 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
port
andtargetPort
- 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 themysql
container will be launched in Pods. - The
volumes
section of config will provide stable storage usingPersistentVolumes
provisioned by a PersistentVolume Provisioner. - Pod Selector should match with the
.spec.selector
field 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
kubectl
command 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 pods
command without any namespaces
Pod Replica Behavior
- It shows the 2 replicas of
mysql
pods. 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.updateStrategy
field 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.type
is 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
RollingUpdate
update 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