{"id":82,"date":"2025-03-13T07:07:37","date_gmt":"2025-03-13T07:07:37","guid":{"rendered":"https:\/\/aiinfrahub.com\/about-us\/?p=82"},"modified":"2025-03-13T07:58:06","modified_gmt":"2025-03-13T07:58:06","slug":"kubernetes-networking-iptables","status":"publish","type":"post","link":"https:\/\/aiinfrahub.com\/about-us\/kubernetes-networking-iptables\/","title":{"rendered":"Kubernetes Networking &#8211; Iptables"},"content":{"rendered":"\n<p class=\"has-text-align-center has-small-font-size\"><\/p>\n\n\n\n<p>As per Wiki definition, &nbsp;\u201c<strong>iptables<\/strong>&nbsp;is a&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/User_space\">user-space<\/a>&nbsp;utility program that allows a&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/System_administrator\">system administrator<\/a>&nbsp;to configure the&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Packet_filter\">IP packet filter rules<\/a>&nbsp;of the&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linux_kernel\">Linux kernel<\/a>&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Firewall_(computing)\">firewall<\/a>, implemented as different&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Netfilter\">Netfilter<\/a>&nbsp;modules\u201d.<\/p>\n\n\n\n<p>In simple words, iptables is linux basic firewall software. Just like a mini version of firewall , it does packet filtering whether to allows, blocks or forward packets.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"letter-spacing:px\">Iptables contains multiple tables to manage the rules. Based on the type of rules and its applicability , user has to create and add rules to a particular table to make the rules work correctly. For example, if a rule is required for network &nbsp;translation, it will be put in nat table. If the rules is to allow or to discard packets , then it will be put in filter table.<\/li>\n\n\n\n<li style=\"letter-spacing:px\">Inside each iptables table, rules are further organized into separate chains. Chains are mapped to kernel netfilters hooks which decide when the rules will be triggers. We can have a single chain or cascading chains based of requirement. A chain can be empty also.<\/li>\n\n\n\n<li style=\"letter-spacing:px\">At the end, we have rules which are the last mile resource, which decides the fate of the packets. Rules can accept, block, forward packets. Rules can accept, block, forward packets coming from certain subnets, for a particular port etc. The outcome of a rule is called Policy. The policy decides whether to drop, accept or reject the traffic.<\/li>\n<\/ul>\n\n\n\n<p>Successor of iptables is&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Nftables\">nftables<\/a>, in modern day system, it has been seen that nftables are getting used, however still iptables are used in the background in order to support legacy network softwares.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-medium-font-size\"><strong>Iptables table and their applicable chains:<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"692\" height=\"743\" src=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-5.png\" alt=\"\" class=\"wp-image-87\" srcset=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-5.png 692w, https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-5-279x300.png 279w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-medium-font-size\"><strong>Tables and their usage:<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"692\" height=\"587\" src=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-4.png\" alt=\"\" class=\"wp-image-86\" srcset=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-4.png 692w, https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-4-300x254.png 300w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-medium-font-size\"><strong>Built-in Chains (default chains provided by Netfilter):<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"376\" src=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-6.png\" alt=\"\" class=\"wp-image-88\" srcset=\"https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-6.png 693w, https:\/\/aiinfrahub.com\/wp-content\/uploads\/2025\/03\/image-6-300x163.png 300w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Demo:<\/h2>\n\n\n\n<p>As we understood the theory and concepts of iptables, lets get our hand dirty.<\/p>\n\n\n\n<p>In this demo, we will deploy simple Kubernetes application with two replicas and exposed it using a NodePort service. After then we will analyze <code>iptables<\/code> rules to uncover how Kubernetes routes and load-balances traffic at the network level.<\/p>\n\n\n\n<p>Filename: hello-app-deployment.yaml <\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: hello-app\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: hello-app\n  template:\n    metadata:\n      labels:\n        app: hello-app\n    spec:\n      containers:\n      - name: hello-app\n        image: gcr.io\/google-samples\/hello-app:1.0\n        ports:\n        - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: hello-app-service\nspec:\n  type: NodePort\n  selector:\n    app: hello-app\n  ports:\n    - protocol: TCP\n      port: 80\n      targetPort: 8080<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-code has-small-font-size\" style=\"font-style:normal;font-weight:100\"><code><strong>host1$kubectl apply -f  hello-app-deployment.yaml \nhost1$kubectl get svc\n<\/strong>NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE\nhello-app-service   NodePort    10.104.81.240   &lt;none&gt;        80:30811\/TCP   2m57s\nkubernetes          ClusterIP   10.96.0.1       &lt;none&gt;        443\/TCP        20d\n<strong>host1$kubectl get pods -o wide\n<\/strong>NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE           NOMINATED NODE   READINESS GATES\nhello-app-58d97c88d4-h7s2n   1\/1     Running   0          3m14s   172.16.166.130   host1   &lt;none&gt;           &lt;none&gt;\nhello-app-58d97c88d4-pkh8c   1\/1     Running   0          3m14s   172.16.192.89    host2   &lt;none&gt;           &lt;none&gt;<\/code><\/pre>\n<\/div>\n<\/div>\n\n\n\n<p><strong>Observation<\/strong>: We can see that after the deployment, we have 2 pods running. In services, apart from NodePort, note that ClusterIP service is assigned by default.<\/p>\n\n\n\n<p>Now suppose, a user fires a curl command <strong>&#8220;curl http:\/\/&lt;NodeIP&gt;:30811&#8221;<\/strong>. Lets trace how this command will reach the end mile resource ie pods behind the NodePort service with the help of iptables.<\/p>\n\n\n\n<p>Lets check the iptables rules.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\" style=\"font-style:normal;font-weight:100\"><code>host1$sudo iptables -n -t nat -L KUBE-SERVICES\nChain KUBE-SERVICES (2 references)\ntarget     prot opt source               destination\nKUBE-SVC-NGVTFAARHANBXKRK  tcp  --  0.0.0.0\/0            10.104.148.121       \/* \n<strong>KUBE-SVC-YG6ZEOBCLVGD3AJB  tcp  --  0.0.0.0\/0            10.104.81.240        \/* default\/hello-app-service cluster IP *\/\n<\/strong>KUBE-NODEPORTS  all  --  0.0.0.0\/0            0.0.0.0\/0            \/* kubernetes service nodeports; NOTE: this must be the last rule in this chain *\/ ADDRTYPE match dst-type LOCAL<\/code><\/pre>\n\n\n\n<p><strong>Observation<\/strong>: In NAT table, KUBE-SVC-XXXX chain handles that any incoming tcp traffic or curl request coming from any source will get directed to NodePort IP ie <strong>10.104.81.240<\/strong>. Internally KUBE-SVC-XXXX chain does the load balancing means direct the traffic to one of the 2 pods managed by the service. Lets see how ?<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\" style=\"font-style:normal;font-weight:100\"><code>host1$sudo iptables -n -t nat -L KUBE-SVC-YG6ZEOBCLVGD3AJB\nChain KUBE-SVC-YG6ZEOBCLVGD3AJB (2 references)\ntarget     prot opt source               destination\nKUBE-MARK-MASQ  tcp  -- !172.16.0.0\/16        10.104.81.240        \/* default\/hello-app-service cluster IP *\/\n<strong>KUBE-SEP-7I3URQ2O437FVP5U  all  --  0.0.0.0\/0            0.0.0.0\/0            \/* default\/hello-app-service -&gt; 172.16.166.130:8080 *\/ statistic mode random probability 0.50000000000\nKUBE-SEP-PSPHHDAXPY5YRT7B  all  --  0.0.0.0\/0            0.0.0.0\/0            \/* default\/hello-app-service -&gt; 172.16.192.89:8080 *\/<\/strong><\/code><\/pre>\n\n\n\n<p><strong>Observation<\/strong>: In NAT table, deep dive inside KUBE-SVC-YG6ZEOBCLVGD3AJB chain reveals that service will load balance the request between two pods randomly with 0.5 % probability.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\" style=\"font-style:normal;font-weight:100\"><code>host1$sudo iptables -n -t nat -L KUBE-SEP-PSPHHDAXPY5YRT7B\nChain KUBE-SEP-PSPHHDAXPY5YRT7B (1 references)\ntarget     prot opt source               destination\nKUBE-MARK-MASQ  all  --  172.16.192.89        0.0.0.0\/0            \/* default\/hello-app-service *\/\nDNAT       tcp  --  0.0.0.0\/0            0.0.0.0\/0            \/* default\/hello-app-service *\/ tcp to:172.16.192.89:8080<\/code><\/pre>\n\n\n\n<p><strong>Observation<\/strong>: Ultimately the leaf chain where the request is landing ie one of the pod IP.<\/p>\n\n\n\n<p>By breaking down the iptables rules, we\u2019ve gained basic insights of Kubernetes cluster networking uncovering  how traffic seamlessly flows from external users to application pods.<\/p>\n\n\n\n<p>In this article, we have covered &#8220;iptables&#8221; tables dealing with ipv4 traffic, however same concept applies to &#8220;ip6tables&#8221; for ipv6 traffic.<\/p>\n\n\n\n<p>In next article, we will be covering Kubernetes services focusing on the networking aspects.<\/p>\n\n\n\n<p>Good Bye for now. Stay tuned.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">References:<\/h2>\n\n\n\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Iptables\">https:\/\/en.wikipedia.org\/wiki\/Iptables<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/man7.org\/linux\/man-pages\/man8\/iptables.8.html\">https:\/\/man7.org\/linux\/man-pages\/man8\/iptables.8.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As per Wiki definition, &nbsp;\u201ciptables&nbsp;is a&nbsp;user-space&nbsp;utility program that allows a&nbsp;system administrator&nbsp;to configure the&nbsp;IP packet filter rules&nbsp;of the&nbsp;Linux kernel&nbsp;firewall, implemented as different&nbsp;Netfilter&nbsp;modules\u201d. In simple words, iptables is linux basic firewall software. Just like a mini version of firewall , it does packet filtering whether to allows, blocks or forward packets. Successor of iptables is&nbsp;nftables, in modern &#8230; <a title=\"Kubernetes Networking &#8211; Iptables\" class=\"read-more\" href=\"https:\/\/aiinfrahub.com\/about-us\/kubernetes-networking-iptables\/\" aria-label=\"Read more about Kubernetes Networking &#8211; Iptables\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":84,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4],"tags":[2],"class_list":["post-82","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kubernetes","category-networking","tag-networking"],"_links":{"self":[{"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/posts\/82","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/comments?post=82"}],"version-history":[{"count":8,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/posts\/82\/revisions"}],"predecessor-version":[{"id":105,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/posts\/82\/revisions\/105"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/media\/84"}],"wp:attachment":[{"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/media?parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/categories?post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aiinfrahub.com\/about-us\/wp-json\/wp\/v2\/tags?post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}