{"id":10064,"date":"2022-03-29T17:20:00","date_gmt":"2022-03-29T11:50:00","guid":{"rendered":"https:\/\/opstree.com\/blog\/\/?p=10064"},"modified":"2022-04-11T11:37:41","modified_gmt":"2022-04-11T06:07:41","slug":"statefulsets-in-k8s","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2022\/03\/29\/statefulsets-in-k8s\/","title":{"rendered":"Explore More on StatefulSets in K8s"},"content":{"rendered":"\n<p class=\"has-text-align-justify\">Do you have a requirement to deploy a stateful application in your Kubernetes cluster? If yes, then this is the right article for you. Kubernetes has various controllers and the one we are going to be talking about today is StatefulSet Controller which will help us achieve the aforementioned task.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is a StatefulSet?<\/h2>\n\n\n\n<p class=\"has-text-align-justify\">Statefulset is a Kubernetes object that deploys and scales a group of Kubernetes pods but so does the deployment. Generally, when we have a deployment, we don&#8217;t care how pods are scheduled and what name they get, but in some cases, it is important that pods are deployed in order and have the same name through all the restarts and reschedules. This is where statefulset comes into the picture.  Statefulset allocates a sticky identity[ a number starting from 0]  to every pod instead of appending a random string to the pod&#8217;s name. Every pod in statefulset is started in a sequential order, so if for some reason pod-0 didn&#8217;t start, pod-1,2,3 and so on wouldn&#8217;t start as well.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">When do we use Statefulset?<\/h2>\n\n\n\n<p class=\"has-text-align-justify\">There can be multiple use cases for a statefulset, the most common one of them is when we want to replicate a database. The databases can&#8217;t be generally replicated by deployments\/replicasets.  <\/p>\n\n\n\n<p>Why can&#8217;t we use deployments to replicate databases?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"797\" height=\"443\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/03\/screenshot-from-2022-03-20-10-59-49.png?w=797\" alt=\"\" class=\"wp-image-10280\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-justify\">In the above diagram, we have a traditional deployment of mysql with no. of replicas set to 1.  Also, we have a web app that reads\/writes to our MySQL database and the MySQL database then stores the data in its persistent volume. This works perfectly for a single pod, but what happens when we scale up our database to match the needs of an increased workload. Say, we set no. of replicas = 3 and hit kubectl apply.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/03\/screenshot-from-2022-03-20-09-08-51-1.png?w=832\" alt=\"\" class=\"wp-image-10263\" width=\"800\" \/><\/figure>\n\n\n\n<p class=\"has-text-align-justify\">Now we have 3 independent mysql pods with no sharing of databases. This wouldn&#8217;t work for several reasons.  When the web app tries to read\/write data from\/to the mysql, it would go to a different pod every time and we would end up with inconsistent data. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How would a Statefulset solve this problem?<\/h2>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"825\" height=\"463\" data-id=\"10265\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/03\/screenshot-from-2022-03-20-09-15-15.png?w=825\" alt=\"\" class=\"wp-image-10265\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"has-text-align-justify\">When we deploy mysql or any other application as a statefulset it is possible to treat the first pod(which in this case happens to be mysql-0) as the primary pod, which will support both read and write requests meanwhile the other pods which are part of statefulset would only serve read requests. This would help us setup a primary-replica or master-slave architecture for databases which means that all the pods which are part of the statefulset would be in sync and share the same data. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to create a Statefulset?<\/h2>\n\n\n\n<p class=\"has-text-align-justify\">A statefulset manifest is pretty similar to that of deployment. The only difference is kind, serviceName and volumeClaimTemplates. Under serviceName, we define the name of the headless service which is nothing but a normal service object of kubernetes, it is treated as headless once we define it in statefulset manifest file.  VolumeClaimTemplates section would serve as the pvc for each pod that would be created as a part of statefulset. <\/p>\n\n\n\n<p>Below is an example of mysql as a statefulset. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: apps\/v1\nkind: StatefulSet\nmetadata:\n  name: mysql\nspec:\n  selector:\n    matchLabels:\n      app: mysql\n  serviceName: \"mysql\"\n  replicas: 3\n  template:\n    metadata:\n      labels:\n        app: mysql\n    spec:\n      terminationGracePeriodSeconds: 10\n      containers:\n      - name: mysql\n        image: mysql\n        ports:\n        - containerPort: 3306\n        volumeMounts:\n        - name: mysql-data\n          mountPath: \/var\/lib\/mysql\n        env:\n          - name: MYSQL_ROOT_PASSWORD\n            value: password\n  volumeClaimTemplates:\n  - metadata:\n      name: mysql-data\n    spec:\n      accessModes: &#091;\"ReadWriteOnce\"]\n      storageClassName: \"gp2\"\n      resources:\n        requests:\n          storage: 10Gi\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: mysql\n  labels:\n    app: mysql\nspec:\n  ports:\n  - port: 3306\n  clusterIP: None\n  selector:\n    app: mysql<\/code><\/pre>\n\n\n\n<p class=\"has-text-align-justify\">This manifest would create a statefulset with 3 mysql pods, a headless service, 3 persistentVolumeClaim and  persistentVolume[one for each pod] .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f mysql.yml<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2022\/03\/screenshot-from-2022-03-20-10-33-39.png?w=1024\" alt=\"\" class=\"wp-image-10271\" width=\"800\" height=\"350\" \/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Note &#8211; Even though Statefulset help us deploy stateful applications, it does not take care of the replication by itself. That part has to be handled seperately.<\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"has-text-align-justify\">In this blog, we learned the basics of statefulset and how if we want to deploy a stateful application we could benefit from it. Statefulset in Kubernetes provides an ordinal number for each pod[beginning from 0]. This helps to easily set up primary-replica and master-slave architecture for stateful applications. It can be used to deploy stateful applications like mysql, mongodb, elasticsearch, wordpress, etc.<\/p>\n\n\n\n<p>Happy Learning !!<\/p>\n\n\n\n<p><br><strong style=\"font-weight:bold;\">Blog Pundit:<\/strong> <strong>Sanjeev Pandey<\/strong>, <a href=\"https:\/\/opstree.com\/blog\/\/author\/deepakgupta97\/\"><strong>Deepak Gupta<\/strong><\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/opstree.com\/blog\/\/author\/sandeep7c51ad81ba\/\" target=\"_blank\"><strong>Sandeep Rawat<\/strong><\/a><\/p>\n\n\n\n<p><strong><a href=\"https:\/\/www.opstree.com\/contact-us?utm_source=blog&amp;utm_medium=wordpress+&amp;utm_campaign=Explore-More-on-StatefulSets-in-K8s\">Opstree<\/a><\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.opstree.com\/contact-us?utm_source=blog&amp;utm_medium=wordpress+&amp;utm_campaign=AWS-Elastic-Network-Interface\" target=\"_blank\"> <\/a>is an End to End DevOps solution provider<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-fill\"><a class=\"wp-block-button__link\" href=\"https:\/\/www.opstree.com\/contact-us\" target=\"_blank\" rel=\"noreferrer noopener\">CONTACT US<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"has-text-align-center\"><strong>Connect Us <\/strong><\/p>\n\n\n\n<ul class=\"wp-block-social-links aligncenter is-content-justification-right is-layout-flex wp-container-core-social-links-is-layout-1 wp-block-social-links-is-layout-flex\"><li class=\"wp-social-link wp-social-link-linkedin  wp-block-social-link\"><a href=\"https:\/\/www.linkedin.com\/company\/opstree-solutions\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">LinkedIn<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-youtube  wp-block-social-link\"><a href=\"https:\/\/www.youtube.com\/channel\/UCeLma6SpNYH7jjYKSBNSexw\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">YouTube<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-github  wp-block-social-link\"><a href=\"https:\/\/github.com\/OpsTree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">GitHub<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-facebook  wp-block-social-link\"><a href=\"https:\/\/www.facebook.com\/opstree\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Facebook<\/span><\/a><\/li>\n\n<li class=\"wp-social-link wp-social-link-medium  wp-block-social-link\"><a href=\"https:\/\/medium.com\/buildpiper\" class=\"wp-block-social-link-anchor\" target=\"_blank\" rel=\"noopener\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z\"><\/path><\/svg><span class=\"wp-block-social-link-label screen-reader-text\">Medium<\/span><\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Do you have a requirement to deploy a stateful application in your Kubernetes cluster? If yes, then this is the right article for you. Kubernetes has various controllers and the one we are going to be talking about today is StatefulSet Controller which will help us achieve the aforementioned task. What is a StatefulSet? Statefulset &hellip; <a href=\"https:\/\/opstree.com\/blog\/2022\/03\/29\/statefulsets-in-k8s\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Explore More on StatefulSets in K8s&#8221;<\/span><\/a><\/p>\n","protected":false},"author":218078523,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[28070474],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-2Ck","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/10064"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/218078523"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=10064"}],"version-history":[{"count":24,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/10064\/revisions"}],"predecessor-version":[{"id":10430,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/10064\/revisions\/10430"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=10064"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=10064"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=10064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}