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

Add extra check before acquiring lease #1937

Merged
merged 1 commit into from
Apr 12, 2024
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: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ else
endif

# Go version to use for builds
GO_VERSION=1.20
GO_VERSION=1.21

# K8s version used for Makefile helpers
K8S_VERSION=1.24.6
Expand Down
40 changes: 27 additions & 13 deletions pkg/backend/vxlan/device_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,9 @@ func ensureNetwork(expectedNetwork *hcn.HostComputeNetwork, expectedAddressPrefi
return nil, errors.Wrapf(lastErr, "timeout, failed to get management IP from HostComputeNetwork %s", networkName)
}

managementIP := getManagementIP(newNetwork)
// Wait for the interface with the management IP
log.Infof("Waiting to get net interface for HostComputeNetwork %s (%s)", networkName, managementIP)
managementIPv4, err := ip.ParseIP4(managementIP)
err = checkHostNetworkReady(newNetwork)
if err != nil {
return nil, errors.Wrapf(err, "Failed to parse management ip (%s)", managementIP)
}

waitErr = wait.Poll(2000*time.Millisecond, 20*time.Second, func() (done bool, err error) {
_, lastErr = ip.GetInterfaceByIP(managementIPv4.ToIP())
return lastErr == nil, nil
})
if waitErr == wait.ErrWaitTimeout {
return nil, errors.Wrapf(lastErr, "timeout, failed to get net interface for HostComputeNetwork %s (%s)", networkName, managementIP)
return nil, errors.Wrapf(err, "Interface bound to %s took too long to get ready. Please check your network host configuration", networkName)
}

log.Infof("Created HostComputeNetwork %s", networkName)
Expand Down Expand Up @@ -236,3 +225,28 @@ func addNetAdapterName(network *hcn.HostComputeNetwork, netAdapterName string) e

return nil
}

// checkHostNetworkReady waits for the host network to be ready: the main interface must be up and have an IP address
func checkHostNetworkReady(network *hcn.HostComputeNetwork) error {
managementIP := getManagementIP(network)
// Wait for the interface with the management IP
log.Infof("Waiting to get net interface for HostComputeNetwork %s (%s)", network.Name, managementIP)
managementIPv4, err := ip.ParseIP4(managementIP)
if err != nil {
return errors.Wrapf(err, "Failed to parse management ip (%s)", managementIP)
}

waitErr := wait.Poll(3*time.Second, 25*time.Second, func() (done bool, err error) {
iface, lastErr := ip.GetInterfaceByIP(managementIPv4.ToIP())
if lastErr == nil {
log.V(2).Infof("Host interface: %s bound by %s ready", iface.Name, network.Name)
return true, nil
}
log.V(2).Infof("Host interface bound by %s not ready", network.Name)
return false, nil
})
if waitErr == wait.ErrWaitTimeout {
return errors.Wrapf(waitErr, "timeout, failed to get net interface for HostComputeNetwork %s (%s)", network.Name, managementIP)
}
return nil
}
18 changes: 12 additions & 6 deletions pkg/backend/vxlan/vxlan_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func newSubnetAttrs(publicIP net.IP, vnid uint16, mac net.HardwareAddr) (*lease.
}
data, err := json.Marshal(&leaseAttrs)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to marshal vxlanLeaseAttrs: %w", err)
}

return &lease.LeaseAttrs{
Expand Down Expand Up @@ -153,7 +153,7 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg *sync.WaitGroup,

dev, err := newVXLANDevice(&devAttrs)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to create VXLAN network: %w", err)
}
dev.directRouting = cfg.DirectRouting
dev.macPrefix = cfg.MacPrefix
Expand All @@ -165,7 +165,7 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg *sync.WaitGroup,

hcnNetwork, err := hcn.GetNetworkByName(cfg.Name)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to get HNS network: %w", err)
}

var newDrMac string
Expand All @@ -174,25 +174,31 @@ func (be *VXLANBackend) RegisterNetwork(ctx context.Context, wg *sync.WaitGroup,
policySettings := hcn.DrMacAddressNetworkPolicySetting{}
err = json.Unmarshal(policy.Settings, &policySettings)
if err != nil {
return nil, fmt.Errorf("Failed to unmarshal settings")
return nil, fmt.Errorf("failed to unmarshal settings")
}
newDrMac = policySettings.Address
}
}

mac, err := net.ParseMAC(string(newDrMac))
if err != nil {
return nil, fmt.Errorf("Cannot parse DR MAC %v: %+v", newDrMac, err)
return nil, fmt.Errorf("cannot parse DR MAC %v: %+v", newDrMac, err)
}

subnetAttrs, err = newSubnetAttrs(be.extIface.ExtAddr, uint16(cfg.VNI), mac)
if err != nil {
return nil, err
}

// Before contacting the lease server (e.g. kube-api), we verify that the physical interface is ready
err = checkHostNetworkReady(hcnNetwork)
if err != nil {
return nil, fmt.Errorf("interface bound to %s took too long to get ready. Please check your network host configuration", hcnNetwork.Name)
}

lease, err = be.subnetMgr.AcquireLease(ctx, subnetAttrs)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to acquire lease: %w", err)
}
network.SubnetLease = lease
return network, nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/lease/lease.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type LeaseAttrs struct {
BackendV6Data json.RawMessage `json:",omitempty"`
}

// Lease includes information about the lease
// Lease includes information about the lease
type Lease struct {
EnableIPv4 bool
EnableIPv6 bool
Expand All @@ -67,7 +67,7 @@ type LeaseWatchResult struct {
}

type LeaseWatcher struct {
OwnLease *Lease //Lease with the subnet of the local node
OwnLease *Lease //Lease with the subnet of the local node
Leases []Lease //Leases with subnets from other nodes
}

Expand Down
Loading