Skip to content

Commit ff2c427

Browse files
committed
fix: pre-create nftables chain to make kubelet use nftables
In Talos, kubelet (and kube-proxy) images use `iptables-wrapper` script to detect which version of `iptables` (legacy or NFT) to use. The script assumes that `kubelet` runs on the host, and uses whatever version of `iptables` which is being used by the host. In Talos, `kubelet` runs in a container which has same `iptables-wrapper` script, and it defaults to `legacy` mode in our case. We can't check the `kubelet` image, as it would affect all Talos version, so instead pre-create the chains/tables in `nftables` so that kubelet will pick up `nft` version of `iptables`, and `kube-proxy` will do the same. Without this fix, the problem arises from the mix of `nft` used by Talos for the firewall and Kubernetes world relying on `legacy` (`xtables`). Fixes siderolabs/kubelet#77 See https://github.com/kubernetes-sigs/iptables-wrappers/blob/e139a115350974aac8a82ec4b815d2845f86997e/iptables-wrapper-installer.sh#L102-L130 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
1 parent 5622f0e commit ff2c427

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

hack/release.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ machine:
212212
title = "Platforms"
213213
description = """\
214214
Talos Linux now supports [Akamai Connected Cloud](https://www.linode.com/) provider (platform `akamai`).
215+
"""
216+
217+
[notes.iptables]
218+
title = "IPTables"
219+
description = """\
220+
Talos Linux now forces `kubelet` and `kube-proxy` to use `iptables-nft` instead of `iptables-legacy` (`xtables`) which was the default
221+
before Talos 1.7.0.
222+
223+
Container images based on `iptables-wrapper` should work without changes, but if there was a direct call to `legacy` mode of `iptables`, make sure
224+
to update to use `iptables-nft`.
215225
"""
216226

217227
[make_deps]

internal/app/machined/pkg/controllers/network/nftables_chain.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ func (ctrl *NfTablesChainController) Run(ctx context.Context, r controller.Runti
6565

6666
var conn nftables.Conn
6767

68+
if err := ctrl.preCreateIptablesNFTable(logger, &conn); err != nil {
69+
return fmt.Errorf("error pre-creating iptables-nft table: %w", err)
70+
}
71+
6872
list, err := safe.ReaderListAll[*network.NfTablesChain](ctx, r)
6973
if err != nil {
7074
return fmt.Errorf("error listing nftables chains: %w", err)
@@ -176,3 +180,34 @@ func (ctrl *NfTablesChainController) Run(ctx context.Context, r controller.Runti
176180
r.ResetRestartBackoff()
177181
}
178182
}
183+
184+
func (ctrl *NfTablesChainController) preCreateIptablesNFTable(logger *zap.Logger, conn *nftables.Conn) error {
185+
// Pre-create the iptables-nft table, if it doesn't exist.
186+
// This is required to ensure that the iptables universal binary prefers iptables-nft over
187+
// iptables-legacy can be used to manage the nftables rules.
188+
tables, err := conn.ListTablesOfFamily(nftables.TableFamilyIPv4)
189+
if err != nil {
190+
return fmt.Errorf("error listing existing nftables tables: %w", err)
191+
}
192+
193+
if slices.IndexFunc(tables, func(t *nftables.Table) bool { return t.Name == "mangle" }) != -1 {
194+
return nil
195+
}
196+
197+
table := &nftables.Table{
198+
Family: nftables.TableFamilyIPv4,
199+
Name: "mangle",
200+
}
201+
conn.AddTable(table)
202+
203+
chain := &nftables.Chain{
204+
Name: "KUBE-IPTABLES-HINT",
205+
Table: table,
206+
Type: nftables.ChainTypeNAT,
207+
}
208+
conn.AddChain(chain)
209+
210+
logger.Info("pre-created iptables-nft table 'mangle'/'KUBE-IPTABLES-HINT'")
211+
212+
return nil
213+
}

0 commit comments

Comments
 (0)