Skip to main content

Command Palette

Search for a command to run...

Kubernetes Networking : Part -1 : The Fundamentals

Updated
13 min read
Kubernetes Networking : Part -1 : The Fundamentals

We have covered the basics of how Kubernetes works at high level in our previous blog if you are new to kubernetes you can check this out here as this will add as a stepping stone for this Kubernetes Networking Blog series.

In this series, we will dive deep into Kubernetes networking such as: how Pods communicate with each other, why Services are needed, the different types of Services, and much more.

So, buckle up: things are about to get interesting. Let’s get started 🚀

Phase 1: How Do Pods Communicate with Each Other?

From our previous blog, we learned that a Pod is the smallest deployable unit in Kubernetes. A Pod can have one or more containers, and this is where our application actually runs.

Now, if our application is running inside a Pod, we need some way to access it, right?

This is where IP addresses come into the picture. Every Pod in Kubernetes gets its own unique IP address. And here comes one of the coolest things about Kubernetes networking Pods can communicate with other Pods in the cluster directly. No NAT. No complex routing setup. No communication barriers (by default). This concept is called the Flat Network Model.

Why is it called a Flat Network Model?

We call it a flat network because:

  • Every Pod gets a unique IP address

  • Pods can communicate with each other across nodes

  • No need for port mapping between Pods

  • Pods can directly reach other Pods without an additional networking layer

Mental model

Pod A (10.244.1.2) → Pod B (10.244.2.5)

👉 Works directly even if on different nodes

🔥 Why Did Kubernetes Choose This Networking Model?

Before we understand why Kubernetes chose this approach, let’s first see how networking usually worked in traditional container environments.

Traditional Approach: Container → NAT → Host → NAT → Another container. This adds extra networking layers, port mappings, and sometimes additional complexity.

Kubernetes Approach: Pod → Pod (direct). No manual port mapping. No complicated networking setup between Pods. Kubernetes networking is designed so Pods can directly reach each other using their IP addresses.

Benefits of This Approach

  • Simpler service discovery - Pods and Services can communicate more predictably inside the cluster.

  • No port conflict - Since every Pod gets its own IP address, multiple applications can use the same port without conflicts.

  • Cleaner Architecture - Networking becomes easier to reason about, making application communication more straightforward.

This is one of the key reasons Kubernetes is designed around a direct Pod-to-Pod communication model to make distributed systems easier to build and operate.

🔌 How Pod Networking Actually Works

So far, we learned that every Pod gets its own IP address and can communicate with other Pods in the cluster. Sounds cool, right?

But have you ever wondered what actually happens behind the scenes? How are these Pods connected? Who manages all this networking magic? Let’s break it down.

🛠️ The Behind-the-Scenes Magic

  • Every Pod Gets Its Own Network Namespace

    • Every pod gets: Its own network namespace and Its own unique IP address?

    • Network Namespace ? Think of a network namespace as a mini network environment for a Pod. It gets its own network interfaces, routing table, and network stack, isolated from other Pods. This is the reason why each Pod behaves almost like a separate machine in the cluster.

  • How Are Pods Connected?

    • Now comes the interesting part how do Pods actually talk to each other?

    • Pods are typically connected using something called veth pairs (Virtual Ethernet pairs).

    • You can think of a veth pair like a virtual network cable: One end connects to the Pod and the other end connects to the host network.

    • From there, traffic is handled using mechanisms such as Linux bridges, routing, overlay networks, or eBPF, depending on the networking solution being used. Don’t worry if this sounds complicated right now we will simplify this step by step in upcoming blogs 😄

  • Who Manages All of This?

    • This is where the real rockstar enters the stage the CNI Plugin (Container Network Interface) 🎸

    • The CNI plugin is responsible for:

      • Assigning an IP address to Pods

      • Setting up the network interfaces

      • Creating required routing/network rules

      • Handling Pod-to-Pod communication across nodes

    • In short, without a CNI plugin, Kubernetes networking simply would not work.

    • 👀 Who Are These CNI Plugins? You might have heard names like: Flannel, Calico, Cilium. These are popular CNI plugins used in Kubernetes for networking.

    • Different companies choose different networking solutions based on their needs. Some prefer simplicity, while others need advanced networking, security policies, or high performance.

Curious to know what CNI plugin your Kubernetes cluster is using? Run the below command:

kubectl get pods -n kube-system

Look for Pods with names related to networking. You might notice something familiar:

  • calico-* → Using Calico

  • cilium-* → Using Cilium

  • kube-flannel-* → Using Flannel

  • aws-node → Usually AWS VPC CNI (common in EKS)

For example, if you see Pods like cilium-xyz123, congratulations your cluster is most likely using Cilium 😄. Here is my example

🧪 Want to Try It Yourself?

If you want to do a hands on practical and see how Pod-to-Pod communication actually works, follow the document to test Pod-to-Pod communication in Kubernetes.

The BIG problem this creates

We learned in our previous blog that Pods are ephemeral in nature.

Ephemeral? This means Pods are temporary if a Pod crashes, gets deleted, or is rescheduled, Kubernetes creates a new one (usually through controllers like Deployments).

But here’s the catch when a new Pod gets created, its IP address changes. Now imagine the headache this creates 😅

If Pod IPs keep changing constantly, how can other Pods reliably communicate with them? Tracking Pod IP addresses manually would be a tedious and messy job.

This is exactly where Kubernetes Services come to the rescue. Instead of talking directly to constantly changing Pod IPs, Services provide a stable way to access Pods, even when Pods come and go behind the scenes.

Phase 2: Services — The Backbone of Kubernetes Networking

We understood one important problem with Pods: they are ephemeral.

Luckily, Kubernetes has a smart solution for this problem Services. But the big question is: How do Services actually solve this issue?

How Services Resolve This Problem 🤔 ?

A Kubernetes Service provides:

  • A Stable Virtual IP

  • A Stable DNS name

This stable identity dynamically maps to the Pods running your application. Think of it like this:

  • Instead of applications directly talking to Pod IPs (which keep changing), they talk to a Service.

  • The Service acts like a stable entry point and forwards requests to the correct Pods behind the scenes.

So, your setup looks something like this: pod-b → Service → pod-a (new Pod)

Every Pod created by your application (usually managed by a Deployment) gets connected to the Service through labels and selectors.

The important part? The Service IP and DNS name stay stable, even if Pods are destroyed and recreated. We will learn how Kubernetes actually does this magic behind the scenes shortly 😄

Why Is This Powerful?

No matter how many times your Pods restart… No matter what new IP addresses your Pods get… Your application always talks to the Service, not directly to the Pods. The Service takes care of routing your request to the correct Pod and returning the response.

✨ How Kubernetes Services Actually Do the Magic

Now comes the interesting part how does a Kubernetes Service actually take your request to the right Pod? Until now, we learned that Services provide a stable IP and DNS name. But what’s happening behind the scenes that makes this possible? Let’s break it down step by step.

The Basics

We already know what a Deployment is. A Deployment manages multiple replicas of your application and takes care of things like: Auto healing (self-recovery), Rolling Updates and Scaling

Let’s say you deploy your application with 3 replicas. What happens next?

The Flow Behind the Scenes

API Server → ETCD → Controller Manager → Scheduler → Kubelet → Container Runtime + CNI

Let’s understand this one by one:

You create a Deployment: You apply your Deployment manifest.

  • API Server updates ETCD: The API Server stores the desired state of the Deployment inside ETCD (Kubernetes' database).

  • Controller Manager notices the Deployment: The Controller Manager sees that 3 replicas are required and starts creating them.

  • Scheduler assigns Nodes: The Scheduler notices new Pods are created but not assigned to any Node yet, so it decides where each Pod should run.

  • Kubelet starts Pod creation: The Kubelet running on each Node notices that a Pod has been assigned to it and starts the Pod creation process.

  • Container Runtime creates containers: The container runtime (like containerd or CRI-O) creates the containers.

  • CNI Plugin joins the party 🎉: The CNI plugin: Assigns IP addresses to Pods, Configures networking, Creates routes required for Pod communication

Parallely Services are created as per the manifest. And now… this is where the real magic starts 👀 Enter the EndpointSlice Controller

EndpointSlice Controller

Kubernetes has something called the EndpointSlice Controller. Its job is to continuously watch for newly created Services. When a Service is created, the controller:

  • Reads the selector labels from the Service definition

  • Finds Pods with matching labels in the same namespace

  • Collects the Pod IP addresses

  • Creates an EndpointSlice object

Think of an EndpointSlice as a list of healthy Pod IPs behind a Service. Pretty cool, right?

But Wait… It Doesn't Add Every Pod Immediately. The EndpointSlice Controller is smart. It does not blindly add Pod IPs. Instead, it checks whether the Pod is actually:

  • Running

  • Healthy

  • Ready to accept traffic

If you configure a Readiness Probe, Kubernetes waits for the Pod to become Ready = True before adding that Pod IP to the EndpointSlice. This prevents traffic from going to unhealthy Pods.

What Happens Next ?

The Kube-Proxy Show

Now kube-proxy takes over. kube-proxy watches these EndpointSlices and creates networking rules (usually using iptables or IPVS, depending on configuration). These rules make sure traffic sent to the Service gets forwarded to one of the healthy Pod IPs behind it.

In simple words: Service → kube-proxy → EndpointSlice → Healthy Pod

A Small but Important Detail: Whenever you create a Service, Kubernetes automatically creates an EndpointSlice for it.

You can actually see them using: kubectl get endpointslices

You’ll notice names similar to your Service name with some random suffix added.

What If a Pod Goes Down?

Imagine one Pod crashes unexpectedly. No worries — Kubernetes has your back 😄

The EndpointSlice Controller notices that the Pod is no longer healthy and removes that Pod IP from the EndpointSlice. This means traffic will stop going to the failed Pod.

When a healthy replacement Pod comes up, Kubernetes automatically adds the new Pod IP back.

So, What’s the Final Magic?

When your application receives a request:

  1. The request first hits the Service

  2. kube-proxy checks the available healthy endpoints

  3. Traffic gets routed to one of the healthy Pod IPs

  4. Your Pod processes the request and sends the response back

And the best part?

You never have to care about changing Pod IPs.

Kubernetes handles all the heavy lifting behind the scenes 🚀

🧪 Want to Try It Yourself?

If you want to do a hands on practical and see how Pod and Service actually works, follow the document to test Pod and Service communication in Kubernetes.

Trust me trying it practically makes Kubernetes networking much easier to understand than just reading theory 😄

🛠️ Troubleshooting Communication Issues

Let’s see some high-level troubleshooting steps to debug Kubernetes Service related issues.

Note: These steps only cover troubleshooting from the Service layer level.

1. Check if the Service Exists

kubectl get svc

Make sure:

  • The Service exists

  • The correct port is exposed

  • The ClusterIP is assigned

2. Check Service Details

kubectl describe svc

Look for:

  • Correct selector labels

  • Correct targetPort

  • Correct exposed port

A label mismatch is one of the most common issues beginners face.

3. Check if Pods Are Running

kubectl get pods -o wide

Verify:

  • Pods are in Running state

  • Pods are READY

  • Pod IPs are assigned

4. Check EndpointSlices (Very Important 👀)

kubectl get endpointslices

kubectl describe endpointslice

This is where the real truth lives 😄 Check whether Pod IPs are actually present.

If you don’t see Pod IPs here, Kubernetes has no healthy backend to route traffic to.

5. Check Pod Labels

kubectl get pods --show-labels

Sometimes Pods exist, but labels don’t match the Service selector.

No matching labels = No endpoints.

6. Check Readiness Probe Status

kubectl describe pod

Look for:

  • Ready: True

  • Probe failures

  • Events section

If readiness checks fail, the Pod will not be added to EndpointSlice, meaning Services won’t send traffic to it.

7. Test Connectivity from Another Pod

kubectl exec -it -- sh

# Then test:

curl http://<service-name>

#or

nslookup <service-name>

This helps verify DNS and Service connectivity. Most Kubernetes networking issues can be debugged by checking these few things:

Service → Labels → Pods → EndpointSlice → kube-proxy → Connectivity

🎯 Wrapping Up — What We Learned

And there you go we just uncovered the fundamentals of Kubernetes Networking 🚀

We started with understanding how Pods communicate with each other, why Kubernetes follows a Flat Network Model, and how CNI plugins quietly handle all the networking magic behind the scenes.

Then we explored the big problem with Pods they are ephemeral, meaning their IPs keep changing. This led us to one of the most important building blocks in Kubernetes networking: Services.

We learned how Services provide:

  • A stable virtual IP

  • A stable DNS name

  • A reliable way for applications to communicate without worrying about changing Pod IPs

And finally, we went under the hood to understand the real magic:

Service → EndpointSlice → kube-proxy → Healthy Pod

Now we know how Kubernetes Services actually route traffic to the right Pods behind the scenes 😄

⏭️ What’s Next?

So far, we focused on the fundamentals and understood why Services exist and how they work behind the scenes. But Kubernetes Services come in different flavors 😄

In the next blog, we will deep dive into the Types of Kubernetes Services. Until then, happy learning and keep experimenting 🚀

Kubernetes in Detail

Part 7 of 7

Kubernetes in Detail is a comprehensive series that explains Kubernetes from the ground up. It covers all core and advanced Kubernetes concepts in depth, with clear explanations and practical insights.

Start from the beginning

Kubernetes - Volumes - Part-1

emptyDir, hostPath