{"id":1724,"date":"2024-08-31T17:12:15","date_gmt":"2024-08-31T17:12:15","guid":{"rendered":"http:\/\/shijuvarghese.com\/?p=1724"},"modified":"2025-05-23T17:54:23","modified_gmt":"2025-05-23T17:54:23","slug":"kubernetes-clusterip","status":"publish","type":"post","link":"http:\/\/shijuvarghese.com\/?p=1724","title":{"rendered":"Kubernetes: ClusterIP"},"content":{"rendered":"<p>The ClusterIP is one of the three services in Kubernetes. When creating a manifest file in yaml format if the kind is\u00a0<em>service<\/em>, and no\u00a0<em>type\u00a0<\/em>is mentioned, Kubernetes assumes that it will be\u00a0<em>ClusterIP<\/em> by default.<\/p>\n<p>Let us assume there is a 2-tire application. A layer that consists of 3 application servers (replica of 3), connecting to next layer of 3 DB servers (3 replica). In a typical traditional network world, 3 DB servers will be sitting behind an LB, and each of the 3 Application Server will be accessing the LB that routs the connection to one of the 3 target DB server.<\/p>\n<p>In the world of Kubernetes each of these DB server has an IP address, and the IPs that sits behind the above mentioned LB can change if a DB pod goes down and another one takes its place, arranged by the ReplicaSet.<\/p>\n<p>In the world of Kubernetes the service <em>ClusterIP<\/em> takes the role of the LB mentioned in the above architecture, and this service discovers and gathers the IP (even new ones) associated with pods hosting DB containers.<\/p>\n<p>As an example, let us create a <em>ReplicaSet<\/em> that deploys 3 pods with image\u00a0<em>mysql server<\/em>, with label parameter &#8220;<em>theApp: sv1&#8243;<\/em><\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> cat replicaset1.yml<\/p>\n<p><em>==== ==<\/em><br \/>\n<em>apiVersion: apps\/v1<\/em><br \/>\n<em>kind: ReplicaSet<\/em><br \/>\n<em>metadata:<\/em><br \/>\n<em>\u00a0 \u00a0 name: myreplicaset<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0labels:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0theApp: sv1<\/em><br \/>\n<em>\u00a0 \u00a0\u00a0spec:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0template:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0metadata:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0name: mypod1<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0labels:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0theApp: sv1<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0spec:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0containers:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0&#8211; name: mypodcontainer<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 image: nginx<\/em><br \/>\n<em>\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 replicas: 2<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0selector:<\/em><br \/>\n<em>\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0 matchLabels:<\/em><br \/>\n<em> \u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0theApp: sv1<\/em><br \/>\n<em>==== ===<\/em><\/p>\n<p>Now let us create a\u00a0<em>service<\/em> with type\u00a0<em>ClusterIP<\/em>.<\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> cat service-clusterip.yml<br \/>\n<em>===== ====<\/em><br \/>\n<em>apiVersion: v1<\/em><br \/>\n<em>kind: Service<\/em><br \/>\n<em>metadata:<\/em><br \/>\n<em>\u00a0 \u00a0 \u00a0name: front-end<\/em><\/p>\n<p><em>spec:<\/em><br \/>\n<em> \u00a0 \u00a0 \u00a0type: ClusterIP<\/em><br \/>\n<em> \u00a0 \u00a0 \u00a0ports:<\/em><br \/>\n<em> \u00a0 \u00a0 \u00a0&#8211; targetPort: 80<\/em><br \/>\n<em> \u00a0 \u00a0 \u00a0\u00a0 \u00a0port: 80<\/em><\/p>\n<p><em>\u00a0 \u00a0 \u00a0selector:<\/em><br \/>\n<em> \u00a0 \u00a0 \u00a0\u00a0 \u00a0 \u00a0theApp: sv1<\/em><br \/>\n<em>==== ====<\/em><\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> kubectl create -f replicaset1.yml<\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> kubectl create -f service-clusterip.yml<\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> kubectl get all | grep front-end<br \/>\nservice\/front-end\u00a0 \u00a0 \u00a0 \u00a0ClusterIP\u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #ff6600;\">10.106.148.176<\/span>\u00a0 \u00a0 \u00a0 \u00a0&lt;none&gt;\u00a0 \u00a0 \u00a0 80\/TCP\u00a0 \u00a0 \u00a0 \u00a018m<\/p>\n<p>Now that we have the Cluster&#8217;s IP which is 10.106.148.176, let us check the nodes where the\u00a0<em>pods<\/em> are running, created by the replicaset.<\/p>\n<p><strong>[root@kubmaster01 ~]#<\/strong> kubectl get pods -o wide<\/p>\n<p>If there are 2 pods created, and running in both worker nodes, they can be accessed by the below command in both the nodes.<\/p>\n<p><strong>[root@kubworker01 ~]#<\/strong> curl http:\/\/10.106.148.176<\/p>\n<p>However, if both the pod<strong>s<\/strong> are only on one node, then the above curl command have to be run on that specific node.<\/p>\n<p>As the web page is accessed using the clusterIP, it does not matter if the pods are recreated and the pod&#8217;s IP changes.\u00a0 This can be verified by scaling the replicaset zero and then back to 1. As the pods are recreated, their IPs change, but still they can be accessed by the ClusterIP.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>The ClusterIP is one of the three services in Kubernetes. When creating a manifest file in yaml format if the kind is\u00a0service, and no\u00a0type\u00a0is mentioned, <a class=\"mh-excerpt-more\" href=\"http:\/\/shijuvarghese.com\/?p=1724\" title=\"Kubernetes: ClusterIP\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":1784,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,34],"tags":[],"class_list":["post-1724","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-kubernetes"],"_links":{"self":[{"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/posts\/1724","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1724"}],"version-history":[{"count":8,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/posts\/1724\/revisions"}],"predecessor-version":[{"id":1766,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/posts\/1724\/revisions\/1766"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=\/wp\/v2\/media\/1784"}],"wp:attachment":[{"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1724"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1724"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/shijuvarghese.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1724"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}