How to Deploy a Stateful Application using Kubernetes? – KubeLabs Glossary

StatefulSet is a Kubernetes controller that is used to manage and maintain one or more Pods. However, so do other controllers like ReplicaSets and, the more robust, Deployments. So what does Kubernetes use StatefulSets for? To answer this question, we need to discuss stateless versus stateful applications.

A stateless application is one that does not care which network it is using, and it does not need permanent storage. Examples of stateless apps may include web servers (Apache, NginX, or Tomcat).

On the other hand, we have stateful apps. Let’s say you have a Solr database cluster that is managed by several Zookeeper instances. For such an application to function correctly, each Solr instance must be aware of the Zookeeper instances that are controlling it. Similarly, the Zookeeper instances themselves establish connections between each other to elect a master node. Due to such a design, Solr clusters are an example of stateful applications. If you deploy Zookeeper on Kubernetes, you’ll need to ensure that pods can reach each other through a unique identity that does not change (hostnames, IPs…etc.). Other examples of stateful applications include MySQL clusters, Redis, Kafka, MongoDB, and others.

Given this difference, Deployment is more suited to work with stateless applications. As far as a Deployment is concerned, Pods are interchangeable. While a StatefulSet keeps a unique identity for each Pod it manages. It uses the same identity whenever it needs to reschedule those Pods.

Exposing a StatefulSet

A Kubernetes Service acts as an abstraction layer. In a stateless application like an Nginx web server, the client does not (and should not) care which pod receives a response to the request. The connection reaches the Service, and it routes it to any backend pod. This is not the case in stateful apps. In the above diagram, a Solr pod may need to reach the Zookeeper master, not any pod. For this reason, part of the Statefulset definition entails a Headless Service. A Headless Service does not contain a ClusterIP. Instead, it creates several Endpoints that are used to produce DNS records. Each DNS record is bound to a pod. All of this is done internally by Kubernetes, but it’s good to have an idea about how it does it.

Deploying a Stateful Application Using Kubernetes Statefulset

If you look at web_stateful.yaml file, you will find a snippet around how we are deploying a stateful application. For simplicity, are we using Nginx as the pod image. The deployment is made up of 2 Nginx web servers; both of them are connected to a persistent volume. For example, look at web_stateful.yaml file under the current location.

Before we start discussing the details of this definition, notice that the file actually contains two definitions: the storage class that the StatefulSet is using and the StatefulSet itself.

Storage Class

Storage classes are Kubernetes objects that let the users specify which type of storage they need from the cloud provider. Different storage classes represent various service quality, such as disk latency and throughput, and are selected depending on the scenario they are used for and the cloud provider’s support. Persistent Volumes and Persistent Volume Claims use Storage Classes.

Persistent Volumes and Persistent Volume Claims

Persistent volumes act as an abstraction layer to save the user from going into the details of how storage is managed and provisioned by each cloud provider (in this example, we are using Google GCE). By definition, StatefulSets are the most frequent users of Persistent Volumes since they need permanent storage for their pods.

A Persistent Volume Claim is a request to use a Persistent Volume. If we are to use the Pods and Nodes analogy, then consider Persistent Volumes as the “nodes” and Persistent Volume Claims as the “pods” that use the node resources. The resources we are talking about here are storage properties, such as storage size, latency, throughput, etc.

Under this tutorial, we will see example of NFS server.

Deploying NFS Server

NFS is a protocol that allows nodes to read/write data over a network. The protocol works by having a master node running the NFS daemon and stores the data. This master node makes certain directories available over the network.

Clients access the masters shared via drive mounts. From the viewpoint of applications, they are writing to the local disk. Under the covers, the NFS protocol writes it to the master.

In this scenario, and for demonstration and learning purposes, the role of the NFS Server is handled by a customised container. The container makes directories available via NFS and stores the data inside the container. In production, it is recommended to configure a dedicated NFS Server.

Start the NFS using the command:

docker run -d --net=host     --privileged --name nfs-server     katacoda/contained-nfs-server:centos7     /exports/data-0001 /exports/data-0002 

The NFS server exposes two directories, data-0001 and data-0002. In the next steps, this is used to store data.

Deploying Persistent Volume

For Kubernetes to understand the available NFS shares, it requires a PersistentVolume configuration. The PersistentVolume supports different protocols for storing data, such as AWS EBS volumes, GCE storage, OpenStack Cinder, Glusterfs and NFS. The configuration provides an abstraction between storage and API allowing for a consistent experience.

In the case of NFS, one PersistentVolume relates to one NFS directory. When a container has finished with the volume, the data can either be Retained for future use or the volume can be Recycled meaning all the data is deleted. The policy is defined by the persistentVolumeReclaimPolicy option.

Spec File:

apiVersion: v1 kind: PersistentVolume metadata:   name:  spec:   capacity:     storage: 1Gi   accessModes:     - ReadWriteOnce     - ReadWriteMany   persistentVolumeReclaimPolicy: Recycle   nfs:     server:      path:  

The spec defines additional metadata about the persistent volume, including how much space is available and if it has read/write access.

Task

Create two new PersistentVolume definitions to point at the two available NFS shares.

kubectl create -f nfs-0001.yaml 
kubectl create -f nfs-0002.yaml 

View the contents of the files using cat nfs-0001.yaml nfs-0002.yaml

Once created, view all PersistentVolumes in the cluster using kubectl get pv

Deploying Persistent Volume Claim

Once a Persistent Volume is available, applications can claim the volume for their use. The claim is designed to stop applications accidentally writing to the same volume and causing conflicts and data corruption.

The claim specifies the requirements for a volume. This includes read/write access and storage space required. An example is as follows:

kind: PersistentVolumeClaim apiVersion: v1 metadata:   name: claim-mysql spec:   accessModes:     - ReadWriteOnce   resources:     requests:       storage: 3Gi 

Task

Create two claims for two different applications. A MySQL Pod will use one claim, the other used by an HTTP server.

kubectl create -f pvc-mysql.yaml 
kubectl create -f pvc-http.yaml 

View the contents of the files using cat pvc-mysql.yaml pvc-http.yaml

Once created, view all PersistentVolumesClaims in the cluster using

kubectl get pvc. 

The claim will output which Volume the claim is mapped to claim.

Using Volume

When a deployment is defined, it can assign itself to a previous claim. The following snippet defines a volume mount for the directory /var/lib/mysql/data which is mapped to the storage mysql-persistent-storage. The storage called mysql-persistent-storage is mapped to the claim called claim-mysql.

 spec:       volumeMounts:         - name: mysql-persistent-storage           mountPath: /var/lib/mysql/data   volumes:     - name: mysql-persistent-storage       persistentVolumeClaim:         claimName: claim-mysql          

Task

Launch two new Pods with Persistent Volume Claims. Volumes are mapped to the correct directory when the Pods start allowing applications to read/write as if it was a local directory.

kubectl create -f pod-mysql.yaml 
kubectl create -f pod-www.yaml 

Use the command below to view the definition of the Pods.

cat pod-mysql.yaml pod-www.yaml 

You can see the status of the Pods starting using

kubectl get pods 

If a Persistent Volume Claim is not assigned to a Persistent Volume, then the Pod will be in Pending mode until it becomes available. In the next step, we’ll read/write data to the volume.

Read/Write Data

tore all database changes to the NFS Server while the HTTP Server will serve static from the NFS drive. When upgrading, restarting or moving containers to a different machine the data will still be accessible.

To test the HTTP server, write a ‘Hello World’ index.html homepage. In this scenario, we know the HTTP directory will be based on data-0001 as the volume definition hasn’t driven enough space to satisfy the MySQL size requirement.

docker exec -it nfs-server bash -c "echo 'Hello World' > /exports/data-0001/index.html" 

Based on the IP of the Pod, when accessing the Pod, it should return the expected response.

ip=$(kubectl get pod www -o yaml |grep podIP | awk '{split($0,a,":"); print a[2]}'); echo $ip 
curl $ip 

Update Data

When the data on the NFS share changes, then the Pod will read the newly updated data.

docker exec -it nfs-server bash -c "echo 'Hello NFS World' > /exports/data-0001/index.html" 
curl $ip 

Recreate Pod

Because a remote NFS server stores the data, if the Pod or the Host were to go down, then the data will still be available.

Task

Deleting a Pod will cause it to remove claims to any persistent volumes. New Pods can pick up and re-use the NFS share.

kubectl delete pod www 
kubectl create -f pod-www2.yaml 
ip=$(kubectl get pod www2 -o yaml |grep podIP | awk '{split($0,a,":"); print a[2]}'); curl $ip 

The applications now use a remote NFS for their data storage. Depending on requirements, this same approach works with other storage engines such as GlusterFS, AWS EBS, GCE storage or OpenStack Cinder.

Please follow and like us:
1

46 thoughts on “How to Deploy a Stateful Application using Kubernetes? – KubeLabs Glossary

  1. Greetings from Ohio! I’m bored to death at work so I decided to browse your blog on my iphone during lunch break. I enjoy the knowledge you provide here and can’t wait to take a look when I get home. I’m surprised at how quick your blog loaded on my phone .. I’m not even using WIFI, just 3G .. Anyways, wonderful blog!

  2. This design is steller! You obviously know how to keep a reader amused. Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Wonderful job. I really loved what you had to say, and more than that, how you presented it. Too cool!

  3. Hello! This is my 1st comment here so I just wanted to give a quick shout out and tell you I really enjoy reading through your blog posts. Can you suggest any other blogs/websites/forums that go over the same subjects? Thank you!

  4. Thank you for sharing superb informations. Your web-site is very cool. I’m impressed by the details that you¦ve on this website. It reveals how nicely you perceive this subject. Bookmarked this website page, will come back for extra articles. You, my pal, ROCK! I found simply the info I already searched everywhere and just couldn’t come across. What a perfect web site.

  5. Oh my goodness! an amazing article dude. Thank you Nonetheless I am experiencing subject with ur rss . Don’t know why Unable to subscribe to it. Is there anybody getting an identical rss problem? Anyone who knows kindly respond. Thnkx

  6. I needed to send you one tiny remark just to say thank you yet again regarding the marvelous tactics you have shown above. It’s so unbelievably open-handed with you to present unreservedly exactly what many people would’ve offered as an e book to help with making some profit for their own end, specifically now that you could possibly have tried it if you ever desired. The smart ideas additionally served like the fantastic way to realize that someone else have similar interest just like my own to grasp whole lot more in terms of this problem. I am sure there are lots of more fun opportunities in the future for many who read your website.

  7. Have you ever thought about publishing an e-book or guest authoring on other blogs? I have a blog based on the same information you discuss and would love to have you share some stories/information. I know my viewers would value your work. If you’re even remotely interested, feel free to send me an e mail.

  8. Wonderful beat ! I wish to apprentice while you amend your web site, how can i subscribe for a blog web site? The account helped me a acceptable deal. I have been tiny bit acquainted of this your broadcast offered vivid transparent idea

  9. I was just seeking this information for some time. After 6 hours of continuous Googleing, at last I got it in your web site. I wonder what’s the lack of Google strategy that don’t rank this type of informative sites in top of the list. Normally the top web sites are full of garbage.

  10. I am glad for writing to let you understand of the helpful encounter my cousin’s girl encountered visiting your webblog. She noticed too many things, not to mention how it is like to possess an incredible teaching heart to make many others without hassle fully understand certain complicated subject matter. You actually did more than her desires. Thank you for giving those valuable, trustworthy, informative and in addition cool guidance on the topic to Lizeth.

  11. Howdy! Quick question that’s completely off topic. Do you know how to make your site mobile friendly? My weblog looks weird when viewing from my iphone 4. I’m trying to find a template or plugin that might be able to resolve this issue. If you have any suggestions, please share. Thank you!

  12. Thank you a lot for providing individuals with an extraordinarily breathtaking chance to check tips from here. It really is very amazing plus jam-packed with a lot of fun for me personally and my office co-workers to visit your website at the very least 3 times a week to learn the fresh items you have got. And of course, we are at all times pleased with all the wonderful creative concepts you give. Certain two tips in this posting are honestly the most suitable we have had.

  13. I don’t even know how I ended up here, but I thought this post was great. I do not know who you are but certainly you are going to a famous blogger if you are not already 😉 Cheers!

  14. Hi there! I could have sworn I’ve been to this blog before but after checking through some of the post I realized it’s new to me. Anyhow, I’m definitely happy I found it and I’ll be book-marking and checking back often!

  15. One other issue is when you are in a problem where you do not have a cosigner then you may actually want to try to wear out all of your financing options. You will discover many awards and other scholarship grants that will give you funding that can help with education expenses. Thx for the post.

  16. Hi I am so excited I found your web site, I really found you by accident, while I was researching on Askjeeve for something else, Regardless I am here now and would just like to say cheers for a marvelous post and a all round enjoyable blog (I also love the theme/design), I don’t have time to read it all at the minute but I have bookmarked it and also included your RSS feeds, so when I have time I will be back to read more, Please do keep up the fantastic work.

  17. I’m truly enjoying the design and layout of your website. It’s a very easy on the eyes which makes it much more pleasant for me to come here and visit more often. Did you hire out a developer to create your theme? Superb work!

Leave a Reply to Anonymous Cancel reply