Installing Cilium and Multus on Talos OS for Advanced Kubernetes Networking
In a previous article, we explored deploying a highly available Kubernetes cluster using Talos OS, running on Proxmox and automated with Terraform. That setup provided a clean, immutable base for Kubernetes. However, its default networking stack—based on Flannel and kube-proxy—offers limited capabilities when it comes to modern network observability, performance tuning, or multi-interface pods.
In this guide, we’ll walk through installing Cilium as the primary CNI and Multus as a secondary CNI meta-plugin on Talos OS. This combination introduces support for advanced features such as eBPF-powered networking, per-pod visibility, and attaching pods to multiple physical or logical networks.
If you’d like to explore or reuse the configurations directly, everything is available on GitHub.
Why Kubernetes Networking Depends on CNIs
Kubernetes delegates all pod networking to external CNI plugins. These plugins are responsible for IP address allocation, routing setup, and network policy enforcement. Without a functioning CNI, Kubernetes cannot connect pods or expose services.
By default, Talos OS includes Flannel as the CNI. Flannel provides a basic overlay network that allows pod-to-pod communication across nodes, but it lacks support for native network policies and does not provide observability or performance features.
To support more demanding workloads or networking requirements, switching to a more capable CNI like Cilium is often necessary.
Choosing Cilium for eBPF-Based Kubernetes Networking
Cilium is a modern CNI built around eBPF, a Linux kernel technology that enables fast, safe, and programmable packet filtering and routing. Cilium takes advantage of eBPF to enforce network policies, accelerate service load balancing, and provide in-depth visibility into network flows—all without relying on traditional iptables or kube-proxy.
By using eBPF, Cilium can hook directly into the Linux kernel networking stack and monitor or modify packets in real time. This makes it particularly well-suited for observability, security, and performance-sensitive applications. Tools like Hubble, which integrate with Cilium, offer service maps and flow logging out of the box, providing insight into pod-level traffic that would otherwise be difficult to capture.
For clusters running Talos OS, which emphasizes minimalism and security, Cilium complements this model by offering advanced features without adding extra daemons or kernel modules.
Extending Pod Networking with Multus
Cilium is designed to be the primary CNI for the cluster, managing the default eth0
interface inside every pod. However, there are many use cases where a pod needs access to more than one network interface. This is where Multus becomes essential.
Multus is a meta-CNI that allows Kubernetes to attach additional network interfaces to pods, alongside the default one. This enables a pod to simultaneously participate in multiple networks, each managed by a different CNI plugin such as macvlan or ipvlan.
Multus is particularly helpful when workloads need to communicate with physical infrastructure, connect directly to external VLANs, or participate in L2 broadcasts or multicast traffic. For example, a pod may need to communicate with a non-containerized device on a physical subnet using ARP or mDNS, which is not typically possible through overlay networks like those created by Cilium.
Another important feature of Multus is its support for static IP addressing on secondary interfaces, which is useful in environments where predictable network identity is required. This is especially common in edge computing or environments that integrate with legacy systems.
While Cilium continues to manage the default cluster network, Multus adds the ability to layer on specialized interfaces for use cases where overlay networking alone is not enough.
Adding a Secondary NIC to Talos Worker Nodes
In the previous setup, each Kubernetes node had a single virtual NIC connected to the wlan 70
subnet. To support additional interfaces through Multus, we updated the Proxmox VM configuration to add a second NIC attached to a separate network—wlan 40
in our case.
This secondary NIC will be exposed to pods through the macvlan
plugin, allowing them to interact directly with that subnet without routing through the cluster network.
Disabling Flannel and Kube-Proxy in Talos
To make room for Cilium and avoid conflicts with the default networking stack, we updated the Talos machine configuration to remove Flannel and disable kube-proxy. This was done in the common.yaml
configuration file:
|
|
Additionally, to ensure that Talos picks the correct interface for internal communication, we specified the subnet that corresponds to the node’s primary network interface. Depending on your network setup, you may need to add a default gateway route for the same subnet with lower metric then the default one.
|
|
Make sure to modify this subnet to match your own cluster’s network layout.
Deploying Cilium During Talos Bootstrap
Because Talos starts without a CNI when Flannel is removed, it’s important to apply Cilium immediately after cluster bootstrap to restore networking. One reliable approach is to inject the Cilium manifest directly into the Talos cluster configuration as an inline manifest.
To generate the Cilium manifest, we first ensure that the Helm values file includes the exclusive: false
setting. This allows Cilium to coexist with Multus:
|
|
Then we render the manifest using Helm:
|
|
After rendering, we paste the output into the Talos configuration patch under the inlineManifests
key:
|
|
Since these manifests may contain secrets or sensitive configurations, avoid committing them to version control unless they’ve been sanitized.
Installing Multus with Talos Compatibility Patches
Once Cilium is running, we can safely install Multus as a secondary CNI plugin. However, Talos has a minimal and locked-down filesystem layout, which means that the upstream Multus DaemonSet does not work out-of-the-box. To fix this, we must apply a few Kubernetes patches using Kustomize to adapt the deployment to Talos.
We begin by downloading the upstream “thick” version of the Multus DaemonSet manifest. This version is self-contained and includes all necessary binaries:
|
|
We then create a kustomize
directory with patch files. Each patch modifies the DaemonSet in a way that makes it compatible with Talos OS.
The first patch replaces the default init container with one that correctly installs the Multus binary into the Talos filesystem:
|
|
The second patch adds a volume mount that allows Multus to access /var/run/netns
, which is required for creating network namespaces but not exposed by default in Talos:
|
|
Finally, because Talos and Cilium do not include additional CNI binaries like macvlan
or ipvlan
, we add another init container to install those into the proper path. This patch uses an official SideroLabs image for installing CNI tools:
|
|
We then define a kustomization.yaml
file that ties everything together:
|
|
With all files in place, we can build and apply the final, patched manifest like this:
|
|
This should successfully deploy the Multus DaemonSet with Talos-specific compatibility fixes applied.
If you plan to use macvlan
or ipvlan
network types in your NetworkAttachmentDefinitions
, this step is essential. Without these patches, the required binaries will be missing, and secondary networks will fail to attach.
Defining a macvlan Network for Multus
With Multus installed, we created a NetworkAttachmentDefinition
that attaches pods to the secondary interface using macvlan
. This allows the pod to communicate directly with the 192.168.40.0/24
subnet:
|
|
Deploying and Verifying a Multi-Interface Pod
We then deployed a test pod that used both the default Cilium-managed interface and the Multus-provided macvlan
interface:
|
|
To verify the pod’s interfaces, we used the following commands:
|
|
This confirmed the pod had both eth0
from Cilium and eth1
from the macvlan network, as expected.
Conclusion
By combining Cilium and Multus on Talos OS, you can achieve a Kubernetes networking setup that is both modern and flexible. Cilium brings performance and observability through eBPF, while Multus allows pods to connect to multiple networks for use cases that require Layer 2 access or static IPs.
Although this setup is more complex than using a single CNI, it opens up networking capabilities that are essential for advanced environments such as homelabs, edge deployments, or hybrid infrastructure. For teams that need visibility, isolation, and direct hardware access from Kubernetes pods, this approach can be a solid fit.
You can find all configuration files and examples in the GitHub repository
Happy engineering!