Skip to content

flannel migration: document removing leftover flannel iptables rules - #2768

Open
stitrace wants to merge 4 commits into
tigera:mainfrom
stitrace:docs/flannel-migration-iptables-cleanup
Open

flannel migration: document removing leftover flannel iptables rules#2768
stitrace wants to merge 4 commits into
tigera:mainfrom
stitrace:docs/flannel-migration-iptables-cleanup

Conversation

@stitrace

@stitrace stitrace commented Jun 5, 2026

Copy link
Copy Markdown

Description

The live-migration guide tells you to delete the migration controller once migration completes, but it does not mention that flannel leaves iptables rules behind on every node.

The migration controller removes the flannel daemonset and deletes the flannel network devices (flannel.<vni>, cni0), but it does not remove the iptables chains flannel programs: FLANNEL-POSTRTG (nat) and FLANNEL-FWD (filter). These survive the migration.

The masquerade rule in FLANNEL-POSTRTG keeps SNAT-ing cross-node pod-to-pod traffic to the node's tunnel IP. This is invisible until you use NetworkPolicy: the SNAT'd source no longer matches pod-selector rules, so Calico's default-deny drops the traffic. Symptom after an otherwise successful migration: cross-node connections to policy-selected pods silently time out, while same-node traffic keeps working.

This PR adds a cleanup step after "Delete the migration controller" with an idempotent flush command (legacy + nft backends) and a reboot alternative.

Notes

Reproduction

After migrating, on any node: nft list chain ip nat POSTROUTING still shows jump FLANNEL-POSTRTG with non-zero counters; a cross-node listener sees the client's source as the sender node's tunnel IP (<block>.0) rather than the pod IP, and NetworkPolicy-selected pods become unreachable cross-node.

@stitrace
stitrace requested a review from a team as a code owner June 5, 2026 16:52
@netlify

netlify Bot commented Jun 5, 2026

Copy link
Copy Markdown

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

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

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

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

@netlify

netlify Bot commented Jun 5, 2026

Copy link
Copy Markdown

Deploy Preview succeeded!

Built without sensitive environment variables

Name Link
🔨 Latest commit 1019f4b
🔍 Latest deploy log https://app.netlify.com/projects/tigera/deploys/6a7c4b3480a3cd0008236103
😎 Deploy Preview https://deploy-preview-2768--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 14 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
🤖 Make changes Run an agent on this branch

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

@ctauchen

ctauchen commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

@stitrace Thanks for the submission. Someone will take a look at this together with projectcalico/calico#12920

@caseydavenport

Copy link
Copy Markdown
Member

Is this an alternative to projectcalico/calico#12920 ?

With the automated removal in the linked PR, presumably we don't need manual steps?

@stitrace

Copy link
Copy Markdown
Author

Not quite an alternative — they're complementary. #12920 (projectcalico/calico#12920) automates the cleanup for migrations performed with a Calico version that includes the fix, so going forward the manual steps won't be needed.

However, the leftover chains don't clean themselves up: any cluster that already migrated with an earlier version still has the stale Flannel iptables rules sitting there, and anyone migrating on an older release will keep hitting this. For those users the docs are the only discoverable fix.

I'd suggest trimming this PR down to a short note along the lines of: "migrations performed with Calico vX.Y+ remove these rules automatically; if you migrated with an earlier version, clean them up manually as follows" — with the version filled in once the fix ships in a release. Happy to rework the PR that way if it sounds good.

@caseydavenport

Copy link
Copy Markdown
Member

Got it. Also, just a thought - for a lot of folks simply doing a rolling update of cluster nodes will be an easier way to handle this rather than scripting running these commands across a whole cluster. Might be worth taking that approach?

@stitrace

Copy link
Copy Markdown
Author

Good point, agreed. Since flannel is already gone after the migration, nothing re-creates the chains, so a rolling reboot (or node replacement in immutable/managed node setups) fully clears them.

The current text mentions rebooting only as a one-line "alternatively" at the end. I'll flip the emphasis: recommend a rolling reboot/replacement of nodes as the primary approach, and keep the script as an option for clusters where cycling every node is impractical, or when you need to restore cross-node traffic immediately without waiting for a full node roll (the SNAT breakage affects live traffic until the rules are gone).

I'll push an update shortly.

@CLAassistant

CLAassistant commented Jul 25, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@stitrace
stitrace force-pushed the docs/flannel-migration-iptables-cleanup branch from ac8072b to c123eca Compare July 25, 2026 01:21
@ctauchen

ctauchen commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks for this, @stitrace

One suggestion on the step's shape. The rest of this guide keeps each step to one imperative line plus a code block, so the five paragraphs of lead-in here read as heavy by comparison. The two methods are the valuable part and they get a bit buried. I'd trim the exposition but keep both methods as a clear either/or:

1. Remove leftover flannel `iptables` rules from each node.

   The migration controller deletes the flannel devices but leaves flannel's `iptables` chains (`FLANNEL-POSTRTG` in `nat`, `FLANNEL-FWD` in `filter`) in place. Their masquerade rule SNATs cross-node pod traffic, which breaks Kubernetes `NetworkPolicy` for policy-selected pods. Because flannel is no longer running, you only need to clear the chains once. Use either method:

   **Method 1: Reboot or replace nodes**

   Perform a rolling reboot (drain, reboot, uncordon each node in turn), or replace the nodes if you use immutable or managed node pools. The rules do not persist across a reboot, so no work on the nodes is needed.

   **Method 2: Remove the chains in place**

   Run the following on every node. It takes effect immediately without disrupting workloads, covers both the legacy and nft backends, and is safe to re-run:

   (unchanged command block)

This change currently targets 3.33+. Does this need to be applied also to previous versions?

@stitrace

Copy link
Copy Markdown
Author

Thanks — applied your restructure in 24c425a. The step is now one mechanism paragraph plus the two methods as an explicit either/or, with a single sentence of rationale each; the command block is unchanged. Net is 44 → 21 added lines.

On the backport question: the page is byte-identical across calico/ and all four versioned snapshots (3.29, 3.30, 3.31, 3.32) apart from the frontmatter description, so this block drops into each of them cleanly with no adaptation. The issue itself affects every released version — the leftover chains are left behind by any migration done before the controller fix (projectcalico/calico#12920, approved and awaiting merge), and clusters already migrated stay broken until someone clears them, so the guidance is arguably most useful on the versioned pages people are actually reading.

I've kept this PR to calico/ only. Happy to push the same block to 3.29–3.32 here, or to whichever subset you consider still in scope — just say which and I'll add it.

One note on the failing checks: the tigera Netlify deploy is failing on this PR while calico-docs-preview-next builds and previews fine (preview). Looks unrelated to the content of this change, but flagging it in case it needs a maintainer to re-run.

@ctauchen

Copy link
Copy Markdown
Collaborator

considering that the fix will likely land in 3.33, then we should remove this change from calico/ (because the fix removes the requirement) and add the change to all the versioned directories.

I suspect the build will correct itself if you fetch and rebase your PR. @stitrace

The live-migration controller removes the flannel daemonset and deletes the
flannel network devices, but it does not remove the iptables chains flannel
programs (FLANNEL-POSTRTG in nat, FLANNEL-FWD in filter). These survive the
migration and the FLANNEL-POSTRTG masquerade rule keeps SNAT-ing cross-node
pod-to-pod traffic to the node tunnel IP, which silently breaks NetworkPolicy
after migration. Add a cleanup step (with a reboot alternative) so operators
can remove the leftover rules.
The controller-side fix lands in 3.33, so the manual step is only
needed for clusters migrated with 3.29-3.32.
@stitrace
stitrace force-pushed the docs/flannel-migration-iptables-cleanup branch from 24c425a to 1019f4b Compare August 12, 2026 10:30
@stitrace

Copy link
Copy Markdown
Author

Done — rebased on main and restructured as you described. The PR is now +96 across 4 files, all under calico_versioned_docs/ (3.29, 3.30, 3.31, 3.32); calico/ is untouched, so 3.33 ships without the manual step once the controller fix lands. The inserted block is identical in each version and sits in the same position — right after "Delete the migration controller".

You were right about the build: the rebase picked up ~30 commits of main and the Netlify checks are re-running clean so far.

One edge case worth a second opinion, not a blocker: the controller fix cleans up during migration, so it helps clusters migrating on 3.33. A cluster that migrated on 3.31 and later upgrades to 3.33 still carries the leftover chains, and its operators will be reading the 3.33 page, which no longer mentions them. If you think that's worth covering, the natural home is a short note in the 3.33 release notes or upgrade guide rather than the migration page — happy to open a follow-up for that. Otherwise this is ready as-is.

@ctauchen

Copy link
Copy Markdown
Collaborator

@caseydavenport PTAL, I think this is good to go. Anything else to add?

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