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

Remove the ethtool kubelet dependency; use ip link instead of ethtool to determine pair interface. #30356

Closed
wants to merge 1 commit into from
Closed
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
20 changes: 7 additions & 13 deletions pkg/kubelet/network/hairpin/hairpin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ const (
hairpinEnable = "1"
)

var (
ethtoolOutputRegex = regexp.MustCompile("peer_ifindex: (\\d+)")
)

func SetUpContainerPid(containerPid int, containerInterfaceName string) error {
pidStr := fmt.Sprintf("%d", containerPid)
nsenterArgs := []string{"-t", pidStr, "-n"}
Expand Down Expand Up @@ -69,24 +65,22 @@ func findPairInterfaceOfContainerInterface(e exec.Interface, containerInterfaceN
if err != nil {
return "", err
}
ethtoolPath, err := e.LookPath("ethtool")
if err != nil {
return "", err
}

nsenterArgs = append(nsenterArgs, "-F", "--", ethtoolPath, "--statistics", containerInterfaceName)
ipLinkOutputRegex := regexp.MustCompile(containerInterfaceName + "@if(\\d+)")

nsenterArgs = append(nsenterArgs, "-F", "--", "ip", "link", "show", containerInterfaceName)
output, err := e.Command(nsenterPath, nsenterArgs...).CombinedOutput()
if err != nil {
return "", fmt.Errorf("Unable to query interface %s of container %s: %v: %s", containerInterfaceName, containerDesc, err, string(output))
}
// look for peer_ifindex
match := ethtoolOutputRegex.FindSubmatch(output)
// look for the interface name which is named eth0@if{pair_interface}
match := ipLinkOutputRegex.FindSubmatch(output)
if match == nil {
return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %s", containerInterfaceName, containerDesc)
return "", fmt.Errorf("No pair interface returned from container output %s. Description: %s", containerInterfaceName, containerDesc)
}
peerIfIndex, err := strconv.Atoi(string(match[1]))
if err != nil { // seems impossible (\d+ not numeric)
return "", fmt.Errorf("peer_ifindex wasn't numeric: %s: %v", match[1], err)
return "", fmt.Errorf("Pair interface wasn't numeric: %s: %v", match[1], err)
}
iface, err := net.InterfaceByIndex(peerIfIndex)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions pkg/kubelet/network/hairpin/hairpin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ import (
func TestFindPairInterfaceOfContainerInterface(t *testing.T) {
// there should be at least "lo" on any system
interfaces, _ := net.Interfaces()
validOutput := fmt.Sprintf("garbage\n peer_ifindex: %d", interfaces[0].Index)
invalidOutput := fmt.Sprintf("garbage\n unknown: %d", interfaces[0].Index)
// let's imagine eth0 in a container connects to iface index 1 on the host system (=localhost)
validOutput := fmt.Sprintf("2: eth0@if1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000")
invalidOutput := fmt.Sprintf("2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000")

tests := []struct {
output string
Expand Down