- When a Service is assigned an IP on the local L2 subnet (for example, 172.16.1.250), hosts on that subnet may ARP for that IP.
- With L2 announce enabled, Cilium elects a node to claim the service IP via an ARP reply using the node’s MAC.
- The external sender directs traffic to the node’s MAC; that node forwards traffic into the cluster to the service endpoints.
- Different services can be announced by different nodes, enabling per‑service placement and failover without running BGP.

- Use L2 announce when cluster nodes and external clients share the same L2 broadcast domain (same VLAN/subnet).
- Do not use L2 announce to advertise services across routed networks or different subnets — use BGP-based advertisement for routed domains.
Enable L2 announce only when your nodes and external clients are on the same broadcast domain. If your network is routed across subnets, use BGP-based advertisement instead.
Benefits and tradeoffs
- Benefits: Simple to configure for flat networks, no router adjacency or BGP required, per-service assignment and automatic failover via leases.
- Tradeoffs: Works only within the same L2 domain; not suitable for multi‑subnet/routed environments.
Enabling L2 announce
Prerequisite: kube-proxy replacement must be enabled in Cilium (required for L2 announcement). Example Cilium Helm values (or equivalent installation manifest changes):Cilium L2 Announcement Policy (CiliumL2AnnouncementPolicy)
L2 announcements are controlled per service using the CiliumL2AnnouncementPolicy CRD. A policy selects which services should be announced, which nodes are eligible to respond to ARP, which network interfaces to use, and which IP types to advertise (ExternalIPs, LoadBalancer IPs, etc). Example policy:| Field | Purpose | Example |
|---|---|---|
| serviceSelector | Selects Services by label to announce their service IPs | app: myapp |
| nodeSelector | Selects the set of nodes allowed to hold leases / respond to ARP | Exclude control-plane nodes via DoesNotExist |
| interfaces | Regex list of network interface names on which to respond to ARP | ^eth[0-9]+ matches eth0, eth1, … |
| externalIPs | When true, advertise Service ExternalIPs | true |
| loadBalancerIPs | When true, advertise LoadBalancer service IPs | true |
- The interfaces list accepts regular expressions applied to node interface names, giving fine control over which NICs will answer ARP.
- nodeSelector controls which nodes can acquire a lease for a given service IP; only eligible nodes will be chosen.
Verifying configuration and runtime state
Describe the policy to inspect spec and status:- HOLDER shows the node currently answering ARP for the service IP.
- If the holder node fails or loses eligibility, the lease will be acquired by another eligible node, which then begins responding — providing automatic failover.
Troubleshooting tips
- Confirm nodes and external clients are on the same L2 subnet/VLAN.
- Verify the interface regex matches the actual interface name (check with ip link show).
- Ensure kube-proxy replacement is enabled (kubeProxyReplacement: “strict”) before enabling l2announcements.
- Inspect Cilium logs on nodes and the cilium-operator for errors about leases or ARP handling:
- kubectl -n kube-system logs ds/cilium
- kubectl -n kube-system logs deployment/cilium-operator