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.26] Fix tailscale bug with ip modes #8097

Merged
merged 1 commit into from Aug 3, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 16 additions & 4 deletions pkg/agent/config/config.go
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/rancher/wrangler/pkg/slice"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/json"
utilsnet "k8s.io/utils/net"
)

const (
Expand Down Expand Up @@ -405,14 +406,25 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
return nil, err
}

// Pass ipv4, ipv6 or both depending on nodeIPs mode
var vpnIPs []net.IP
if vpnInfo.IPv4Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv4Address)
dualNode, err := utilsnet.IsDualStackIPs(nodeIPs)
if err != nil {
return nil, errors.Wrapf(err, "failed to validate node-ip: %v", nodeIPs)
}
if vpnInfo.IPv6Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv6Address)
if dualNode && vpnInfo.IPv4Address != nil && vpnInfo.IPv6Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv4Address, vpnInfo.IPv6Address)
} else {
if utilsnet.IsIPv4(nodeIPs[0]) && vpnInfo.IPv4Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv4Address)
} else if utilsnet.IsIPv6(nodeIPs[0]) && vpnInfo.IPv6Address != nil {
vpnIPs = append(vpnIPs, vpnInfo.IPv6Address)
} else {
return nil, errors.Errorf("address family mismatch when assigning VPN addresses to node: node=%v, VPN ipv4=%v ipv6=%v", nodeIPs, vpnInfo.IPv4Address, vpnInfo.IPv6Address)
}
}

// Overwrite nodeip and flannel interface and throw a warning if user explicitly set those parameters
if len(vpnIPs) != 0 {
logrus.Infof("Node-ip changed to %v due to VPN", vpnIPs)
if len(envInfo.NodeIP) != 0 {
Expand Down
40 changes: 24 additions & 16 deletions pkg/cli/server/server.go
Expand Up @@ -223,16 +223,36 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
serverConfig.ControlConfig.PrivateIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP)
}

// Ensure that we add the localhost name/ip and node name/ip to the SAN list. This list is shared by the
// certs for the supervisor, kube-apiserver cert, and etcd. DNS entries for the in-cluster kubernetes
// service endpoint are added later when the certificates are created.
nodeName, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP)
if err != nil {
return err
}
serverConfig.ControlConfig.ServerNodeName = nodeName
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, "127.0.0.1", "::1", "localhost", nodeName)
for _, ip := range nodeIPs {
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, ip.String())
}

// if not set, try setting advertise-ip from agent VPN
if cmds.AgentConfig.VPNAuth != "" {
vpnInfo, err := vpn.GetVPNInfo(cmds.AgentConfig.VPNAuth)
if err != nil {
return err
}

logrus.Debugf("Processing vpn node-ip based on the detected nodeIPs: %v", nodeIPs)
dualNode, err := utilsnet.IsDualStackIPs(nodeIPs)
if err != nil {
return errors.Wrapf(err, "failed to validate node-ip: %v", nodeIPs)
}

// If we are in ipv6-only mode, we should pass the ipv6 address. Otherwise, ipv4
if utilsnet.IsIPv6CIDRString(util.JoinIPNets(serverConfig.ControlConfig.ClusterIPRanges)) {
if !dualNode && utilsnet.IsIPv6(nodeIPs[0]) {
if vpnInfo.IPv6Address != nil {
logrus.Infof("Advertise-address changed to %v due to VPN", vpnInfo.IPv6Address)
logrus.Infof("Changed advertise-address to %v due to VPN", vpnInfo.IPv6Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
Expand All @@ -241,8 +261,9 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
return errors.New("tailscale does not provide an ipv6 address")
}
} else {
// We are in dual-stack or ipv4-only mode
if vpnInfo.IPv4Address != nil {
logrus.Infof("Advertise-address changed to %v due to VPN", vpnInfo.IPv4Address)
logrus.Infof("Changed advertise-address to %v due to VPN", vpnInfo.IPv4Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
Expand Down Expand Up @@ -272,19 +293,6 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, serverConfig.ControlConfig.AdvertiseIP)
}

// Ensure that we add the localhost name/ip and node name/ip to the SAN list. This list is shared by the
// certs for the supervisor, kube-apiserver cert, and etcd. DNS entries for the in-cluster kubernetes
// service endpoint are added later when the certificates are created.
nodeName, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP)
if err != nil {
return err
}
serverConfig.ControlConfig.ServerNodeName = nodeName
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, "127.0.0.1", "::1", "localhost", nodeName)
for _, ip := range nodeIPs {
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, ip.String())
}

// configure ClusterIPRanges
_, _, IPv6only, _ := util.GetFirstIP(nodeIPs)
if len(cmds.ServerConfig.ClusterCIDR) == 0 {
Expand Down