Container Networking Explained: Architecture, CNI, and Troubleshooting
Container networking is the set of kernel, runtime, and platform mechanisms that lets containers discover one another, reach external services, and receive traffic from users. It is easy to demonstrate with a single docker run command, but production networking also involves address allocation, routing, encapsulation, service discovery, policy enforcement, and observability.
This guide explains the architecture behind those layers for developers, system administrators, and platform engineers. It starts with the Linux primitives shared by most implementations, then compares common networking models, explains the role of the Container Network Interface (CNI), and finishes with a practical Docker and Kubernetes troubleshooting workflow.
What Is Container Networking?
Container networking gives an isolated process a network identity and a path to other endpoints. A container may have its own network namespace, virtual Ethernet interface, IP address, routes, and firewall context. The container runtime or orchestrator connects those resources to a host network, a cluster network, or no network at all.
The important distinction is between connectivity and application behavior:
- A network makes packets deliverable between endpoints.
- Service discovery maps a stable name to changing endpoints.
- A load-balancing layer chooses among healthy endpoints.
- Network policy decides which flows are allowed.
- The application still owns authentication, authorization, retries, and data consistency.
Docker exposes these choices through network drivers. Kubernetes describes a pod-level network model and relies on a CNI implementation to provide it. For the runtime-independent interface used by Kubernetes and other orchestrators, see the CNI documentation.
Why Do Containers Need a Network Model?
Containers are deliberately short-lived. A replica can be stopped and replaced with a new instance whose IP address is different, or it can move to another host entirely. Hard-coding the address of a database, API, or worker therefore creates an operational dependency on an unstable implementation detail.
A useful container network must solve several problems at once:
- Local connectivity: Processes in separate containers on one host need isolated but routable interfaces.
- External access: Selected services need controlled ingress and egress through the host or a gateway.
- Multi-host reachability: Workloads on different nodes need a path that does not require every application to understand node placement.
- Stable discovery: Clients need names or virtual service addresses that survive replica replacement.
- Segmentation: A frontend should not automatically be able to connect to every database or administrative endpoint.
- Operability: Engineers need to inspect addresses, routes, DNS, policy, and packet flow when a request fails.
These goals conflict. Sharing the host network can reduce overhead but weakens isolation. An overlay can make multi-host placement transparent but adds encapsulation, control-plane state, and MTU constraints. A sound design chooses the smallest network scope that meets the workload’s requirements.
How Container Networking Works
The Linux building blocks
On Linux, a container commonly receives a separate network namespace. The namespace contains its own interfaces, routing table, ports, and network-related firewall state. A virtual Ethernet pair, or veth pair, connects the container namespace to the host namespace: one endpoint appears as eth0 in the container and the other is attached to a bridge or dataplane on the host.
For a bridge-based network, the packet path is roughly:
process in container
-> eth0 in the container network namespace
-> veth pair
-> host bridge or virtual dataplane
-> host routing and firewall rules
-> physical interface, gateway, or NAT
-> destination service
The runtime assigns an address and route, while the host connects the virtual interface to a larger network. Outbound traffic may be translated by NAT. Inbound traffic normally requires an explicit port publication, proxy, load balancer, or ingress rule. A container listening on port 8080 is not automatically reachable at port 8080 on the host.
The Docker networking documentation describes this model and the commands for creating, inspecting, and connecting Docker networks. A user-defined bridge is usually preferable to relying on the legacy default bridge because it provides clearer isolation and name-based discovery for the services attached to it.
Multi-host and overlay paths
When the destination is on another node, the local dataplane must locate the remote endpoint and deliver the packet over the physical underlay. An overlay keeps a logical inner packet for the container network and wraps it in an outer packet addressed to the remote node or tunnel endpoint.
container A
-> logical container network
-> local overlay endpoint
-> outer packet across the routed underlay
-> remote overlay endpoint
-> container B
Encapsulation consumes header space and can reduce the effective MTU. Firewall rules must allow the control and data-plane traffic required by the implementation, and the hosts must have routes to one another. RFC 7348 explains the VXLAN encapsulation model used by many overlay designs.
Kubernetes, pods, services, and CNI
Kubernetes applies its network model at the pod level. Containers in the same pod share a network namespace and can communicate over localhost; containers in different pods normally use pod IPs. The cluster network is expected to provide pod-to-pod reachability without requiring application-level NAT between pods. The Kubernetes networking concepts document defines these expectations.
The CNI plugin is responsible for wiring a pod to the network when it is created and removing that wiring when it is deleted. A plugin may implement routing, overlay tunnels, encryption, eBPF dataplanes, IP address management, or policy enforcement. CNI is an interface, not a single network technology, so two Kubernetes clusters can meet the same high-level model with very different dataplanes.
Kubernetes Services provide a stable virtual identity in front of changing pod endpoints. Cluster DNS turns service names into usable addresses, while kube-proxy or an equivalent dataplane programs the traffic path. A Kubernetes Service is therefore different from a pod network: the pod network delivers to pod addresses, while the Service abstraction provides stable discovery and distribution.
Network policy is a separate control layer. A policy can restrict ingress or egress based on namespaces, pod labels, IP ranges, and ports, subject to what the selected network implementation supports. The Kubernetes NetworkPolicy documentation explains the API and its limits. A policy resource does nothing if the cluster’s network implementation does not enforce it.
Network Models, Components, and Variants
The following models solve different placement and isolation problems. They should not be treated as interchangeable performance settings.
| Model | Scope | Strength | Trade-off | Typical use |
|---|---|---|---|---|
| User-defined bridge | One host | Simple isolation and service-name discovery | Does not span hosts by itself | Local application stacks |
| Host network | One host | Low virtual-network overhead | Shares host ports and reduces namespace isolation | Carefully reviewed host agents |
| Overlay | Multiple hosts | Stable logical network across nodes | Encapsulation, MTU, firewall, and control-plane complexity | Clustered multi-host workloads |
| Macvlan or ipvlan | Physical LAN segment | Direct relationship with LAN addressing | More difficult host communication and address planning | Specialized appliances |
| None | One container | Maximum network isolation | No normal connectivity | Batch or deliberately disconnected work |
| CNI-provided pod network | Cluster | Integrates IPAM, routing, policy, and orchestration | Behavior varies by plugin and configuration | Kubernetes workloads |
Address management and routing
An IP address management (IPAM) component allocates addresses and tracks subnets. Routes determine where packets go, while the dataplane implements forwarding, NAT, load balancing, or encapsulation. Overlapping container subnets with office, VPN, or cloud networks are a common source of failures because the host cannot unambiguously select a route.
Service discovery and load balancing
Discovery should be based on a service name or virtual address rather than a replica’s IP. Docker user-defined networks can resolve container names locally. Kubernetes normally uses cluster DNS and Services. Neither mechanism guarantees that an application is healthy: a name can resolve while the process is not ready, so readiness checks and connection timeouts remain necessary. The DNS lookup process guide explains how the resolver path differs from the network path that carries the eventual application request.
Network policy and encryption
Network segmentation limits accidental reachability, but it is not a replacement for identity or authorization. Use least-privilege policies for east-west traffic, restrict exposed ports, and use TLS or mutual TLS when peers need authenticated confidentiality. An overlay or private subnet may hide addresses without encrypting application data.
Real-World Use Cases
Local multi-service development
A user-defined bridge is a good fit for a local API, worker, cache, and database. Only the API or reverse proxy needs a published host port; the other services can remain reachable only through the private application network.
Clustered stateless services
An orchestrator can place replicas on different nodes while Services or an equivalent discovery layer keeps the client-facing identity stable. The network implementation must handle address allocation, endpoint changes, and node failures without requiring each application to track pod placement.
Host-level observability and packet processing
A monitoring agent, packet collector, or node-local service may need access to host interfaces. Host networking can be appropriate after reviewing privileges, port collisions, and the reduced isolation boundary. It should not be chosen merely because it is the shortest command.
Legacy network appliances
Macvlan or ipvlan can make a container appear on an existing LAN when a legacy appliance expects direct Ethernet reachability. This requires careful address allocation, switching configuration, and a tested path between the host and the attached container.
Practical Guide: Configure and Troubleshoot Container Networks
Create and inspect a Docker network
The following example creates an isolated application network, attaches two services, and publishes only the web endpoint:
docker network create --driver bridge --subnet 172.28.0.0/16 app-net
docker run -d --name api --network app-net nginx
docker run -d --name web --network app-net -p 127.0.0.1:8080:80 nginx
docker network inspect app-net
docker inspect --format '{{json .NetworkSettings.Networks}}' api
docker port web
For a real application, give the API and web containers distinct names and configure the web service to call the api service on its application port over the user-defined network. Bind development ports to 127.0.0.1 unless other clients on the host or LAN need access.
Check a Kubernetes service path
A minimal Service exposes a group of pods through a stable cluster identity:
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
ports:
- name: http
port: 80
targetPort: 8080
Useful inspection commands are:
kubectl get pods -o wide
kubectl get svc api
kubectl get endpointslice -l kubernetes.io/service-name=api
kubectl get networkpolicy --all-namespaces
kubectl describe pod <pod-name>
The EndpointSlice output tells you whether the Service has ready backends. If the Service has no endpoints, investigate selectors and readiness before debugging routes or firewall rules.
Troubleshoot in layers
Work from the smallest scope to the largest instead of changing several network settings at once:
- Process: Confirm the application is running and listening on the expected address and port. A process bound only to
127.0.0.1inside a container cannot receive traffic through its container interface. - Attachment: Verify that the container or pod is connected to the expected network and has an address.
- Discovery: Resolve the service name from the same network or namespace. Check DNS configuration and search domains.
- Policy: Review Docker isolation, host firewalls, Kubernetes NetworkPolicies, security groups, and egress controls.
- Path: Compare routes, MTU, published ports, load-balancer rules, and overlay endpoint reachability.
- Application: Check HTTP status, TLS certificates, authentication, timeouts, and dependency health.
For Docker, docker network inspect, docker inspect, docker port, and a diagnostic container with ip, getent, and nc are useful first tools. For Kubernetes, combine kubectl describe, DNS lookup from a temporary pod, EndpointSlice inspection, and the network implementation’s own diagnostics. If only cross-node traffic fails, compare node routes, tunnel firewall rules, and MTU before changing application configuration.
Common Misconceptions
“A container IP is a stable service address”
Usually not. Container and pod IPs are implementation-managed endpoints that can change during replacement or rescheduling. Use a service name, Service, load balancer, or another stable discovery mechanism.
“Publishing a port makes every container port public”
No. Port publication creates a specific host-to-container path. A service that is not published may still be reachable from an attached private network, but it is not automatically exposed on every host interface.
“An overlay is the same as encryption”
No. An overlay changes how packets are transported between endpoints. It may support encryption, but confidentiality and peer authentication must be verified in the selected implementation. Use TLS or a documented encrypted dataplane when required.
“Kubernetes NetworkPolicy always blocks traffic”
Only an enforcing network implementation can apply it, and policy behavior depends on the selected rules and traffic direction. Confirm that the CNI implementation supports the policy features being used and test both allowed and denied paths.
“Host networking is always faster”
It removes some virtual networking layers, but it also removes isolation and can create port conflicts. Measure the real workload before accepting the security and operability costs.
Related Articles
- Compare Docker bridge, host, and overlay networking drivers when selecting a single-host or multi-host Docker design.
- Learn the broader network virtualization model behind underlays, overlays, tunnels, and virtual segments.
- Review Kubernetes architecture to see how pods, nodes, services, and the control plane fit together.
- Diagnose the naming layer with our DNS configuration guide for Linux.
- Apply defense-in-depth with container security best practices.

