Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Release 1.27] Take IPFamily precedence based on order #8504

Merged
merged 2 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions manifests/coredns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ spec:
selector:
k8s-app: kube-dns
clusterIP: %{CLUSTER_DNS}%
clusterIPs: %{CLUSTER_DNS_LIST}%
ports:
- name: dns
port: 53
Expand All @@ -215,3 +216,4 @@ spec:
- name: metrics
port: 9153
protocol: TCP
ipFamilyPolicy: %{CLUSTER_DNS_IPFAMILYPOLICY}%
1 change: 1 addition & 0 deletions manifests/metrics-server/metrics-server-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ spec:
name: https
protocol: TCP
targetPort: https
ipFamilyPolicy: PreferDualStack
10 changes: 3 additions & 7 deletions pkg/agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,22 +557,18 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
nodeConfig.Certificate = servingCert

nodeConfig.AgentConfig.NodeIPs = nodeIPs
nodeIP, listenAddress, _, err := util.GetFirstIP(nodeIPs)
listenAddress, _, _, err := util.GetDefaultAddresses(nodeIPs[0])
if err != nil {
return nil, errors.Wrap(err, "cannot configure IPv4/IPv6 node-ip")
}
nodeConfig.AgentConfig.NodeIP = nodeIP.String()
nodeConfig.AgentConfig.NodeIP = nodeIPs[0].String()
nodeConfig.AgentConfig.ListenAddress = listenAddress
nodeConfig.AgentConfig.NodeExternalIPs = nodeExternalIPs

// if configured, set NodeExternalIP to the first IPv4 address, for legacy clients
// unless only IPv6 address given
if len(nodeConfig.AgentConfig.NodeExternalIPs) > 0 {
nodeExternalIP, _, _, err := util.GetFirstIP(nodeConfig.AgentConfig.NodeExternalIPs)
if err != nil {
return nil, errors.Wrap(err, "cannot configure IPv4/IPv6 node-external-ip")
}
nodeConfig.AgentConfig.NodeExternalIP = nodeExternalIP.String()
nodeConfig.AgentConfig.NodeExternalIP = nodeConfig.AgentConfig.NodeExternalIPs[0].String()
}

nodeConfig.NoFlannel = nodeConfig.FlannelBackend == config.FlannelBackendNone
Expand Down
3 changes: 2 additions & 1 deletion pkg/agent/flannel/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@ func createFlannelConf(nodeConfig *config.Node) error {
confJSON = strings.ReplaceAll(confJSON, "%IPV6_ENABLED%", "false")
confJSON = strings.ReplaceAll(confJSON, "%CIDR_IPV6%", emptyIPv6Network)
} else if netMode == (ipv4 + ipv6) {
confJSON = strings.ReplaceAll(confJSON, "%CIDR%", nodeConfig.AgentConfig.ClusterCIDR.String())
confJSON = strings.ReplaceAll(confJSON, "%IPV6_ENABLED%", "true")
for _, cidr := range nodeConfig.AgentConfig.ClusterCIDRs {
if utilsnet.IsIPv6(cidr.IP) {
// Only one ipv6 range available. This might change in future: https://github.com/kubernetes/enhancements/issues/2593
confJSON = strings.ReplaceAll(confJSON, "%CIDR_IPV6%", cidr.String())
} else {
confJSON = strings.ReplaceAll(confJSON, "%CIDR%", cidr.String())
}
}
} else {
Expand Down
7 changes: 6 additions & 1 deletion pkg/agent/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
serviceIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ServiceCIDR)
clusterIPv6 := utilsnet.IsIPv6CIDR(nodeConfig.AgentConfig.ClusterCIDR)
nodeIPv6 := utilsnet.IsIPv6String(nodeConfig.AgentConfig.NodeIP)

// check that cluster-cidr and service-cidr have the same IP versions
if (serviceIPv6 != clusterIPv6) || (dualCluster != dualService) || (serviceIPv4 != clusterIPv4) {
return fmt.Errorf("cluster-cidr: %v and service-cidr: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.ServiceCIDRs)
}
if (clusterIPv6 && !nodeIPv6) || (dualCluster && !dualNode) || (clusterIPv4 && !nodeIPv4) {

// check that node-ip has the IP versions set in cluster-cidr
if (clusterIPv6 && !(nodeIPv6 || dualNode)) || (dualCluster && !dualNode) || (clusterIPv4 && !(nodeIPv4 || dualNode)) {
return fmt.Errorf("cluster-cidr: %v and node-ip: %v, must share the same IP version (IPv4, IPv6 or dual-stack)", nodeConfig.AgentConfig.ClusterCIDRs, nodeConfig.AgentConfig.NodeIPs)
}

enableIPv6 := dualCluster || clusterIPv6
enableIPv4 := dualCluster || clusterIPv4

Expand Down
68 changes: 17 additions & 51 deletions pkg/cli/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,10 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, serverConfig.ControlConfig.AdvertiseIP)
}

// configure ClusterIPRanges
_, _, IPv6only, _ := util.GetFirstIP(nodeIPs)
// configure ClusterIPRanges. Use default 10.42.0.0/16 or fd00:42::/56 if user did not set it
_, defaultClusterCIDR, defaultServiceCIDR, _ := util.GetDefaultAddresses(nodeIPs[0])
if len(cmds.ServerConfig.ClusterCIDR) == 0 {
clusterCIDR := "10.42.0.0/16"
if IPv6only {
clusterCIDR = "fd00:42::/56"
}
cmds.ServerConfig.ClusterCIDR.Set(clusterCIDR)
cmds.ServerConfig.ClusterCIDR.Set(defaultClusterCIDR)
}
for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ClusterCIDR) {
_, parsed, err := net.ParseCIDR(cidr)
Expand All @@ -315,21 +311,12 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
serverConfig.ControlConfig.ClusterIPRanges = append(serverConfig.ControlConfig.ClusterIPRanges, parsed)
}

// set ClusterIPRange to the first IPv4 block, for legacy clients
// unless only IPv6 range given
clusterIPRange, err := util.GetFirstNet(serverConfig.ControlConfig.ClusterIPRanges)
if err != nil {
return errors.Wrap(err, "cannot configure IPv4/IPv6 cluster-cidr")
}
serverConfig.ControlConfig.ClusterIPRange = clusterIPRange
// set ClusterIPRange to the first address (first defined IPFamily is preferred)
serverConfig.ControlConfig.ClusterIPRange = serverConfig.ControlConfig.ClusterIPRanges[0]

// configure ServiceIPRanges
// configure ServiceIPRanges. Use default 10.43.0.0/16 or fd00:43::/112 if user did not set it
if len(cmds.ServerConfig.ServiceCIDR) == 0 {
serviceCIDR := "10.43.0.0/16"
if IPv6only {
serviceCIDR = "fd00:43::/112"
}
cmds.ServerConfig.ServiceCIDR.Set(serviceCIDR)
cmds.ServerConfig.ServiceCIDR.Set(defaultServiceCIDR)
}
for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ServiceCIDR) {
_, parsed, err := net.ParseCIDR(cidr)
Expand All @@ -339,13 +326,8 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
serverConfig.ControlConfig.ServiceIPRanges = append(serverConfig.ControlConfig.ServiceIPRanges, parsed)
}

// set ServiceIPRange to the first IPv4 block, for legacy clients
// unless only IPv6 range given
serviceIPRange, err := util.GetFirstNet(serverConfig.ControlConfig.ServiceIPRanges)
if err != nil {
return errors.Wrap(err, "cannot configure IPv4/IPv6 service-cidr")
}
serverConfig.ControlConfig.ServiceIPRange = serviceIPRange
// set ServiceIPRange to the first address (first defined IPFamily is preferred)
serverConfig.ControlConfig.ServiceIPRange = serverConfig.ControlConfig.ServiceIPRanges[0]

serverConfig.ControlConfig.ServiceNodePortRange, err = utilnet.ParsePortRange(cfg.ServiceNodePortRange)
if err != nil {
Expand All @@ -364,12 +346,13 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
// If there are no IPv4 ServiceCIDRs, an IPv6 ServiceCIDRs will be used.
// If neither of IPv4 or IPv6 are found an error is raised.
if len(cmds.ServerConfig.ClusterDNS) == 0 {
clusterDNS, err := utilsnet.GetIndexedIP(serverConfig.ControlConfig.ServiceIPRange, 10)
if err != nil {
return errors.Wrap(err, "cannot configure default cluster-dns address")
for _, svcCIDR := range serverConfig.ControlConfig.ServiceIPRanges {
clusterDNS, err := utilsnet.GetIndexedIP(svcCIDR, 10)
if err != nil {
return errors.Wrap(err, "cannot configure default cluster-dns address")
}
serverConfig.ControlConfig.ClusterDNSs = append(serverConfig.ControlConfig.ClusterDNSs, clusterDNS)
}
serverConfig.ControlConfig.ClusterDNS = clusterDNS
serverConfig.ControlConfig.ClusterDNSs = []net.IP{serverConfig.ControlConfig.ClusterDNS}
} else {
for _, ip := range util.SplitStringSlice(cmds.ServerConfig.ClusterDNS) {
parsed := net.ParseIP(ip)
Expand All @@ -378,15 +361,10 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
}
serverConfig.ControlConfig.ClusterDNSs = append(serverConfig.ControlConfig.ClusterDNSs, parsed)
}
// Set ClusterDNS to the first IPv4 address, for legacy clients
// unless only IPv6 range given
clusterDNS, _, _, err := util.GetFirstIP(serverConfig.ControlConfig.ClusterDNSs)
if err != nil {
return errors.Wrap(err, "cannot configure IPv4/IPv6 cluster-dns address")
}
serverConfig.ControlConfig.ClusterDNS = clusterDNS
}

serverConfig.ControlConfig.ClusterDNS = serverConfig.ControlConfig.ClusterDNSs[0]

if err := validateNetworkConfiguration(serverConfig); err != nil {
return err
}
Expand Down Expand Up @@ -577,18 +555,6 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont

// validateNetworkConfig ensures that the network configuration values make sense.
func validateNetworkConfiguration(serverConfig server.Config) error {
// Dual-stack operation requires fairly extensive manual configuration at the moment - do some
// preflight checks to make sure that the user isn't trying to use flannel/npc, or trying to
// enable dual-stack DNS (which we don't currently support since it's not easy to template)
dualDNS, err := utilsnet.IsDualStackIPs(serverConfig.ControlConfig.ClusterDNSs)
if err != nil {
return errors.Wrap(err, "failed to validate cluster-dns")
}

if dualDNS == true {
return errors.New("dual-stack cluster-dns is not supported")
}

switch serverConfig.ControlConfig.EgressSelectorMode {
case config.EgressSelectorModeCluster, config.EgressSelectorModePod:
case config.EgressSelectorModeAgent, config.EgressSelectorModeDisabled:
Expand Down
5 changes: 2 additions & 3 deletions pkg/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
"github.com/k3s-io/k3s/pkg/cluster/managed"
"github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/etcd"
"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/kine/pkg/endpoint"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
utilsnet "k8s.io/utils/net"
)

type Cluster struct {
Expand Down Expand Up @@ -54,8 +54,7 @@ func (c *Cluster) Start(ctx context.Context) (<-chan struct{}, error) {
clientURL.Host = clientURL.Hostname() + ":2379"
clientURLs = append(clientURLs, clientURL.String())
}
IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(c.config.ServiceIPRanges)
etcdProxy, err := etcd.NewETCDProxy(ctx, true, c.config.DataDir, clientURLs[0], IPv6OnlyService)
etcdProxy, err := etcd.NewETCDProxy(ctx, true, c.config.DataDir, clientURLs[0], utilsnet.IsIPv6CIDR(c.config.ServiceIPRanges[0]))
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/daemons/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"sync"
"time"

"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/kine/pkg/endpoint"
"github.com/rancher/wrangler/pkg/generated/controllers/core"
"github.com/rancher/wrangler/pkg/leader"
Expand Down Expand Up @@ -251,7 +250,7 @@ func (c *Control) BindAddressOrLoopback(chooseHostInterface, urlSafe bool) strin
// service CIDRs indicate an IPv4/Dual-Stack or IPv6 only cluster. If the urlSafe
// parameter is true, IPv6 addresses are enclosed in square brackets, as per RFC2732.
func (c *Control) Loopback(urlSafe bool) string {
if IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(c.ServiceIPRanges); IPv6OnlyService {
if utilsnet.IsIPv6CIDR(c.ServiceIPRange) {
if urlSafe {
return "[::1]"
}
Expand Down
Loading