Skip to content

Update l2 pod/lb docs#2844

Open
MichalFupso wants to merge 2 commits into
tigera:mainfrom
MichalFupso:pod/lb-arp
Open

Update l2 pod/lb docs#2844
MichalFupso wants to merge 2 commits into
tigera:mainfrom
MichalFupso:pod/lb-arp

Conversation

@MichalFupso

Copy link
Copy Markdown
Contributor

Product Version(s):

Issue:

Link to docs preview:

SME review:

  • An SME has approved this change.

DOCS review:

  • A member of the docs team has approved this change.

Additional information:

Merge checklist:

  • Deploy preview inspected wherever changes were made
  • Build completed successfully
  • Test have passed

@MichalFupso MichalFupso requested a review from a team as a code owner July 9, 2026 19:24
Copilot AI review requested due to automatic review settings July 9, 2026 19:24
@netlify

netlify Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploy Preview for calico-docs-preview-next ready!

Name Link
🔨 Latest commit 2b53ead
🔍 Latest deploy log https://app.netlify.com/projects/calico-docs-preview-next/deploys/6a511fab66db93000834c9a5
😎 Deploy Preview https://deploy-preview-2844--calico-docs-preview-next.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploy Preview succeeded!

Built without sensitive environment variables

Name Link
🔨 Latest commit 2b53ead
🔍 Latest deploy log https://app.netlify.com/projects/tigera/deploys/6a511fab028f200008a92dc1
😎 Deploy Preview https://deploy-preview-2844--tigera.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 71 (🔴 down 23 from production)
Accessibility: 98 (no change from production)
Best Practices: 92 (no change from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Local Subnet L2 Reachability documentation for Calico OSS and Calico Enterprise to better describe operational constraints around LoadBalancer VIP ownership and to document additional tuning options for ARP/NDP behavior.

Changes:

  • Added new “Limitations” bullets covering externalTrafficPolicy constraints and kube-proxy IPVS strictARP requirements for LoadBalancer VIPs.
  • Updated guidance on enabling the feature to state Felix restarts automatically on change.
  • Added an optional tuning section for periodic re-announcement via localSubnetL2ReachabilityRefreshInterval.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
calico/networking/configuring/local-subnet-l2-reachability.mdx Adds LB/IPVS limitations, updates enablement/restart guidance, and introduces refresh-interval tuning.
calico-enterprise/networking/configuring/local-subnet-l2-reachability.mdx Mirrors the same LB/IPVS limitations, restart guidance, and refresh-interval tuning for Enterprise docs.

- **Cloud provider ARP filtering.** Some cloud networks (for example, AWS VPC) filter ARP at the hypervisor. The responder will not work unless the VIP/pod IPs are assigned to the node's cloud interface. This is an infrastructure constraint outside $[prodname]'s control.
- **Heterogeneous subnets.** Node selection for LoadBalancer VIPs hashes over all nodes without checking whether a node has an interface on the VIP's subnet. This is only a concern when nodes do not share the same subnets.
- **Only `externalTrafficPolicy: Cluster` is supported for LoadBalancer services.** $[prodname] elects the node that answers for a VIP with a consistent hash over all nodes, independent of where the service's backends run. Under `externalTrafficPolicy: Local` the elected node may have no local backend, so traffic that reaches it is dropped. Leave `externalTrafficPolicy` at its default of `Cluster`.
- **kube-proxy in IPVS mode requires `strictARP`.** In IPVS mode, kube-proxy binds every LoadBalancer VIP to the `kube-ipvs0` dummy interface on *all* nodes. Because the Linux kernel answers ARP for any IP configured on the host by default, every node replies for the VIP — not just the one $[prodname] elected — so external hosts receive conflicting replies from several MAC addresses. Either run kube-proxy in `iptables` or `nftables` mode, or keep IPVS mode and set `strictARP: true` (the `ipvs.strictARP` field of the kube-proxy `ConfigMap`) so the kernel stops answering ARP for the dummy-interface VIPs and leaves it to $[prodname]'s responder.
Comment on lines +75 to +79
**Optional: tune periodic re-announcement.** While the feature is enabled, Felix periodically re-announces every IP it proxies with a gratuitous ARP / unsolicited Neighbor Advertisement, keeping upstream neighbor caches and switch forwarding tables warm even when the set of proxied IPs has not changed. `localSubnetL2ReachabilityRefreshInterval` controls how often this happens (default `120s`). Lower it if your upstream devices age out ARP/NDP entries quickly, or set it to `0` to disable periodic re-announcement and keep only the one-shot announcement sent when an IP is first proxied:

```bash
kubectl patch felixconfiguration default --type='merge' \
-p '{"spec": {"localSubnetL2ReachabilityRefreshInterval": "30s"}}'
- **Cloud provider ARP filtering.** Some cloud networks (for example, AWS VPC) filter ARP at the hypervisor. The responder will not work unless the VIP/pod IPs are assigned to the node's cloud interface. This is an infrastructure constraint outside $[prodname]'s control.
- **Heterogeneous subnets.** Node selection for LoadBalancer VIPs hashes over all nodes without checking whether a node has an interface on the VIP's subnet. This is only a concern when nodes do not share the same subnets.
- **Only `externalTrafficPolicy: Cluster` is supported for LoadBalancer services.** $[prodname] elects the node that answers for a VIP with a consistent hash over all nodes, independent of where the service's backends run. Under `externalTrafficPolicy: Local` the elected node may have no local backend, so traffic that reaches it is dropped. Leave `externalTrafficPolicy` at its default of `Cluster`.
- **kube-proxy in IPVS mode requires `strictARP`.** In IPVS mode, kube-proxy binds every LoadBalancer VIP to the `kube-ipvs0` dummy interface on *all* nodes. Because the Linux kernel answers ARP for any IP configured on the host by default, every node replies for the VIP — not just the one $[prodname] elected — so external hosts receive conflicting replies from several MAC addresses. Either run kube-proxy in `iptables` or `nftables` mode, or keep IPVS mode and set `strictARP: true` (the `ipvs.strictARP` field of the kube-proxy `ConfigMap`) so the kernel stops answering ARP for the dummy-interface VIPs and leaves it to $[prodname]'s responder.
Comment on lines +75 to +79
**Optional: tune periodic re-announcement.** While the feature is enabled, Felix periodically re-announces every IP it proxies with a gratuitous ARP / unsolicited Neighbor Advertisement, keeping upstream neighbor caches and switch forwarding tables warm even when the set of proxied IPs has not changed. `localSubnetL2ReachabilityRefreshInterval` controls how often this happens (default `120s`). Lower it if your upstream devices age out ARP/NDP entries quickly, or set it to `0` to disable periodic re-announcement and keep only the one-shot announcement sent when an IP is first proxied:

```bash
kubectl patch felixconfiguration default --type='merge' \
-p '{"spec": {"localSubnetL2ReachabilityRefreshInterval": "30s"}}'

@ctauchen ctauchen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with copilot -- will you take a look? Also failing the lint check (dataplane--> data plane). And there's a build failure.

But apart from all that, looks good to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants