Calico is a pure three-layer data center network solution that seamlessly integrates with IaaS cloud architectures like OpenStack, providing controlled IP communication between VMs, containers, and bare metal. Why is it called pure three-layer? Because all data packets are routed to the corresponding hosts and containers through BGP protocol synchronization on all machines or data centers.
Simply put, Calico creates a bunch of veth pairs on the host, one end of which is on the host and the other end in the container’s network namespace. Then several routes are set up in both the container and host to complete network interconnection.
1.
Unveiling the Calico Network Model
Next, we will use specific examples to help everyone understand the communication principles of Calico network.
We will create a new busybox to learn about Calico’s network model.
The yaml file for the busybox is as follows:
|
|
Choose any node in the k8s cluster as an experimental node, enter the container POD, and check the IP address of container A.
|
|
Here, the container is obtaining a /32 host address, which means that Container A is being treated as a single-point local network. Let’s take a look at the default route for Container A.
|
|
Now here’s the problem. The routing table tells us that 169.254.1.1 is the container’s default gateway, but we can’t find any network card that corresponds to this IP address. What’s going on?
Don’t panic, let’s recall that when a packet’s destination address is not local, it queries the routing table. After finding the gateway from the routing table, it first uses ARP to get the gateway’s MAC address. Then it changes the destination MAC address in the outgoing network packet to the gateway’s MAC address, but the gateway’s IP address doesn’t appear in the network packet header. In other words, nobody cares about the actual IP address as long as the corresponding MAC address is found and can respond to ARP.
With this in mind, we can continue by using the ip neigh command to check the local ARP cache.
|
|
The MAC address should have been hard-coded into Calico and can respond to ARP requests. But how exactly was it implemented?
Let’s first recall the normal situation. The kernel sends an ARP request to ask who owns the IP address 169.254.1.1 in the entire Layer 2 network, and the device that owns this IP address returns its MAC address to the requester. But now the situation is quite embarrassing. Neither the container nor the host has this IP address, and even the port calicba2f87f6bb on the host has a useless MAC address of ee:ee:ee:ee:ee:ee. According to reason, the container and the host network cannot communicate at all. So how did Calico achieve this?
I’ll cut to the chase here. In fact, Calico leverages the proxy ARP feature of the network card. Proxy ARP is a variant of the ARP protocol. When an ARP request target crosses a network segment, the gateway device receiving the ARP request will return its own MAC address to the requester. This is called proxy ARP. For example:
In the above figure, when the computer sends an ARP request to obtain the MAC address of server 8.8.8.8, the router (gateway) receiving the request will judge that the target 8.8.8.8 does not belong to the local network segment (that is, crosses the network segment). At this time, it returns its own interface MAC address to the PC. When the computer subsequently accesses the server, the target MAC is directly encapsulated as MAC254.
Now we know that Calico essentially leverages proxy ARP to tell a “white lie”. Next, let’s confirm this by checking the host’s network card information and routing information.
|
|
Check if proxy ARP is enabled:
|
|
If you are still not confident, you can use tcpdump to capture and verify the packets.
|
|
Summary:
-
Calico cleverly directs all traffic of the workload to a special gateway IP address 169.254.1.1, which flows to the main host’s calixxx network device and ultimately converts all Layer 2 traffic into Layer 3 traffic for forwarding.
-
Enabling proxy ARP on the host implements ARP response, suppressing ARP broadcast storms and preventing ARP table inflation.
-
Simulated Networking
Since we have already mastered the networking principles of Calico, we can proceed with manual simulation verification. The architecture is shown in the figure:
First, execute the following command on Host0:
|
|
Execute the following command on Host1:
|
|
Network connectivity test:
|
|
The experiment was successful!
The specific forwarding process is as follows:
- All data packets in the ns0 network space are forwarded to a virtual IP address 169.254.1.1 and an ARP request is sent.
- When Host0’s veth port receives the ARP request, it returns its MAC address directly to ns0 by enabling the proxy ARP function of the network card.
- ns0 sends an IP packet with a destination address of ns1.
- Because an address like 169.254.1.1 is used, Host determines that it is a layer 3 routing forwarding, queries the local routing 10.20.1.3 via 192.168.1.16 dev ens192, and sends it to the other end Host1. If BGP is configured, the proto protocol will be shown as BIRD here.
- When Host1 receives the data packet of 10.20.1.3, it matches the local routing table 10.20.1.3 dev veth0 scope link, forwards the data packet to the corresponding veth0 port, and thus reaches ns1.
- The return path is similar.
Through this experiment, we can have a clear understanding of the data forwarding process of Calico network. First, a special route needs to be configured for all ns, and veth’s proxy ARP function is used to change all the forwarding from ns to layer 3 routing forwarding. Then, host routing is used for forwarding. This method not only implements layer 2 and layer 3 forwarding within the same host but also enables cross-host forwarding.