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 https://github.com/siderolabs/kubelet/issues/77
See e139a11535/iptables-wrapper-installer.sh (L102-L130)
Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
parent
5622f0e450
commit
ff2c427b04
@ -212,6 +212,16 @@ machine:
|
||||
title = "Platforms"
|
||||
description = """\
|
||||
Talos Linux now supports [Akamai Connected Cloud](https://www.linode.com/) provider (platform `akamai`).
|
||||
"""
|
||||
|
||||
[notes.iptables]
|
||||
title = "IPTables"
|
||||
description = """\
|
||||
Talos Linux now forces `kubelet` and `kube-proxy` to use `iptables-nft` instead of `iptables-legacy` (`xtables`) which was the default
|
||||
before Talos 1.7.0.
|
||||
|
||||
Container images based on `iptables-wrapper` should work without changes, but if there was a direct call to `legacy` mode of `iptables`, make sure
|
||||
to update to use `iptables-nft`.
|
||||
"""
|
||||
|
||||
[make_deps]
|
||||
|
@ -65,6 +65,10 @@ func (ctrl *NfTablesChainController) Run(ctx context.Context, r controller.Runti
|
||||
|
||||
var conn nftables.Conn
|
||||
|
||||
if err := ctrl.preCreateIptablesNFTable(logger, &conn); err != nil {
|
||||
return fmt.Errorf("error pre-creating iptables-nft table: %w", err)
|
||||
}
|
||||
|
||||
list, err := safe.ReaderListAll[*network.NfTablesChain](ctx, r)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing nftables chains: %w", err)
|
||||
@ -176,3 +180,34 @@ func (ctrl *NfTablesChainController) Run(ctx context.Context, r controller.Runti
|
||||
r.ResetRestartBackoff()
|
||||
}
|
||||
}
|
||||
|
||||
func (ctrl *NfTablesChainController) preCreateIptablesNFTable(logger *zap.Logger, conn *nftables.Conn) error {
|
||||
// Pre-create the iptables-nft table, if it doesn't exist.
|
||||
// This is required to ensure that the iptables universal binary prefers iptables-nft over
|
||||
// iptables-legacy can be used to manage the nftables rules.
|
||||
tables, err := conn.ListTablesOfFamily(nftables.TableFamilyIPv4)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing existing nftables tables: %w", err)
|
||||
}
|
||||
|
||||
if slices.IndexFunc(tables, func(t *nftables.Table) bool { return t.Name == "mangle" }) != -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
table := &nftables.Table{
|
||||
Family: nftables.TableFamilyIPv4,
|
||||
Name: "mangle",
|
||||
}
|
||||
conn.AddTable(table)
|
||||
|
||||
chain := &nftables.Chain{
|
||||
Name: "KUBE-IPTABLES-HINT",
|
||||
Table: table,
|
||||
Type: nftables.ChainTypeNAT,
|
||||
}
|
||||
conn.AddChain(chain)
|
||||
|
||||
logger.Info("pre-created iptables-nft table 'mangle'/'KUBE-IPTABLES-HINT'")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user