<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>iptables | Ronak Nathani</title><link>https://ronaknathani.pages.dev/tag/iptables/</link><atom:link href="https://ronaknathani.pages.dev/tag/iptables/index.xml" rel="self" type="application/rss+xml"/><description>iptables</description><generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>en-us</language><copyright>© 2026 Ronak Nathani</copyright><lastBuildDate>Wed, 08 Jul 2020 14:36:33 -0700</lastBuildDate><image><url>https://ronaknathani.pages.dev/img/avatar.jpg</url><title>iptables</title><link>https://ronaknathani.pages.dev/tag/iptables/</link></image><item><title>Kubernetes NodePort and iptables rules</title><link>https://ronaknathani.pages.dev/blog/2020/07/kubernetes-nodeport-and-iptables-rules/</link><pubDate>Wed, 08 Jul 2020 14:36:33 -0700</pubDate><guid>https://ronaknathani.pages.dev/blog/2020/07/kubernetes-nodeport-and-iptables-rules/</guid><description>&lt;p>I have been working on kubernetes over the last few months and having fun learning about the underlying systems. When I started using
&lt;a href="%28https://kubernetes.io/docs/concepts/services-networking/service/%29">kubernetes services&lt;/a>, I wanted to learn about the iptables rules that kube-proxy creates to enable them, however, I didn&amp;rsquo;t exactly know where to start. While there are some really good posts explaining
&lt;a href="https://www.stackrox.com/post/2020/01/kubernetes-networking-demystified/" target="_blank" rel="noopener">kubernetes networking&lt;/a> and how the concept of
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-iptables" target="_blank" rel="noopener">services works&lt;/a>, I couldn&amp;rsquo;t easily find a starting point to explore these iptables except reading the code or trying to make sense of the output of &lt;code>iptables-save&lt;/code> command (which I can&amp;rsquo;t).&lt;/p>
&lt;p>In this post, I share some of what I have learned by digging a little deeper into the iptables rules for NodePort type services and share answers to the following questions I came across while working on kube-proxy:&lt;/p>
&lt;ul>
&lt;li>What happens when a non-kubernetes process starts using a port that&amp;rsquo;s allocated as a NodePort to a service?&lt;/li>
&lt;li>Does the service endpoint continue to route traffic to pods if kube-proxy (configured in iptables mode) process dies on the node?&lt;/li>
&lt;/ul>
&lt;h2 id="some-background">Some background&lt;/h2>
&lt;p>Kubernetes allows a
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types" target="_blank" rel="noopener">few ways to expose applications&lt;/a> to the world outside the kubernetes cluster through the concept of
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/" target="_blank" rel="noopener">services&lt;/a>. In our setup at work, we expose a few of our apps through
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" target="_blank" rel="noopener">NodePort&lt;/a> type services. Also,
&lt;a href="https://kubernetes.io/docs/concepts/overview/components/#kube-proxy" target="_blank" rel="noopener">kube-proxy&lt;/a> is the kubernetes component that powers the
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/" target="_blank" rel="noopener">services concept&lt;/a> and we run it in iptables mode (default).&lt;/p>
&lt;h2 id="a-little-about-nodeport">A little about NodePort&lt;/h2>
&lt;p>
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" target="_blank" rel="noopener">NodePort&lt;/a> is one of the ways of exposing
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/" target="_blank" rel="noopener">Kubernetes Services&lt;/a> to the world outside the kubernetes cluster. As per Kubernetes
&lt;a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" target="_blank" rel="noopener">docs&lt;/a>,&lt;/p>
&lt;blockquote>
&lt;p>If you set the type field to NodePort, the Kubernetes control plane allocates a port from a range specified by &lt;code>--service-node-port-range&lt;/code> flag &lt;code>(default: 30000-32767)&lt;/code>. Each node proxies that port (the same port number on every Node) into your Service.&lt;/p>
&lt;/blockquote>
&lt;p>This means that if we have a &lt;code>service&lt;/code> with NodePort &lt;code>30000&lt;/code>, a request to &lt;code>&amp;lt;kubernetes-node-ip&amp;gt;:30000&lt;/code> will get routed to our app. Under normal circumstances kube-proxy
&lt;a href="https://github.com/kubernetes/kubernetes/blob/7de3f938c82a7c0538bdfac5bb9b3cad50c30eae/pkg/proxy/iptables/proxier.go#L1638" target="_blank" rel="noopener">binds and listens&lt;/a> on all NodePorts to ensure these ports stay reserved and no other processes can use them.&lt;/p>
&lt;h3 id="erra-non-kubernetes-is-using-the-nodeport">err&amp;hellip;a non-kubernetes is using the NodePort!!&lt;/h3>
&lt;p>A few weeks back at work, one of our kubernetes nodes was rebooted and as it was added back to the cluster, we saw errors in kube-proxy logs - &lt;code>bind: address already in use&lt;/code>:&lt;/p>
&lt;pre>&lt;code class="language-bash">I0707 20:57:38.648179 1 proxier.go:701] Syncing iptables rules
E0707 20:57:38.679876 1 proxier.go:1072] can't open &amp;quot;nodePort for default/azure-vote-front:&amp;quot; (:30450/tcp), skipping this nodePort: listen tcp :30450: bind: address already in use
&lt;/code>&lt;/pre>
&lt;p>This error meant that a port allocated as a NodePort to a &lt;code>service&lt;/code> was already in use by another process. We found out that there was a non-kubernetes process using this NodePort as a client port to connect to a remote server. This happened due of a race condition post node reboot. This other process started using the NodePort before kube-proxy could bind and listen on the port to reserve it.&lt;/p>
&lt;h2 id="will-the-nodeport-on-this-node-still-route-traffic-to-the-pods">Will the NodePort on this node still route traffic to the pods?&lt;/h2>
&lt;p>This was the immediate question that popped up in our heads as the NodePort allocated to a &lt;code>service&lt;/code> was now being used by a non-kubernetes process. One of my colleagues,
&lt;a href="https://www.linkedin.com/in/alexanderdudko/" target="_blank" rel="noopener">Alex Dudko&lt;/a> pointed out that kube-proxy creates iptables rules in the &lt;strong>PREROUTING&lt;/strong> chain in &lt;strong>nat&lt;/strong> table.&lt;/p>
&lt;p>Because of these rules, the answer to the above question is - &lt;strong>Yes!&lt;/strong> Traffic sent to the NodePort on this node will still correctly be routed to the backend pods it targets.&lt;/p>
&lt;p>The NodePort would also continue to work if another process was listening on the port as a server and not just using it as a client. Though, would our &lt;code>HTTP GET&lt;/code> requests reach this server? More on this later.&lt;/p>
&lt;h2 id="kube-proxy-iptables-rules">Kube-proxy iptables rules&lt;/h2>
&lt;p>In iptables mode, kube-proxy creates iptables rules for kubernetes services which ensure that the request to the &lt;code>service&lt;/code> gets routed (and load balanced) to the appropriate pods.&lt;/p>
&lt;p>These iptables rules also help answer the second question mentioned above. As long as these iptables rules exist, requests to &lt;code>services&lt;/code> will get routed to the appropriate pods even if kube-proxy process dies on the node. Endpoints for new &lt;code>services&lt;/code> won&amp;rsquo;t work from this node, however, since kube-proxy process won&amp;rsquo;t create the iptables rules for it.&lt;/p>
&lt;h3 id="rules-in-the-prerouting-chain">Rules in the PREROUTING chain&lt;/h3>
&lt;p>As outlined in this
&lt;a href="https://docs.google.com/drawings/d/1MtWL8qRTs6PlnJrW4dh8135_S9e2SaawT410bJuoBPk/preview" target="_blank" rel="noopener">flow chart&lt;/a>, there are rules in the &lt;strong>PREROUTING&lt;/strong> chain of the &lt;strong>nat&lt;/strong> table for kubernetes services. As per
&lt;a href="https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg" target="_blank" rel="noopener">iptables rules evaluation order&lt;/a>, rules in the &lt;strong>PREROUTING&lt;/strong> chain are the first ones to be consulted as a packet enters the linux kernel&amp;rsquo;s networking stack.&lt;/p>
&lt;p>Rules created by kube-proxy in the &lt;strong>PREROUTING&lt;/strong> chain help determine if the packet is meant for a local socket on the node or if it should be forwarded to a pod. It is these rules that ensure that the request to &lt;code>&amp;lt;kubernetes-node-ip&amp;gt;:&amp;lt;NodePort&amp;gt;&lt;/code> continue to get routed to pods even if the NodePort is in use by another process.&lt;/p>
&lt;p>Below is an over-simplified diagram that demonstrates this:&lt;/p>
&lt;p>&lt;img src="prerouting-rule.png" alt="prerouting-rule effect">&lt;/p>
&lt;p>In rest of this post, I walk through a setup that reproduces the above scenario and examine the iptables rules that make this work.&lt;/p>
&lt;h2 id="setting-up-a-kubernetes-cluster">Setting up a Kubernetes cluster&lt;/h2>
&lt;p>I created a kubernetes cluster using
&lt;a href="https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough" target="_blank" rel="noopener">Azure Kubernetes Service &lt;/a>.&lt;/p>
&lt;h3 id="creating-pods-and-a-nodeport-service">Creating pods and a NodePort Service&lt;/h3>
&lt;p>From the
&lt;a href="https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough#run-the-application" target="_blank" rel="noopener">AKS docs&lt;/a>, I also created a
&lt;a href="https://gist.github.com/ronaknnathani/49b54d7147e263d8dd3bb6016614f817" target="_blank" rel="noopener">deployment for an app with a frontend and a backend&lt;/a>. I updated the &lt;strong>azure-vote-front&lt;/strong> to &lt;strong>type: NodePort&lt;/strong> service.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>azure-vote-front&lt;/strong> pod in the cluster&lt;/li>
&lt;/ul>
&lt;pre>&lt;code class="language-bash">$ kubectl get po -l app=azure-vote-front --show-labels -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
azure-vote-front-5bc759676c-x9bwg 1/1 Running 0 24d 10.244.0.11 aks-nodepool1-22391620-vmss000000 &amp;lt;none&amp;gt; &amp;lt;none&amp;gt; app=azure-vote-front,pod-template-hash=5bc759676c
&lt;/code>&lt;/pre>
&lt;ul>
&lt;li>&lt;strong>azure-vote-front&lt;/strong> service targeting the above pod&lt;/li>
&lt;/ul>
&lt;pre>&lt;code class="language-bash">$ kubectl get svc azure-vote-front -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
azure-vote-front NodePort 10.0.237.3 &amp;lt;none&amp;gt; 80:30450/TCP 24d app=azure-vote-front
&lt;/code>&lt;/pre>
&lt;p>The above output shows that the port &lt;strong>30450&lt;/strong> is assigned as the NodePort to our service. And we can send HTTP requests to the app from host network:&lt;/p>
&lt;pre>&lt;code class="language-bash">$ curl -IX GET localhost:30450
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Wed, 08 Jul 2020 00:02:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 950
Connection: keep-alive
$ curl -sSL localhost:30450 | grep title
&amp;lt;title&amp;gt;Azure Voting App&amp;lt;/title&amp;gt;
&lt;/code>&lt;/pre>
&lt;h3 id="examining-iptables-rules-for-a-nodeport-service">Examining iptables rules for a NodePort service&lt;/h3>
&lt;p>&lt;em>Note: AKS doesn&amp;rsquo;t allow ssh&amp;rsquo;ing into an AKS worker node directly, instead, a pod needs to be spun up to ssh into the worker node. Instructions
&lt;a href="https://docs.microsoft.com/en-us/azure/aks/ssh#configure-virtual-machine-scale-set-based-aks-clusters-for-ssh-access" target="_blank" rel="noopener">here&lt;/a>.&lt;/em>&lt;/p>
&lt;p>Let&amp;rsquo;s look at the iptables rules for the &lt;strong>azure-vote-front&lt;/strong> service.&lt;/p>
&lt;p>After ssh&amp;rsquo;ing into the kubernetes worker node, let&amp;rsquo;s look at the &lt;strong>PREROUTING&lt;/strong> chain in the &lt;strong>nat&lt;/strong> table. (&lt;code>PREROUTING&lt;/code>
&lt;a href="https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture#which-chains-are-implemented-in-each-table" target="_blank" rel="noopener">chain exists&lt;/a> in &lt;code>raw&lt;/code>, &lt;code>nat&lt;/code> and &lt;code>mangle&lt;/code> tables, however, kube-proxy only creates &lt;code>PREROUTING&lt;/code> chain rules in &lt;code>nat&lt;/code> table)&lt;/p>
&lt;pre>&lt;code class="language-bash">$ sudo iptables -t nat -L PREROUTING | column -t
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- anywhere anywhere /* kubernetes service portals */
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
&lt;/code>&lt;/pre>
&lt;p>There&amp;rsquo;s a &lt;code>KUBE-SERVICES&lt;/code> chain in the target that&amp;rsquo;s created by kube-proxy. Let&amp;rsquo;s list the rules in that chain.&lt;/p>
&lt;pre>&lt;code class="language-bash">$ sudo iptables -t nat -L KUBE-SERVICES -n | column -t
Chain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.202.188 /* kube-system/healthmodel-replicaset-service: cluster IP */ tcp dpt:25227
KUBE-SVC-KA44REDDIFNWY4W2 tcp -- 0.0.0.0/0 10.0.202.188 /* kube-system/healthmodel-replicaset-service: cluster IP */ tcp dpt:25227
KUBE-MARK-MASQ udp -- !10.244.0.0/16 10.0.0.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:53
KUBE-SVC-TCOU7JCQXEZGVUNU udp -- 0.0.0.0/0 10.0.0.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:53
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.0.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:53
KUBE-SVC-ERIFXISQEP7F7OF4 tcp -- 0.0.0.0/0 10.0.0.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:53
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.190.160 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:80
KUBE-SVC-XGLOHA7QRQ3V22RZ tcp -- 0.0.0.0/0 10.0.190.160 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:80
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.195.6 /* kube-system/metrics-server: cluster IP */ tcp dpt:443
KUBE-SVC-LC5QY66VUV2HJ6WZ tcp -- 0.0.0.0/0 10.0.195.6 /* kube-system/metrics-server: cluster IP */ tcp dpt:443
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.129.119 /* default/azure-vote-back: cluster IP */ tcp dpt:6379
KUBE-SVC-JQ4VBJ2YWO22DDZW tcp -- 0.0.0.0/0 10.0.129.119 /* default/azure-vote-back: cluster IP */ tcp dpt:6379
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.237.3 /* default/azure-vote-front: cluster IP */ tcp dpt:80
KUBE-SVC-GHSLGKVXVBRM4GZX tcp -- 0.0.0.0/0 10.0.237.3 /* default/azure-vote-front: cluster IP */ tcp dpt:80
KUBE-MARK-MASQ tcp -- !10.244.0.0/16 10.0.0.1 /* default/kubernetes:https cluster IP */ tcp dpt:443
KUBE-SVC-NPX46M4PTMTKRN6Y tcp -- 0.0.0.0/0 10.0.0.1 /* default/kubernetes:https cluster IP */ tcp dpt:443
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
&lt;/code>&lt;/pre>
&lt;p>The last terget in the &lt;code>KUBE-SERVICES&lt;/code> chain is the &lt;code>KUBE-NODEPORTS&lt;/code> chain. Since the service we created is of type &lt;code>NodePort&lt;/code>, let&amp;rsquo;s list the rules in &lt;code>KUBE-NODEPORTS&lt;/code> chain.&lt;/p>
&lt;pre>&lt;code class="language-bash">$ sudo iptables -t nat -L KUBE-NODEPORTS -n | column -t
Chain KUBE-NODEPORTS (1 references)
target prot opt source destination
KUBE-MARK-MASQ tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/azure-vote-front: */ tcp dpt:30450
KUBE-SVC-GHSLGKVXVBRM4GZX tcp -- 0.0.0.0/0 0.0.0.0/0 /* default/azure-vote-front: */ tcp dpt:30450
&lt;/code>&lt;/pre>
&lt;p>We can see that the above targets are for packets destined to our NodePort &lt;strong>30450&lt;/strong>. The comments also show the namespace/pod name - &lt;code>default/azure-vote-front&lt;/code>. For requests originating from outside the cluster and destined to our app running as a pod, the &lt;code>KUBE-MARK-MASQ&lt;/code> rule marks the packet to be altered later in the &lt;code>POSTROUTING&lt;/code> chain to use SNAT (source network address translation) to rewrite the source IP as the node IP (so that other hosts outside the pod network can reply back).&lt;/p>
&lt;p>Since &lt;code>KUBE-MARK-MASQ&lt;/code> target is to
&lt;a href="https://www.frozentux.net/iptables-tutorial/chunkyhtml/x4422.html" target="_blank" rel="noopener">MASQUERADE&lt;/a> packets later, let&amp;rsquo;s follow the &lt;code>KUBE-SVC-GHSLGKVXVBRM4GZX&lt;/code> chain to further examine our service.&lt;/p>
&lt;pre>&lt;code class="language-bash">$ sudo iptables -t nat -L KUBE-SVC-GHSLGKVXVBRM4GZX -n | column -t
Chain KUBE-SVC-GHSLGKVXVBRM4GZX (2 references)
target prot opt source destination
KUBE-SEP-QXDNOBCCLOXLV7LV all -- 0.0.0.0/0 0.0.0.0/0
$ sudo iptables -t nat -L KUBE-SEP-QXDNOBCCLOXLV7LV -n | column -t
Chain KUBE-SEP-QXDNOBCCLOXLV7LV (1 references)
target prot opt source destination
KUBE-MARK-MASQ all -- 10.244.0.11 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp to:10.244.0.11:80
&lt;/code>&lt;/pre>
&lt;p>Here we see the
&lt;a href="https://www.frozentux.net/iptables-tutorial/chunkyhtml/x4033.html" target="_blank" rel="noopener">DNAT (Destination Network Address Translation)&lt;/a> target is used to rewrite the destination of the packet destined to port &lt;strong>30450&lt;/strong> to our pod &lt;strong>10.244.0.11:80&lt;/strong>. We can verify the &lt;strong>podIP&lt;/strong> and &lt;strong>containerPort&lt;/strong> of our pod as follows:&lt;/p>
&lt;pre>&lt;code class="language-bash">$ kubectl get po azure-vote-front-5bc759676c-x9bwg -o json | jq -r '[.status.podIP, .spec.containers[0].ports[0].containerPort | tostring] | join(&amp;quot;:&amp;quot;)'
10.244.0.11:80
&lt;/code>&lt;/pre>
&lt;h3 id="verify-kube-proxy-is-listening-on-nodeport">Verify kube-proxy is listening on NodePort&lt;/h3>
&lt;p>Under normal circumstances kube-proxy binds and listens on all NodePorts to ensure these ports stay reserved and no other processes can use them. We can verify this on the above kubernetes node:&lt;/p>
&lt;pre>&lt;code class="language-bash">$ sudo lsof -i:30450
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
hyperkube 11558 root 9u IPv6 95841832 0t0 TCP *:30450 (LISTEN)
$ ps -aef | grep -v grep | grep 11558
root 11558 11539 0 Jul02 ? 00:06:37 /hyperkube kube-proxy --kubeconfig=/var/lib/kubelet/kubeconfig --cluster-cidr=10.244.0.0/16 --feature-gates=ExperimentalCriticalPodAnnotation=true --v=3
&lt;/code>&lt;/pre>
&lt;p>kube-proxy is listening on NodePort &lt;strong>30450&lt;/strong>.&lt;/p>
&lt;h3 id="create-a-non-kubernetes-process-use-the-nodeport">Create a non-kubernetes process use the NodePort&lt;/h3>
&lt;p>Now let&amp;rsquo;s kill kube-proxy process and start a server that listens on this NodePort instead.&lt;/p>
&lt;pre>&lt;code class="language-bash">$ kill -9 11558
$ python -m SimpleHTTPServer 30450 &amp;amp;
[1] 123578
$ sudo lsof -i:30450
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 123578 azureuser 3u IPv4 95854834 0t0 TCP *:30450 (LISTEN)
$ ps -aef | grep -v grep | grep 123578
azureus+ 123578 85107 0 00:49 pts/5 00:00:00 python -m SimpleHTTPServer 30450
&lt;/code>&lt;/pre>
&lt;h3 id="where-will-the-requests-to-nodeport-be-routed---pod-or-the-non-kubernetes-process">Where will the requests to NodePort be routed - pod or the non-kubernetes process?&lt;/h3>
&lt;p>While the python process is listening on port &lt;strong>30450&lt;/strong>, also allocated as a &lt;code>NodePort&lt;/code> to our kubernetes service, the iptables rules in the &lt;strong>PREROUTING&lt;/strong> chain will route all requests to port &lt;strong>30450&lt;/strong> to our pod. We can verify this as below:&lt;/p>
&lt;pre>&lt;code class="language-bash">$ curl -I -XGET localhost:30450
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Wed, 08 Jul 2020 00:53:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 950
Connection: keep-alive
&lt;/code>&lt;/pre>
&lt;p>As we send a &lt;code>GET&lt;/code> request to port &lt;strong>30450&lt;/strong>, we receive a response from an nginx server hosting &lt;strong>Azure Voting App&lt;/strong>, like we saw when
&lt;a href="#creating-pods-and-a-nodeport-service">kube-proxy was listening on port &lt;strong>30450&lt;/strong>&lt;/a>.&lt;/p>
&lt;pre>&lt;code class="language-bash">$ curl -sSL localhost:30450 | grep title
&amp;lt;title&amp;gt;Azure Voting App&amp;lt;/title&amp;gt;
&lt;/code>&lt;/pre>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;ul>
&lt;li>When kube-proxy is used in iptables mode, routing requests to &lt;strong>services&lt;/strong> continues to work for existing services even when the kube-proxy process dies on the node&lt;/li>
&lt;li>Kube-proxy binds and listens (on all k8s nodes) to all ports allocated as NodePorts to ensure these ports stay reserved and no other processes can use them&lt;/li>
&lt;li>Even if a process starts using NodePort, iptables rules (because they are in &lt;strong>PRESOUTING&lt;/strong> chain) ensure that the traffic sent to the &lt;code>NodePort&lt;/code> gets routed to the pods&lt;/li>
&lt;/ul>
&lt;h2 id="references">References&lt;/h2>
&lt;ul>
&lt;li>
&lt;a href="https://twitter.com/thockin" target="_blank" rel="noopener">@thockin&amp;rsquo;s&lt;/a> tweet,
&lt;a href="https://twitter.com/thockin/status/1191766983735296000" target="_blank" rel="noopener">describing kube-proxy iptables rules&lt;/a> in a
&lt;a href="https://docs.google.com/drawings/d/1MtWL8qRTs6PlnJrW4dh8135_S9e2SaawT410bJuoBPk/preview" target="_blank" rel="noopener">flow chart&lt;/a>, is an excellent way to holistically follow a packet&amp;rsquo;s path through various iptables rules before it reaches the destined pod.&lt;/li>
&lt;li>
&lt;a href="https://www.stackrox.com/post/2020/01/kubernetes-networking-demystified/" target="_blank" rel="noopener">Kubernetes Networking Demystified: A Brief Guide&lt;/a> is a great post explaining how kubernetes services and kubernetes networking work.&lt;/li>
&lt;/ul></description></item></channel></rss>