Skip to content

Commit

Permalink
feat: automatically limit kubelet node IP family based on service CIDRs
Browse files Browse the repository at this point in the history
Fixes #4451

If the cluster is configured e.g. only for IPv4 single-stack, kubelet
should always pick IPv4 address as the node IP. Or if the primary
service CIDR is IPv6, then node primary address should be IPv6 as well.

This fixes a case when kubelet randomly picks up KubeSpan IPv6 address
as the node address on single-stack IPv4 cluster.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
(cherry picked from commit d798635)
  • Loading branch information
smira authored and Unix4ever committed Nov 2, 2021
1 parent c873dc5 commit 2698679
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion internal/app/machined/pkg/system/services/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,17 @@ func (k *Kubelet) args(r runtime.Runtime) ([]string, error) {

extraArgs := argsbuilder.Args(r.Config().Machine().Kubelet().ExtraArgs())

nodeIPs, err := pickNodeIPs(r.Config().Machine().Kubelet().NodeIP().ValidSubnets())
validSubnets := r.Config().Machine().Kubelet().NodeIP().ValidSubnets()

// configure automatically valid subnets for IPv4/IPv6 based on service CIDRs
if len(validSubnets) == 0 {
validSubnets, err = ipSubnetsFromServiceCIDRs(r.Config().Cluster().Network().ServiceCIDRs())
if err != nil {
return nil, err
}
}

nodeIPs, err := pickNodeIPs(validSubnets)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -386,6 +396,27 @@ func writeKubeletConfig(r runtime.Runtime) error {
return ioutil.WriteFile("/etc/kubernetes/kubelet.yaml", buf.Bytes(), 0o600)
}

func ipSubnetsFromServiceCIDRs(serviceCIDRs []string) ([]string, error) {
// automatically configure valid IP subnets based on service CIDRs
// if the primary service CIDR is IPv4, primary kubelet node IP should be IPv4 as well, and so on
result := make([]string, 0, len(serviceCIDRs))

for _, cidr := range serviceCIDRs {
network, err := net.ParseCIDR(cidr)
if err != nil {
return nil, fmt.Errorf("failed to parse subnet: %w", err)
}

if network.IP.To4() == nil {
result = append(result, "::/0")
} else {
result = append(result, "0.0.0.0/0")
}
}

return result, nil
}

func pickNodeIPs(cidrs []string) ([]stdnet.IP, error) {
if len(cidrs) == 0 {
return nil, nil
Expand Down

0 comments on commit 2698679

Please sign in to comment.