Skip to content

Commit

Permalink
windows support for cni server
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzujian committed Apr 19, 2022
1 parent 75d8f4d commit 4705ce2
Show file tree
Hide file tree
Showing 26 changed files with 1,731 additions and 510 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
.vscode/*
.DS_Store
dist/images/kube-ovn-cmd
dist/images/kube-ovn.exe
dist/images/kube-ovn-webhook
dist/images/kube-ovn.exe
dist/images/kube-ovn-daemon.exe
test/e2e/ovnnb_db.*
test/e2e/ovnsb_db.*
kube-ovn.yaml
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ build-go:
build-go-windows:
go mod tidy
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -buildmode=pie -o $(CURDIR)/dist/images/kube-ovn.exe -ldflags $(GOLDFLAGS) -v ./cmd/windows/cni
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -buildmode=pie -o $(CURDIR)/dist/images/kube-ovn-daemon.exe -ldflags $(GOLDFLAGS) -v ./cmd/windows/daemon

.PHONY: build-go-arm
build-go-arm:
Expand Down
11 changes: 6 additions & 5 deletions cmd/daemon/cniserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
_ "net/http/pprof" // #nosec
"os"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -75,21 +76,21 @@ func CmdMain() {
kubeovnInformerFactory.Start(stopCh)
go ctl.Run(stopCh)
go daemon.RunServer(config, ctl)
if err := mvCNIConf(config.CniConfName); err != nil {
if err := mvCNIConf(config.CniConfDir, config.CniConfFile, config.CniConfName); err != nil {
klog.Fatalf("failed to mv cni conf, %v", err)
}
http.Handle("/metrics", promhttp.Handler())
klog.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", config.PprofPort), nil))
}

func mvCNIConf(confName string) error {
data, err := os.ReadFile("/kube-ovn/01-kube-ovn.conflist")
func mvCNIConf(configDir, configFile, confName string) error {
data, err := os.ReadFile(configFile)
if err != nil {
return err
}

cniConfPath := fmt.Sprintf("/etc/cni/net.d/%s", confName)
return os.WriteFile(cniConfPath, data, 0444)
cniConfPath := filepath.Join(configDir, confName)
return os.WriteFile(cniConfPath, data, 0644)
}

func Retry(attempts int, sleep int, f func(configuration *daemon.Configuration) error, ctrl *daemon.Configuration) (err error) {
Expand Down
7 changes: 7 additions & 0 deletions cmd/windows/daemon/main_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "github.com/kubeovn/kube-ovn/cmd/daemon"

func main() {
daemon.CmdMain()
}
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ go 1.17
require (
github.com/Mellanox/sriovnet v1.0.3
github.com/Microsoft/go-winio v0.5.2
github.com/Microsoft/hcsshim v0.9.2
github.com/alauda/felix v3.6.6-0.20201207121355-187332daf314+incompatible
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.1.1
Expand All @@ -26,7 +28,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
google.golang.org/grpc v1.40.0
gopkg.in/k8snetworkplumbingwg/multus-cni.v3 v3.7.2
k8s.io/api v0.23.1
Expand All @@ -40,12 +42,11 @@ require (
)

require (
github.com/Microsoft/hcsshim v0.8.22 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/containerd/cgroups v1.0.1 // indirect
github.com/containerd/cgroups v1.0.3 // indirect
github.com/coreos/prometheus-operator v0.38.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
Expand All @@ -61,8 +62,8 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.5.0 // indirect
github.com/google/go-cmp v0.5.5 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
Expand All @@ -71,6 +72,7 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/errors v0.0.0-20220331221717-b38fca44723b // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/kubernetes-csi/external-snapshotter/v2 v2.1.1 // indirect
Expand Down
48 changes: 40 additions & 8 deletions go.sum

Large diffs are not rendered by default.

98 changes: 20 additions & 78 deletions pkg/daemon/config.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package daemon

import (
"context"
"errors"
"flag"
"fmt"
"net"
Expand All @@ -13,7 +11,6 @@ import (

"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
Expand Down Expand Up @@ -42,6 +39,8 @@ type Configuration struct {
EncapChecksum bool
PprofPort int
NetworkType string
CniConfDir string
CniConfFile string
CniConfName string
DefaultProviderName string
DefaultInterfaceName string
Expand All @@ -52,20 +51,23 @@ type Configuration struct {
// TODO: validate configuration
func ParseFlags(nicBridgeMappings map[string]string) (*Configuration, error) {
var (
argNodeName = pflag.String("node-name", "", "Name of the node on which the daemon is running on.")
argIface = pflag.String("iface", "", "The iface used to inter-host pod communication, can be a nic name or a group of regex separated by comma (default the default route iface)")
argDPDKTunnelIface = pflag.String("dpdk-tunnel-iface", "br-phy", "Specifies the name of the dpdk tunnel iface.")
argMTU = pflag.Int("mtu", 0, "The MTU used by pod iface in overlay networks (default iface MTU - 100)")
argEnableMirror = pflag.Bool("enable-mirror", false, "Enable traffic mirror (default false)")
argMirrorNic = pflag.String("mirror-iface", "mirror0", "The mirror nic name that will be created by kube-ovn")
argBindSocket = pflag.String("bind-socket", "/run/openvswitch/kube-ovn-daemon.sock", "The socket daemon bind to.")
argBindSocket = pflag.String("bind-socket", defaultBindSocket, "The socket daemon bind to.")
argOvsSocket = pflag.String("ovs-socket", "", "The socket to local ovs-server")
argKubeConfigFile = pflag.String("kubeconfig", "", "Path to kubeconfig file with authorization and master location information. If not set use the inCluster token.")
argServiceClusterIPRange = pflag.String("service-cluster-ip-range", "10.96.0.0/12", "The kubernetes service cluster ip range")
argNodeLocalDnsIP = pflag.String("node-local-dns-ip", "", "If use nodelocaldns the local dns server ip should be set here.")
argEncapChecksum = pflag.Bool("encap-checksum", true, "Enable checksum")
argPprofPort = pflag.Int("pprof-port", 10665, "The port to get profiling data")

argsNetworkType = pflag.String("network-type", "geneve", "The ovn network type")
argsNetworkType = pflag.String("network-type", defaultNetworkType, "The ovn network type")
argCniConfDir = pflag.String("cni-conf-dir", util.DefaultCniConfigDir, "Path of the CNI config directory.")
argCniConfFile = pflag.String("cni-conf-file", util.DefaultCniConfigFile, "Path of the CNI config file.")
argsCniConfName = pflag.String("cni-conf-name", "01-kube-ovn.conflist", "Specify the name of kube ovn conflist name in dir /etc/cni/net.d/, default: 01-kube-ovn.conflist")
argsDefaultProviderName = pflag.String("default-provider-name", "provider", "The vlan or vxlan type default provider interface name")
argsDefaultInterfaceName = pflag.String("default-interface-name", "", "The default host interface name in the vlan/vxlan type")
Expand Down Expand Up @@ -93,11 +95,18 @@ func ParseFlags(nicBridgeMappings map[string]string) (*Configuration, error) {
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()

nodeName := os.Getenv(util.HostnameEnv)
nodeName := *argNodeName
if nodeName == "" {
klog.Errorf("env KUBE_NODE_NAME not exists")
return nil, fmt.Errorf("env KUBE_NODE_NAME not exists")
klog.Info("node name not specified in command line parameters, fall back to the environment variable")
if nodeName = os.Getenv(util.HostnameEnv); nodeName == "" {
klog.Info("node name not specified in environment variables, fall back to the hostname")
var err error
if nodeName, err = os.Hostname(); err != nil {
return nil, fmt.Errorf("failed to get hostname: %v", err)
}
}
}

config := &Configuration{
Iface: *argIface,
DPDKTunnelIface: *argDPDKTunnelIface,
Expand All @@ -108,11 +117,13 @@ func ParseFlags(nicBridgeMappings map[string]string) (*Configuration, error) {
OvsSocket: *argOvsSocket,
KubeConfigFile: *argKubeConfigFile,
PprofPort: *argPprofPort,
NodeName: nodeName,
NodeName: strings.ToLower(nodeName),
ServiceClusterIPRange: *argServiceClusterIPRange,
NodeLocalDnsIP: *argNodeLocalDnsIP,
EncapChecksum: *argEncapChecksum,
NetworkType: *argsNetworkType,
CniConfDir: *argCniConfDir,
CniConfFile: *argCniConfFile,
CniConfName: *argsCniConfName,
DefaultProviderName: *argsDefaultProviderName,
DefaultInterfaceName: *argsDefaultInterfaceName,
Expand All @@ -131,75 +142,6 @@ func ParseFlags(nicBridgeMappings map[string]string) (*Configuration, error) {
return config, nil
}

func (config *Configuration) initNicConfig(nicBridgeMappings map[string]string) error {
var (
iface *net.Interface
err error
encapIP string
)

// Support to specify node network card separately
node, err := config.KubeClient.CoreV1().Nodes().Get(context.Background(), config.NodeName, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to find node info, err: %v", err)
return err
}
if nodeTunnelName := node.GetAnnotations()[util.TunnelInterfaceAnnotation]; nodeTunnelName != "" {
config.Iface = nodeTunnelName
klog.Infof("Find node tunnel interface name: %v", nodeTunnelName)
}

isDPDKNode := node.GetLabels()[util.OvsDpTypeLabel] == "userspace"
if isDPDKNode {
config.Iface = config.DPDKTunnelIface
}
if config.Iface == "" {
podIP, ok := os.LookupEnv(util.POD_IP)
if !ok || podIP == "" {
return errors.New("failed to lookup env POD_IP")
}
iface, err = getIfaceOwnPodIP(podIP)
if err != nil {
klog.Errorf("failed to find POD_IP iface %v", err)
return err
}
encapIP = podIP
} else {
tunnelNic := config.Iface
if brName := nicBridgeMappings[tunnelNic]; brName != "" {
klog.Infof("nic %s has been bridged to %s, use %s as the tunnel interface instead", tunnelNic, brName, brName)
tunnelNic = brName
}

iface, err = findInterface(tunnelNic)
if err != nil {
klog.Errorf("failed to find iface %s, %v", tunnelNic, err)
return err
}
addrs, err := iface.Addrs()
if err != nil {
return fmt.Errorf("failed to get iface addr. %v", err)
}
if len(addrs) == 0 {
return fmt.Errorf("iface %s has no ip address", tunnelNic)
}
encapIP = strings.Split(addrs[0].String(), "/")[0]
}

if config.MTU == 0 {
config.MTU = iface.MTU - util.GeneveHeaderLength
}

config.MSS = config.MTU - util.TcpIpHeaderLength
if !config.EncapChecksum {
if err := disableChecksum(); err != nil {
klog.Errorf("failed to set checksum offload, %v", err)
}
}

return setEncapIP(encapIP)
}

func findInterface(ifaceStr string) (*net.Interface, error) {
iface, err := net.InterfaceByName(ifaceStr)
if err == nil && iface != nil {
Expand Down
80 changes: 80 additions & 0 deletions pkg/daemon/config_linux.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,93 @@
package daemon

import (
"context"
"errors"
"fmt"
"net"
"os"
"strings"

"github.com/kubeovn/kube-ovn/pkg/util"
"github.com/vishvananda/netlink"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)

const (
defaultBindSocket = `/run/openvswitch/kube-ovn-daemon.sock`
defaultNetworkType = `geneve`
)

func (config *Configuration) initNicConfig(nicBridgeMappings map[string]string) error {
var (
iface *net.Interface
err error
encapIP string
)

// Support to specify node network card separately
node, err := config.KubeClient.CoreV1().Nodes().Get(context.Background(), config.NodeName, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to find node info, err: %v", err)
return err
}
if nodeTunnelName := node.GetAnnotations()[util.TunnelInterfaceAnnotation]; nodeTunnelName != "" {
config.Iface = nodeTunnelName
klog.Infof("Find node tunnel interface name: %v", nodeTunnelName)
}

isDPDKNode := node.GetLabels()[util.OvsDpTypeLabel] == "userspace"
if isDPDKNode {
config.Iface = config.DPDKTunnelIface
}
if config.Iface == "" {
podIP, ok := os.LookupEnv(util.POD_IP)
if !ok || podIP == "" {
return errors.New("failed to lookup env POD_IP")
}
iface, err = getIfaceOwnPodIP(podIP)
if err != nil {
klog.Errorf("failed to find POD_IP iface %v", err)
return err
}
encapIP = podIP
} else {
tunnelNic := config.Iface
if brName := nicBridgeMappings[tunnelNic]; brName != "" {
klog.Infof("nic %s has been bridged to %s, use %s as the tunnel interface instead", tunnelNic, brName, brName)
tunnelNic = brName
}

iface, err = findInterface(tunnelNic)
if err != nil {
klog.Errorf("failed to find iface %s, %v", tunnelNic, err)
return err
}
addrs, err := iface.Addrs()
if err != nil {
return fmt.Errorf("failed to get iface addr. %v", err)
}
if len(addrs) == 0 {
return fmt.Errorf("iface %s has no ip address", tunnelNic)
}
encapIP = strings.Split(addrs[0].String(), "/")[0]
}

if config.MTU == 0 {
config.MTU = iface.MTU - util.GeneveHeaderLength
}

config.MSS = config.MTU - util.TcpIpHeaderLength
if !config.EncapChecksum {
if err := disableChecksum(); err != nil {
klog.Errorf("failed to set checksum offload, %v", err)
}
}

return setEncapIP(encapIP)
}

func getIfaceOwnPodIP(podIP string) (*net.Interface, error) {
links, err := netlink.LinkList()
if err != nil {
Expand Down
Loading

0 comments on commit 4705ce2

Please sign in to comment.