Kubernetes Networking
by Maegan Jong and Dominik Tornow
Kubernetes is a Container Orchestration Engine designed to host containerized applications on a set of nodes, commonly referred to as a cluster. Using a systems modeling approach, this series aims to advance the understanding of Kubernetes and its underlying concepts.
For this blog post, a basic understanding of Kubernetes and Networking is recommended.
Related
Kubernetes Networking is a core abstraction of Kubernetes. In a nutshell, the Kubernetes Networking Model guarantees that all Kubernetes Pods on a cluster are able to communicate. In addition, on top of the Kubernetes Networking Model, Kubernetes provides additional core abstractions, Kubernetes Services and Kubernetes Ingress.
Using a systems modeling approach, this blog post will explore Kubernetes Networking. Here, we will develop a concise mental model to reason about Container-to-Container and Pod-to-Pod communication. Future blog posts will explore Kubernetes Services and Kubernetes Ingress.
All models are wrong, but some models are useful
1. How To Think About Networking
Without a doubt, networking is a vast and complex field that demands years of theory and practice to claim proficiency. However, here we reason about networking on a conceptual level, skipping a host of details that would be necessary if we reasoned on an implementation level.
Figure 1. illustrates a network as a Network Graph that consists of a set of Nodes and a set of Links between the Nodes: One Node may exchange a message with another Node if and only if there exists a link between the Nodes.
A Node, the Source, exchanges a message with another Node, the Target, by placing the message in the Target’s input queue. The message exchange is represented by a Send Event, Send●M, observed at the Source, and a corresponding Receive Event, Recv●M, observed at the Target.
A Node in the network is either a Process or a Switch. Processes produce and consume messages, Switches process messages according to their Forward Information Base (FIB).
Figure 2. illustrates the Forward Information Base of Switch S1 and S2. On receiving a message, each Switch consults its Forward Information Base to determine whether to deliver, forward, or discard the message.
The Switch
- matches the message’s header, that is, the source address, source port, target address, and target port with its Forward Information Base
- performs the associated action, discarding being the default.
In the next blog post Kubernetes Services, we will extend the model of a Switch to allow for Network Address Translation.
2. Kubernetes Networking Model
The Kubernetes Networking Model is a descriptive networking model, that is, any network that satisfies the specification of the Kubernetes Networking Model is a Kubernetes Network.
However, Kubernetes does not prescribe how to implement the Networking Model. In fact, many alternative implementations, called Network Plugins, exist today.
This section describes the Kubernetes Networking Model in terms of a set of constraints on message exchange.
2.1. Constraint ●
Network Addressable Entities
The Kubernetes Networking Model defines three Addressable Entities, K8s Pods, K8s Nodes, and K8s Services, where each unique entity is associated with a unique IP Address.
∧ (K8s-Pod(E₁) ∨ K8s-Node(E₁) ∨ K8s-Service(E₁))
∧ (K8s-Pod(E₂) ∨ K8s-Node(E₂) ∨ K8s-Service(E₂)):
addr(E₁, a) ∧ addr(E₂, a)
⟺ E₁ = E₂
However, the Networking Model does not make any further statements about these IP Addresses. For example, the Kubernetes Networking Model does not make any further statements about the IP Address Spaces these IP Addresses are drawn from.
2.2. Constraint ●
Container to Container Communication
The Kubernetes Networking model requires that a Container C₁ executing in the context of a Pod P can communicate with any other Container C₂ executing in the context of P via localhost.
K8s-Pod(P) ∧ K8s-Container(C₁, P) ∧ K8s-Container(C₂, P):
open(C₂, p)
⟹
Send(e, C₁, 127.0.0.1, _, 127.0.0.1, p)
⟹
Recv(e, C₂, 127.0.0.1, _, 127.0.0.1, p)
2.3. Constraint ●
Pod to Pod
The Kubernetes Networking model requires that a Container C₁ executing in the context of a Pod P₁ can communicate with any other Container C₂ executing in the context of a Pod P₂ via the address of the P₂.
∧ K8s-Pod(P₁) ∧ K8s-Container(C₁, P₁)
∧ K8s-Pod(P₂) ∧ K8s-Container(C2, P₂):
addr(P₁, sa) ∧ addr(P₁, ta) ∧ open(C₂, tp)
⟹
Send(e, C₁, sa, sp, ta, tp)
⟹
Recv(e, C₂, sa, sp, ta, tp)
2.4. Constraint ●
Process to Pod
The Kubernetes Networking model requires that a Process, called a Daemon D, hosted on a Node N, can communicate with any Container C executing in the context of a Pod P hosted on N via the address of the P.
K8s-Node(N) ∧ K8s-Daemon(D) ∧ K8s-Pod(P) ∧ K8s-Container(C, P):
host(N, D) ∧ host(N, P) ∧ addr(P, a) ∧ open(C, p)
⟹
Send(e, D, _, _, a, p)
⟹
Recv(e, C, _, _, a, p)
3. Kubernetes Networks as Network Graphs
This section describes the Kubernetes Networking Model in terms of a Kubernetes Network Graph, an idealized model.
Figure 5. illustrates the example used in this section: A Kubernetes Cluster K₁ that consists of two Nodes. Each Node hosts two Pods. Each Pod executes two Containers, one Container listening on port 8080, one Container listening on port 9090. Additionally, each Node hosts one Daemon.
We can model a Kubernetes Cluster Network as a Graph with a set of Nodes and a set of Links.
3.1 Nodes
- Every K8s Container C maps to a Network Process C
K8s-Pod(P) ∧ K8s-Container(C, P):
Process(C)
- Every Daemon D maps to a Network Process C
K8s-Daemon(D):
Process(D)
- Every K8s Pod P maps to a Network Switch P, the Pod Switch
K8s-Pod(P):
Switch(P)
- Every K8s Node N maps to a Network Switch N, the Node Switch
K8s-Pod(N):
Switch(N)
3.2 Links
- Each Container C is linked to its Pod Switch P
K8s-Pod(P) ∧ K8s-Container(C, P):
link(C, P)
- Each Daemon D is linked to its Node Switch N
K8s-Node(N) ∧ K8s-Daemon(D):
host(N, D)
⟹
link(D, N)
- Each Pod Switch P is linked to its Node Switch N
K8s-Node(N) ∧ K8s-Pod(P):
host(N, P)
⟹
link(P, N)
- Each Node Switch N₁ is linked to every other Node Switch N₂
K8s-Node(N₁) ∧ K8s-Node(N₂):
N₁ ≠ N₂
⟹
link(N₁, N₂)
3.3 Forward Information Base at the Pod Switch
1. Delivery on localhostK8s-Pod(P) ∧ K8s-Container(C, P):
open(C, p)
⟹
[* * 127.0.0.1 p Deliver(C)] in FIB[P]2. Delivery on Pod AddressK8s-Pod(P) ∧ K8s-Container(C, P):
addr(P, a) ∧ open(C, p)
⟹
[* * a p Deliver(C)] in FIB[P]3. Local Forwarding RuleK8s-Node(N) ∧ K8s-Pod(P):
host(N, P)
⟹
[* * * * Forward(N)] in FIB[P]
3.4 Forward Information Base at the Node Switch
1. Node to Pod Forwarding RuleK8s-Node(N) ∧ K8s-Pod(P):
host(N, P) ∧ addr(P, a)
⟹
[* * a * Forward(P)] in FIB[N]2. Node to Node Forwalding RuleK8s-Node(N₁) ∧ K8s-Node(N₂) ∧ K8s-Pod(P):
N₁ ≠ N₂ ∧ host(N₂, P) ∧ addr(P, a)
⟹
[* * a * Forward(N₂)] in FIB[N₁]
Examples
This section walks through some examples and follows the Life of a Message in the Kubernetes Cluster Network K₁.
Container to Container
Here, Container C₁.₁ needs to communicate with Container C₁.₂:
- C₁.₁ executes in the context of Pod P₁
- C₁.₂ executes in the context of Pod P₁
Pod to Pod Communication, Intra Node
Here, Container C₁.₁ needs to communicate with Container C₃.₁:
- C₁.₁ executes in the context of Pod P₁ which is hosted on Node N₁.
- C₃.₁ executes in the context of Pod P₃ which is hosted on Node N₁.
Pod to Pod Communication, Inter Node
Here, Container C₁.₁ needs to communicate with Container C₂.₁:
- C₁.₁ executes in the context of Pod P₁ which is hosted on Node N₁.
- C₂.₁ executes in the context of Pod P₂ which is hosted on Node N₂.
Deamon to Pod Communication
Here, Daemon D₁ needs to communicate with Container C₁.₁:
- D₁ is hosted on Node N₁.
- C₁.₁ executes in the context of Pod P₁ which is hosted on Node N₁.
Conclusion
The Kubernetes Networking Model is a permissive networking model, that is, any network that satisfies the constraints of the Kubernetes Networking Model is a valid Kubernetes Network.
Mapping the Kubernetes Networking Model to a Networking Graph enables us to reason about the network on a conceptual level, skipping a host of details that would be necessary if we reasoned on an implementation level.
In subsequent blog posts, we will reuse this Networking Graph to discuss Kubernetes Services, Kubernetes Ingress, and Kubernetes Policies.
Thank you to Maegan Jong, Software Engineering Intern at Cisco in 2020/2021.