Skip to content

Commit

Permalink
Merge branch 'master' into fix-init-node-router_policy-slow
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdy authored Jan 2, 2025
2 parents 2924f7c + 4d3dd9c commit cccdcd0
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 74 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@

[中文文档](https://kubeovn.github.io/docs/)

If you miss the good old days of SDN, then Kube-OVN is your choice in Cloud Native era.
If you are looking for a powerful networking solution that excels in both container and VM scenarios, or if you need robust multi-tenant networking capabilities, Kube-OVN is your ideal choice in the Cloud Native era.

Kube-OVN, a [CNCF Sandbox Level Project](https://www.cncf.io/sandbox-projects/), integrates the OVN-based Network Virtualization with Kubernetes.
It offers an advanced Container Network Fabric for Enterprises with the most functions, extreme performance and the easiest operation.
Kube-OVN, a [CNCF Sandbox Level Project](https://www.cncf.io/sandbox-projects/), integrates OVN-based Network Virtualization with Kubernetes. It provides enhanced support for KubeVirt workloads and unique multi-tenant capabilities, offering enterprise-grade network features with superior performance and simplified operations.

## Community
The Kube-OVN community is waiting for your participation!

- Join the [Online Meeting](https://docs.google.com/document/d/1OPFC3s0rVxGkLR5GaUayNC6Nx9lwvjapg_hQl4MWt3E/edit#heading=h.1e73t98gdg9l)
- Follow us at [Twitter](https://twitter.com/KubeOvn)
- Chat with us at [Slack](https://communityinviter.com/apps/kube-ovn/kube-ovn)
- 微信用户请[填写表单](https://jinshuju.net/f/lyrEow)加入交流群!
- 💭 Chat with us at [Slack](https://communityinviter.com/apps/kube-ovn/kube-ovn)
- 📅 Join the [Online Meeting](https://docs.google.com/document/d/1OPFC3s0rVxGkLR5GaUayNC6Nx9lwvjapg_hQl4MWt3E/edit#heading=h.1e73t98gdg9l)
- 🐦 Follow us at [Twitter](https://twitter.com/KubeOvn)
- 💬 微信用户请[填写表单](https://jinshuju.net/f/lyrEow)加入交流群!

## Features
- **Namespaced Subnets**: Each Namespace can have a unique Subnet (backed by a Logical Switch). Pods within the Namespace will have IP addresses allocated from the Subnet. It's also possible for multiple Namespaces to share a Subnet.
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ require (
github.com/kubeovn/ovsdb v0.0.0-20240410091831-5dd26006c475
github.com/mdlayher/arp v0.0.0-20220512170110-6706a2966875
github.com/moby/sys/mountinfo v0.7.2
github.com/onsi/ginkgo/v2 v2.22.1
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/osrg/gobgp/v3 v3.32.0
github.com/osrg/gobgp/v3 v3.33.0
github.com/ovn-org/libovsdb v0.7.0
github.com/parnurzeal/gorequest v0.3.0
github.com/prometheus-community/pro-bing v0.5.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM=
github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
Expand Down Expand Up @@ -542,8 +542,8 @@ github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPf
github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/osrg/gobgp/v3 v3.32.0 h1:B2krh/44etYQAuLq+iMkORxIvXj+cGIpuR6qDGNGagM=
github.com/osrg/gobgp/v3 v3.32.0/go.mod h1:8m+kgkdaWrByxg5EWpNUO2r/mopodrNBOUBhMnW/yGQ=
github.com/osrg/gobgp/v3 v3.33.0 h1:G8NlY1gzz0DOfiwfiYv2++vWpPLm+CMAKYRVzSmaJow=
github.com/osrg/gobgp/v3 v3.33.0/go.mod h1:8m+kgkdaWrByxg5EWpNUO2r/mopodrNBOUBhMnW/yGQ=
github.com/parnurzeal/gorequest v0.3.0 h1:SoFyqCDC9COr1xuS6VA8fC8RU7XyrJZN2ona1kEX7FI=
github.com/parnurzeal/gorequest v0.3.0/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/kubeovn/v1/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ type BFDPort struct {
NodeSelector *metav1.LabelSelector `json:"nodeSelector,omitempty"`
}

func (p *BFDPort) IsEnabled() bool {
return p != nil && p.Enabled
}

type VpcPeering struct {
RemoteVpc string `json:"remoteVpc,omitempty"`
LocalConnectIP string `json:"localConnectIP,omitempty"`
Expand Down Expand Up @@ -98,6 +102,14 @@ type BFDPortStatus struct {
Nodes []string `json:"nodes,omitempty"`
}

func (s BFDPortStatus) IsEmpty() bool {
return s.Name == "" && s.IP == "" && len(s.Nodes) == 0
}

func (s *BFDPortStatus) Clear() {
s.Name, s.IP, s.Nodes = "", "", nil
}

type VpcStatus struct {
// Conditions represents the latest state of the object
// +optional
Expand Down
20 changes: 10 additions & 10 deletions pkg/controller/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ func (c *Controller) handleAddNamespace(key string) error {
}
namespace := cachedNs.DeepCopy()

var ls, ippool string
var lss, cidrs, excludeIps []string
var ls string
var lss, cidrs, excludeIps, ipPoolsAnnotation []string
subnets, err := c.subnetsLister.List(labels.Everything())
if err != nil {
klog.Errorf("failed to list subnets %v", err)
return err
}
ippools, err := c.ippoolLister.List(labels.Everything())
ipPoolList, err := c.ippoolLister.List(labels.Everything())
if err != nil {
klog.Errorf("failed to list ippools: %v", err)
return err
Expand Down Expand Up @@ -151,10 +151,9 @@ func (c *Controller) handleAddNamespace(key string) error {
}
}

for _, p := range ippools {
if slices.Contains(p.Spec.Namespaces, key) {
ippool = p.Name
break
for _, ipPool := range ipPoolList {
if slices.Contains(ipPool.Spec.Namespaces, key) {
ipPoolsAnnotation = append(ipPoolsAnnotation, ipPool.Name)
}
}

Expand Down Expand Up @@ -195,7 +194,7 @@ func (c *Controller) handleAddNamespace(key string) error {
if namespace.Annotations[util.LogicalSwitchAnnotation] == strings.Join(lss, ",") &&
namespace.Annotations[util.CidrAnnotation] == strings.Join(cidrs, ";") &&
namespace.Annotations[util.ExcludeIpsAnnotation] == strings.Join(excludeIps, ";") &&
namespace.Annotations[util.IPPoolAnnotation] == ippool {
namespace.Annotations[util.IPPoolAnnotation] == strings.Join(ipPoolsAnnotation, ",") {
return nil
}

Expand All @@ -204,10 +203,11 @@ func (c *Controller) handleAddNamespace(key string) error {
util.CidrAnnotation: strings.Join(cidrs, ";"),
util.ExcludeIpsAnnotation: strings.Join(excludeIps, ";"),
}
if ippool == "" {

if len(ipPoolsAnnotation) == 0 {
patch[util.IPPoolAnnotation] = nil
} else {
patch[util.IPPoolAnnotation] = ippool
patch[util.IPPoolAnnotation] = strings.Join(ipPoolsAnnotation, ",")
}

if err = util.PatchAnnotations(c.config.KubeClient.CoreV1().Namespaces(), key, patch); err != nil {
Expand Down
32 changes: 31 additions & 1 deletion pkg/controller/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -1643,8 +1643,38 @@ func (c *Controller) acquireAddress(pod *v1.Pod, podNet *kubeovnNet) (string, st
klog.Errorf("failed to get namespace %s: %v", pod.Namespace, err)
return "", "", "", podNet.Subnet, err
}

if len(ns.Annotations) != 0 {
ippoolStr = ns.Annotations[util.IPPoolAnnotation]
if ipPoolList, ok := ns.Annotations[util.IPPoolAnnotation]; ok {
for _, ipPoolName := range strings.Split(ipPoolList, ",") {
ippool, err := c.ippoolLister.Get(ipPoolName)
if err != nil {
klog.Errorf("failed to get ippool %s: %v", ipPoolName, err)
return "", "", "", podNet.Subnet, err
}

switch podNet.Subnet.Spec.Protocol {
case kubeovnv1.ProtocolDual:
if ippool.Status.V4AvailableIPs.Int64() == 0 || ippool.Status.V6AvailableIPs.Int64() == 0 {
continue
}
case kubeovnv1.ProtocolIPv4:
if ippool.Status.V4AvailableIPs.Int64() == 0 {
continue
}

default:
if ippool.Status.V6AvailableIPs.Int64() == 0 {
continue
}
}

if ippool.Spec.Subnet == podNet.Subnet.Name {
ippoolStr = ippool.Name
break
}
}
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/controller/vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ func (c *Controller) handleUpdateVpcStatus(key string) error {

vpc.Status.DefaultLogicalSwitch = defaultSubnet
vpc.Status.Subnets = subnets
if !vpc.Spec.BFDPort.IsEnabled() && !vpc.Status.BFDPort.IsEmpty() {
vpc.Status.BFDPort.Clear()
}
bytes, err := vpc.Status.Bytes()
if err != nil {
klog.Error(err)
Expand Down
10 changes: 10 additions & 0 deletions pkg/util/pod_routes.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package util

import (
"cmp"
"encoding/json"
"fmt"
"slices"

"github.com/kubeovn/kube-ovn/pkg/request"
)
Expand Down Expand Up @@ -48,6 +50,14 @@ func (r PodRoutes) ToAnnotations() (map[string]string, error) {
continue
}

// sort routes to ensure the result is stable
slices.SortFunc(routes, func(a, b request.Route) int {
if n := cmp.Compare(a.Destination, b.Destination); n != 0 {
return n
}
return cmp.Compare(a.Gateway, b.Gateway)
})

// no error will be returned here
buf, _ := json.Marshal(routes)
annotations[fmt.Sprintf(RoutesAnnotationTemplate, provider)] = string(buf)
Expand Down
5 changes: 5 additions & 0 deletions pkg/util/pod_routes_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -24,6 +25,10 @@ func TestPodRoutes(t *testing.T) {
annotations, err = routes.ToAnnotations()
require.NoError(t, err)
require.Len(t, annotations, 1)
require.Equal(t,
annotations[fmt.Sprintf(RoutesAnnotationTemplate, "foo")],
`[{"dst":"0.0.0.1","gw":"1.1.1.1"},{"dst":"0.0.1.0/24","gw":"1.1.1.1"},{"dst":"0.1.0.0/16","gw":"1.1.1.2"}]`,
)

routes.Add("foo", "0.0.0.1", "")
routes.Add("foo", "", "1.1.1.3")
Expand Down
7 changes: 4 additions & 3 deletions test/e2e/framework/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ func (c *NamespaceClient) WaitToDisappear(name string, _, timeout time.Duration)
return nil
}

func MakeNamespace(name string, labels map[string]string) *corev1.Namespace {
func MakeNamespace(name string, labels, annotations map[string]string) *corev1.Namespace {
namespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: labels,
Name: name,
Labels: labels,
Annotations: annotations,
},
}
return namespace
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/framework/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,6 @@ func CheckPodEgressRoutes(ns, pod string, ipv4, ipv6 bool, ttl int, expectedHops
lines := strings.Split(strings.TrimSpace(output), "\n")
fields := strings.Fields(lines[len(lines)-1])
return len(fields) > 2 && slices.Contains(expectedHops, fields[1]), nil
}, "")
}, fmt.Sprintf("expected hops: %s", strings.Join(expectedHops, ", ")))
}
}
Loading

0 comments on commit cccdcd0

Please sign in to comment.