-
Notifications
You must be signed in to change notification settings - Fork 39
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 k8s-pure cni #67
add k8s-pure cni #67
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net" | ||
"runtime" | ||
|
||
"github.com/containernetworking/cni/pkg/skel" | ||
"github.com/containernetworking/cni/pkg/types" | ||
t020 "github.com/containernetworking/cni/pkg/types/020" | ||
"github.com/containernetworking/cni/pkg/version" | ||
"github.com/vishvananda/netlink" | ||
"tkestack.io/galaxy/cni/ipam" | ||
"tkestack.io/galaxy/pkg/network" | ||
"tkestack.io/galaxy/pkg/network/vlan" | ||
"tkestack.io/galaxy/pkg/utils" | ||
) | ||
|
||
func init() { | ||
// this ensures that main runs only on main thread (thread group leader). | ||
// since namespace ops (unshare, setns) are done for a single thread, we | ||
// must ensure that the goroutine does not jump from OS thread to thread | ||
runtime.LockOSThread() | ||
} | ||
|
||
func main() { | ||
skel.PluginMain(cmdAdd, cmdDel, version.Legacy) | ||
} | ||
|
||
func cmdDel(args *skel.CmdArgs) error { | ||
if err := utils.DeleteAllVeth(args.Netns); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func cmdAdd(args *skel.CmdArgs) error { | ||
conf := vlan.NetConf{} | ||
if err := json.Unmarshal(args.StdinData, &conf); err != nil { | ||
return fmt.Errorf("conf error: %v", err) | ||
} | ||
vlanIds, results, err := ipam.Allocate(conf.IPAM.Type, args) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 还是调用一次这个veth插件配置多个网卡?可以以后再改吧 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 是的,不然这里涉及到的改动太多,方案也还需讨论 |
||
if err != nil { | ||
return fmt.Errorf("allocate failed: %v", err) | ||
} | ||
if err := utils.UnSetArpIgnore("all"); err != nil { | ||
return err | ||
} | ||
if err := utils.EnableNonlocalBind(); err != nil { | ||
return err | ||
} | ||
ifName := args.IfName | ||
ifIndex := 0 | ||
for i := range vlanIds { | ||
vlanId := vlanIds[i] | ||
result, err := t020.GetResult(results[i]) | ||
if err != nil { | ||
return fmt.Errorf("result convert failed: %v", err) | ||
} | ||
device := conf.Device | ||
// fixme: make route configurable | ||
if i != 0 { | ||
result.IP4.Routes = []types.Route{{ | ||
Dst: net.IPNet{ | ||
IP: result.IP4.IP.IP.Mask(result.IP4.IP.Mask), | ||
Mask: result.IP4.IP.Mask, | ||
}, | ||
}} | ||
} | ||
var masterDevice netlink.Link | ||
if masterDevice, err = vlan.SetupVlanInPureMode(device, vlanId); err != nil { | ||
return fmt.Errorf("failed setup vlan: %v", err) | ||
} | ||
suffix := "" | ||
if i != 0 { | ||
suffix = fmt.Sprintf("-%d", i+1) | ||
ifIndex++ | ||
args.IfName = fmt.Sprintf("eth%d", ifIndex) | ||
if args.IfName == ifName { | ||
ifIndex++ | ||
args.IfName = fmt.Sprintf("eth%d", ifIndex) | ||
} | ||
} | ||
v4Addr, err := netlink.AddrList(masterDevice, netlink.FAMILY_V4) | ||
if err != nil { | ||
return fmt.Errorf("error getting ipv4 address %v", err) | ||
} | ||
filteredAddr := network.FilterLoopbackAddr(v4Addr) | ||
var src net.IP | ||
if len(filteredAddr) > 0 { | ||
src = filteredAddr[0].IP | ||
} | ||
if err := utils.VethConnectsHostWithContainer(result, args, "", suffix, src); err != nil { | ||
return fmt.Errorf("veth connect failed: %v", err) | ||
} | ||
utils.SendGratuitousARP(masterDevice.Attrs().Name, result.IP4.IP.IP.String(), "", conf.GratuitousArpRequest) | ||
} | ||
args.IfName = ifName | ||
result, _ := t020.GetResult(results[0]) | ||
return result.Print() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package veth_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestUnderlayVeth(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Underlay-Veth Suite") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package veth | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"tkestack.io/galaxy/e2e/helper" | ||
"tkestack.io/galaxy/pkg/utils" | ||
) | ||
|
||
var _ = Describe("galaxy-underlay-veth vlan test", func() { | ||
cni := "galaxy-underlay-veth" | ||
ifaceCidr := "192.168.0.66/26" | ||
vlanCidr := "192.168.2.68/26" | ||
containerCidr := "192.168.2.69/26" | ||
containerId := helper.NewContainerId() | ||
|
||
AfterEach(func() { | ||
helper.CleanupNetNS() | ||
helper.CleanupIFace("dummy0.2") | ||
helper.CleanupDummy() | ||
}) | ||
It("vlan", func() { | ||
netConf := []byte(`{ | ||
"name": "myvlan", | ||
"type": "galaxy-underlay-veth", | ||
"device": "dummy0" | ||
}`) | ||
Expect(helper.SetupDummyDev("dummy0", ifaceCidr)).NotTo(HaveOccurred()) | ||
Expect(helper.SetupVlanDev("dummy0.2", "dummy0", vlanCidr, 2)).NotTo(HaveOccurred()) | ||
argsStr, err := helper.IPInfo(containerCidr, 2) | ||
Expect(err).NotTo(HaveOccurred()) | ||
nsPath := helper.CmdAdd(containerId, "", argsStr, cni, | ||
`{"cniVersion":"0.2.0","ip4":{"ip":"192.168.2.69/26","gateway":"192.168.2.65","routes":[{"dst":"0.0.0.0/0"}]},"dns":{}}`, netConf) | ||
_, err = helper.Ping("192.168.2.69") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = (&helper.NetworkTopology{ | ||
LeaveDevices: []*helper.LinkDevice{ | ||
helper.NewLinkDevice(nil, utils.HostVethName(containerId, ""), "veth"), | ||
}, | ||
}).Verify() | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
// check container iface topology, route, neigh, ip address is expected | ||
helper.CheckContainerTopology(nsPath, containerCidr, "192.168.2.65") | ||
|
||
// test DEL command | ||
helper.CmdDel(containerId, cni, netConf) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,6 +137,9 @@ func CmdAdd(cmdArgs *skel.CmdArgs, networkInfos []*NetworkInfo) (types.Result, e | |
for idx, networkInfo := range networkInfos { | ||
//append additional args from network info | ||
cmdArgs.Args = strings.TrimRight(fmt.Sprintf("%s;%s", cmdArgs.Args, BuildCNIArgs(networkInfo.Args)), ";") | ||
if result != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个改动哪里用到了吗? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 不过不用删 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 参考多cni格式,后面改造可能会用到 |
||
networkInfo.Conf["prevResult"] = result | ||
} | ||
result, err = DelegateAdd(networkInfo.Conf, cmdArgs, networkInfo.IfName) | ||
if err != nil { | ||
//fail to add cni, then delete all established CNIs recursively | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package vlan | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/vishvananda/netlink" | ||
"tkestack.io/galaxy/pkg/utils" | ||
) | ||
|
||
// SetupVlan is used in pure veth mode, in this mode, vlan will not attach to bridge device | ||
func SetupVlanInPureMode(ethDevice string, vlanId uint16) (netlink.Link, error) { | ||
if vlanId == 0 { | ||
device, err := netlink.LinkByName(ethDevice) | ||
if err != nil { | ||
return nil, fmt.Errorf("device %v not found", err) | ||
} | ||
if err := utils.UnSetArpIgnore(ethDevice); err != nil { | ||
return nil, err | ||
} | ||
if err := utils.SetProxyArp(ethDevice); err != nil { | ||
return nil, err | ||
} | ||
return device, nil | ||
} | ||
vlanDevice, err := findVlanDevice(vlanId) | ||
if err != nil { | ||
return nil, fmt.Errorf("find vlan device failed: %v", err) | ||
} | ||
if err = netlink.LinkSetUp(vlanDevice); err != nil { | ||
return nil, fmt.Errorf("failed set vlan %v up: %v", vlanDevice.Attrs().Name, err) | ||
} | ||
if err := utils.UnSetArpIgnore(vlanDevice.Attrs().Name); err != nil { | ||
return nil, err | ||
} | ||
return vlanDevice, utils.SetProxyArp(vlanDevice.Attrs().Name) | ||
} | ||
|
||
func findVlanDevice(vlanID uint16) (netlink.Link, error) { | ||
links, err := netlink.LinkList() | ||
if err != nil { | ||
return nil, err | ||
} | ||
var result netlink.Link | ||
for _, link := range links { | ||
if link.Type() == "vlan" { | ||
if vlan, ok := link.(*netlink.Vlan); !ok { | ||
return nil, fmt.Errorf("vlan device type case error: %T", link) | ||
} else { | ||
if vlan.VlanId == int(vlanID) { | ||
if result == nil { | ||
result = link | ||
} else { | ||
return nil, fmt.Errorf("found 2 device with same vlanID %d: %s, %s", vlanID, result.Attrs().Name, vlan.Name) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if result == nil { | ||
return nil, fmt.Errorf("no vlan device with vlanID %d", vlanID) | ||
} | ||
return result, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
改下文档supported-cnis.md,简单介绍下怎么使用这个cni插件吗?比如需要管理员自己把vlan网卡和路由配置好
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好的