如何在Kubernetes中配置bond-cni插件创建的bond主从接口
Kubernetes中bond-cni插件Primary Slave配置不生效的问题解决
问题描述
在Kubernetes Pod中使用bond-cni插件创建bond接口时,因原生插件配置功能有限,修改了createBondedLink函数,新增ArpInterval、ArpIpTargets、ArpValidate及Primary参数。目前bond接口可正常创建,但Primary Slave(主从接口)配置未生效。
原始创建函数
func createBondedLink(bondName string, bondMode string, bondMiimon string, bondMTU int, failOverMac int, netNsHandle *netlink.Handle) (*netlink.Bond, error) { var err error bondLinkObj := netlink.NewLinkBond(netlink.NewLinkAttrs()) bondModeObj := netlink.StringToBondMode(bondMode) bondLinkObj.Attrs().Name = bondName bondLinkObj.Mode = bondModeObj bondLinkObj.Miimon, err = strconv.Atoi(bondMiimon) if err != nil { return nil, fmt.Errorf("Failed to convert bondMiimon value (%+v) to an int, error: %+v", bondMiimon, err) } if bondMTU != 0 { bondLinkObj.MTU = bondMTU } bondLinkObj.FailOverMac = netlink.BondFailOverMac(failOverMac) err = netNsHandle.LinkAdd(bondLinkObj) if err != nil { return nil, fmt.Errorf("Failed to add link (%+v) to the netNsHandle, error: %+v", bondLinkObj.Attrs().Name, err) } return bondLinkObj, nil }
修改后的创建函数
func createBondedLink(bondName string, bondMode string, bondMiimon string, bondPrimary int, bondArpInterval string, bondArpTargets string, bondMTU int, failOverMac int, netNsHandle *netlink.Handle) (*netlink.Bond, error) { var err error bondLinkObj := netlink.NewLinkBond(netlink.NewLinkAttrs()) bondModeObj := netlink.StringToBondMode(bondMode) bondLinkObj.Attrs().Name = bondName bondLinkObj.Mode = bondModeObj bondLinkObj.ArpInterval, err = strconv.Atoi(bondArpInterval) if err != nil { return nil, fmt.Errorf("Failed to convert bondMiimon value (%+v) to an int, error: %+v", bondMiimon, err) } bondLinkObj.Miimon = 0 if bondMTU != 0 { bondLinkObj.MTU = bondMTU } bondLinkObj.FailOverMac = netlink.BondFailOverMac(failOverMac) bondLinkObj.ArpValidate = netlink.BondArpValidate(3) bondLinkObj.ArpIpTargets = []net.IP{net.ParseIP(bondArpTargets)} bondLinkObj.Primary = bondPrimary err = netNsHandle.LinkAdd(bondLinkObj) if err != nil { return nil, fmt.Errorf("Failed to add link (%+v) to the netNsHandle, error: %+v", bondLinkObj.Attrs().Name, err) } return bondLinkObj, nil }
现有创建流程
插件创建bond的步骤为:
- 调用
createBondedLink创建bond接口 - 将链路附加至bond(添加从节点)
- 启用bond接口
对应代码:
bondLinkObj, err := createBondedLink(bondName, bondConf.Mode, bondConf.Miimon, bondConf.MTU, bondConf.FailOverMac, netNsHandle) if err != nil { return nil, fmt.Errorf("Failed to create bonded link (%+v), error: %+v", bondName, err) } err = attachLinksToBond(bondLinkObj, linkObjectsToBond, netNsHandle) if err != nil { return nil, fmt.Errorf("Failed to attached links to bond, error: %+v", err) } if err := netNsHandle.LinkSetUp(bondLinkObj); err != nil { return nil, fmt.Errorf("Failed to set bond link UP, error: %v", err) }
已尝试的无效方法
- 使用
netlink.LinkModify修改bond配置:添加从节点后调用该函数,报错error: directory not empty,推测该函数不支持bond配置修改。 - 直接修改sysfs文件:通过
ip netns exec执行echo命令写入/sys/class/net/bond0/bonding/primary,命令无报错但配置未生效,原因是未正确处理shell重定向。
有效解决方案
方案1:使用netlink原生BondSetPrimary方法
netlink库提供了专门设置bond主接口的方法,需在添加所有从节点之后调用。
修改现有流程代码:
bondLinkObj, err := createBondedLink(bondName, bondConf.Mode, bondConf.Miimon, bondConf.MTU, bondConf.FailOverMac, netNsHandle) if err != nil { return nil, fmt.Errorf("Failed to create bonded link (%+v), error: %+v", bondName, err) } // 附加所有从节点到bond err = attachLinksToBond(bondLinkObj, linkObjectsToBond, netNsHandle) if err != nil { return nil, fmt.Errorf("Failed to attached links to bond, error: %+v", err) } // 找到要设置为主接口的从节点对象(示例按索引匹配,可根据实际逻辑调整) var primarySlave *netlink.Link for i, link := range linkObjectsToBond { if i == bondConf.Primary { primarySlave = link break } } // 设置主接口 if primarySlave != nil { err = netNsHandle.BondSetPrimary(bondLinkObj, primarySlave) if err != nil { return nil, fmt.Errorf("Failed to set primary slave: %v", err) } } // 启用bond接口 if err := netNsHandle.LinkSetUp(bondLinkObj); err != nil { return nil, fmt.Errorf("Failed to set bond link UP, error: %v", err) }
方案2:修正sysfs文件写入命令
之前的exec命令未正确处理shell重定向,需通过bash -c执行完整shell命令:
netnsvariable := os.Getenv("CNI_NETNS") netnsName := filepath.Base(netnsvariable) // 使用bash -c包裹命令,确保重定向生效 cmd := exec.Command("bash", "-c", fmt.Sprintf("ip netns exec %s echo tap2 > /sys/class/net/bond0/bonding/primary", netnsName)) if err := cmd.Run(); err != nil { log.Fatal(err) }
建议在添加从节点并启用bond后执行该命令。
内容的提问来源于stack exchange,提问作者juangas
相关产品推荐
相关产品推荐

