From 4af196059283b296b79b434df9d8771eef66199d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A5=96=E5=BB=BA?= Date: Mon, 9 Oct 2023 09:31:37 +0800 Subject: [PATCH 1/8] webhook: use dedicated port for health probe (#3285) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --------- Signed-off-by: 张祖建 --- Makefile | 4 ++-- cmd/webhook/server.go | 11 +++++++++++ yamls/webhook.yaml | 20 ++++++++++++++------ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 8111e10f6ab..4291b278d93 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ KUBEVIRT_TEST_YAML = https://kubevirt.io/labs/manifests/vm.yaml CILIUM_VERSION = 1.14.1 CILIUM_IMAGE_REPO = quay.io/cilium/cilium -CERT_MANAGER_VERSION = v1.12.3 +CERT_MANAGER_VERSION = v1.12.5 CERT_MANAGER_CONTROLLER = quay.io/jetstack/cert-manager-controller:$(CERT_MANAGER_VERSION) CERT_MANAGER_CAINJECTOR = quay.io/jetstack/cert-manager-cainjector:$(CERT_MANAGER_VERSION) CERT_MANAGER_WEBHOOK = quay.io/jetstack/cert-manager-webhook:$(CERT_MANAGER_VERSION) @@ -769,7 +769,7 @@ kind-install-webhook: kind-install kubectl rollout status deployment/cert-manager-cainjector -n cert-manager --timeout 120s kubectl rollout status deployment/cert-manager-webhook -n cert-manager --timeout 120s - kubectl apply -f yamls/webhook.yaml + sed 's#image: .*#image: $(REGISTRY)/kube-ovn:$(VERSION)#' yamls/webhook.yaml | kubectl apply -f - kubectl rollout status deployment/kube-ovn-webhook -n kube-system --timeout 120s .PHONY: kind-install-cilium-chaining diff --git a/cmd/webhook/server.go b/cmd/webhook/server.go index 2d9de801a9a..b9f053e6082 100644 --- a/cmd/webhook/server.go +++ b/cmd/webhook/server.go @@ -2,6 +2,7 @@ package main import ( "flag" + "os" "github.com/spf13/pflag" appsv1 "k8s.io/api/apps/v1" @@ -10,6 +11,7 @@ import ( "k8s.io/klog/v2" "k8s.io/klog/v2/klogr" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" ctrlwebhook "sigs.k8s.io/controller-runtime/pkg/webhook" @@ -39,6 +41,7 @@ func main() { klog.Infof(versions.String()) port := pflag.Int("port", 8443, "The port webhook listen on.") + healthProbePort := pflag.Int32("health-probe-port", 8080, "The port health probes listen on.") klogFlags := flag.NewFlagSet("klog", flag.ExitOnError) klog.InitFlags(klogFlags) @@ -73,6 +76,7 @@ func main() { Metrics: metricsserver.Options{ BindAddress: "0", }, + HealthProbeBindAddress: util.JoinHostPort(os.Getenv("POD_IP"), *healthProbePort), }) if err != nil { panic(err) @@ -91,6 +95,13 @@ func main() { panic(err) } + if err = mgr.AddHealthzCheck("liveness probe", healthz.Ping); err != nil { + panic(err) + } + if err = mgr.AddReadyzCheck("readiness probe", healthz.Ping); err != nil { + panic(err) + } + // Start the server by starting a previously-set-up manager if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { panic(err) diff --git a/yamls/webhook.yaml b/yamls/webhook.yaml index dbbd919a8a0..fe76f86523d 100644 --- a/yamls/webhook.yaml +++ b/yamls/webhook.yaml @@ -39,7 +39,14 @@ spec: - /kube-ovn/kube-ovn-webhook args: - --port=8443 + - --health-probe-port=8080 - --v=3 + env: + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert @@ -48,12 +55,14 @@ spec: - containerPort: 8443 name: https protocol: TCP + - containerPort: 8080 + name: health-probe + protocol: TCP livenessProbe: failureThreshold: 3 httpGet: - path: /validating - port: 8443 - scheme: HTTPS + path: /healthz + port: 8080 initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 @@ -61,9 +70,8 @@ spec: readinessProbe: failureThreshold: 3 httpGet: - path: /validating - port: 8443 - scheme: HTTPS + path: /readyz + port: 8080 initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 From f9edd66926466c83a0a4ff42a18946e414e724e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=A5=96=E5=BB=BA?= Date: Mon, 9 Oct 2023 09:31:53 +0800 Subject: [PATCH 2/8] webhook: fix ip validation when pod is annotated with an ippool name (#3284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张祖建 --- pkg/webhook/static_ip.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/webhook/static_ip.go b/pkg/webhook/static_ip.go index f12ef899fc5..cadc4c21448 100644 --- a/pkg/webhook/static_ip.go +++ b/pkg/webhook/static_ip.go @@ -12,6 +12,7 @@ import ( batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" ctrlwebhook "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -162,14 +163,14 @@ func (v *ValidatingHook) validateIP(ctx context.Context, annotations map[string] if err := v.cache.List(ctx, ipList); err != nil { return ctrlwebhook.Errored(http.StatusBadRequest, err) } - if err := v.validateIPConflict(annotations, name, ipList.Items); err != nil { + if err := v.validateIPConflict(ctx, annotations, name, ipList.Items); err != nil { return ctrlwebhook.Denied(err.Error()) } return ctrlwebhook.Allowed("by pass") } -func (v *ValidatingHook) validateIPConflict(annotations map[string]string, name string, ipList []ovnv1.IP) error { +func (v *ValidatingHook) validateIPConflict(ctx context.Context, annotations map[string]string, name string, ipList []ovnv1.IP) error { annoSubnet := annotations[util.LogicalSwitchAnnotation] if annotations[util.LogicalSwitchAnnotation] == "" { annoSubnet = util.DefaultSubnet @@ -183,7 +184,12 @@ func (v *ValidatingHook) validateIPConflict(annotations map[string]string, name ipPool := annotations[util.IPPoolAnnotation] if ipPool != "" { - if err := v.checkIPConflict(ipPool, annoSubnet, name, ipList); err != nil { + if !strings.ContainsRune(ipPool, ',') && net.ParseIP(ipPool) == nil { + pool := &ovnv1.IPPool{} + if err := v.cache.Get(ctx, types.NamespacedName{Name: ipPool}, pool); err != nil { + return fmt.Errorf("ippool %q not found", ipPool) + } + } else if err := v.checkIPConflict(ipPool, annoSubnet, name, ipList); err != nil { return err } } @@ -198,6 +204,9 @@ func (v *ValidatingHook) checkIPConflict(ipAddress, annoSubnet, name string, ipL } else { ipAddr = net.ParseIP(strings.TrimSpace(ip)) } + if ipAddr == nil { + return fmt.Errorf("invalid static ip/ippool annotation value: %s", ipAddress) + } for _, ipCr := range ipList { if annoSubnet != "" && ipCr.Spec.Subnet != annoSubnet { From 33bc9a626759673ea9b2ffc3aa1fb737636bf008 Mon Sep 17 00:00:00 2001 From: bobz965 Date: Mon, 9 Oct 2023 09:32:31 +0800 Subject: [PATCH 3/8] support custom vpc dns its deployment replicas (#3286) * support custom vpc dns its deployment replicas * the provider is not necessary --------- Signed-off-by: bobz965 --- charts/templates/kube-ovn-crd.yaml | 4 ++++ dist/images/install.sh | 4 ++++ pkg/apis/kubeovn/v1/types.go | 5 +++-- pkg/controller/vpc_dns.go | 24 ++++-------------------- yamls/crd.yaml | 4 ++++ 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/charts/templates/kube-ovn-crd.yaml b/charts/templates/kube-ovn-crd.yaml index fac0dad0237..c87b59c3ef0 100644 --- a/charts/templates/kube-ovn-crd.yaml +++ b/charts/templates/kube-ovn-crd.yaml @@ -39,6 +39,10 @@ spec: type: string subnet: type: string + replicas: + type: integer + minimum: 1 + maximum: 3 status: type: object properties: diff --git a/dist/images/install.sh b/dist/images/install.sh index 30e21c08216..5bcb7656eb9 100755 --- a/dist/images/install.sh +++ b/dist/images/install.sh @@ -264,6 +264,10 @@ spec: type: string subnet: type: string + replicas: + type: integer + minimum: 1 + maximum: 3 status: type: object properties: diff --git a/pkg/apis/kubeovn/v1/types.go b/pkg/apis/kubeovn/v1/types.go index d81c123ebc6..babd254d88e 100644 --- a/pkg/apis/kubeovn/v1/types.go +++ b/pkg/apis/kubeovn/v1/types.go @@ -853,8 +853,9 @@ type VpcDns struct { } type VpcDNSSpec struct { - Vpc string `json:"vpc"` - Subnet string `json:"subnet"` + Replicas int32 `json:"replicas"` + Vpc string `json:"vpc"` + Subnet string `json:"subnet"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/controller/vpc_dns.go b/pkg/controller/vpc_dns.go index cee1dd15760..38071d4c556 100644 --- a/pkg/controller/vpc_dns.go +++ b/pkg/controller/vpc_dns.go @@ -193,12 +193,6 @@ func (c *Controller) handleAddOrUpdateVPCDNS(key string) error { return err } - if err := c.checkOvnDefaultSpecProvider(); err != nil { - err := fmt.Errorf("failed to check %s spec provider, %v", util.DefaultSubnet, err) - klog.Error(err) - return err - } - if err := c.checkVpcDNSDuplicated(vpcDNS); err != nil { err = fmt.Errorf("failed to deploy %s, %v", vpcDNS.Name, err) klog.Error(err) @@ -277,6 +271,10 @@ func (c *Controller) createOrUpdateVpcDNSDep(vpcDNS *kubeovnv1.VpcDns) error { return err } + if vpcDNS.Spec.Replicas != 0 { + newDp.Spec.Replicas = &vpcDNS.Spec.Replicas + } + if needToCreateDp { _, err := c.config.KubeClient.AppsV1().Deployments(c.config.PodNamespace). Create(context.Background(), newDp, metav1.CreateOptions{}) @@ -491,20 +489,6 @@ func (c *Controller) checkOvnNad() error { return nil } -func (c *Controller) checkOvnDefaultSpecProvider() error { - cachedSubnet, err := c.subnetsLister.Get(util.DefaultSubnet) - if err != nil { - klog.Error(err) - return fmt.Errorf("failed to get default subnet %v", err) - } - - if cachedSubnet.Spec.Provider != nadProvider { - return fmt.Errorf("the %s provider does not exist", nadProvider) - } - - return nil -} - func (c *Controller) resyncVpcDNSConfig() { cm, err := c.configMapsLister.ConfigMaps(c.config.PodNamespace).Get(util.VpcDNSConfig) if err != nil && !k8serrors.IsNotFound(err) { diff --git a/yamls/crd.yaml b/yamls/crd.yaml index a081d1819b6..86943ce0789 100644 --- a/yamls/crd.yaml +++ b/yamls/crd.yaml @@ -39,6 +39,10 @@ spec: type: string subnet: type: string + replicas: + type: integer + minimum: 1 + maximum: 3 status: type: object properties: From e5af67e752dbdbfe969ee3ae7e9034566dda5786 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:31:11 +0800 Subject: [PATCH 4/8] build(deps): bump github.com/onsi/ginkgo/v2 from 2.12.1 to 2.13.0 (#3290) Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.12.1 to 2.13.0. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.12.1...v2.13.0) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 309b082d959..b04aa75a492 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/kubeovn/gonetworkmanager/v2 v2.0.0-20230905082151-e28c4d73a589 github.com/mdlayher/arp v0.0.0-20220512170110-6706a2966875 github.com/moby/sys/mountinfo v0.6.2 - github.com/onsi/ginkgo/v2 v2.12.1 + github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/gomega v1.28.0 github.com/osrg/gobgp/v3 v3.19.0 github.com/ovn-org/libovsdb v0.0.0-20230711201130-6785b52d4020 diff --git a/go.sum b/go.sum index c22aa3c5a9f..3cd6d0aec09 100644 --- a/go.sum +++ b/go.sum @@ -1662,8 +1662,8 @@ github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxm github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= From 286e6340dcd5da3a01b9b5f67d1daa61b94c1c4e Mon Sep 17 00:00:00 2001 From: hzma Date: Tue, 10 Oct 2023 14:09:37 +0800 Subject: [PATCH 5/8] update base image to ubuntu:23.10 (#3289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 马洪贞 --- dist/images/Dockerfile.base | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/images/Dockerfile.base b/dist/images/Dockerfile.base index 62aa0ac1133..06dbecadd63 100644 --- a/dist/images/Dockerfile.base +++ b/dist/images/Dockerfile.base @@ -1,5 +1,5 @@ # syntax = docker/dockerfile:experimental -FROM ubuntu:22.04 as ovs-builder +FROM ubuntu:23.10 as ovs-builder ARG ARCH ARG DEBIAN_FRONTEND=noninteractive @@ -73,7 +73,7 @@ RUN mkdir /packages/ && \ cp /usr/src/ovn-*deb /packages && \ cd /packages && rm -f *source* *doc* *datapath* *docker* *vtep* *test* *dev* -FROM ubuntu:22.04 +FROM ubuntu:23.10 ARG DEBIAN_FRONTEND=noninteractive RUN apt update && apt upgrade -y && apt install ca-certificates python3 hostname libunwind8 netbase \ From b6192f37a15d5a35c0c472c301688dced23ea20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E5=BE=AE=E6=BE=9C?= Date: Wed, 11 Oct 2023 09:16:08 +0800 Subject: [PATCH 6/8] add concurrency limiter to ovs-vsctl (#3288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add concurrency limiter to ovs-vsctl * allow unlimited concurrency --------- Signed-off-by: 夜微澜 --- charts/templates/ovncni-ds.yaml | 1 + charts/values.yaml | 1 + cmd/daemon/cniserver.go | 3 ++ dist/images/install.sh | 2 + pkg/daemon/config.go | 3 ++ pkg/ovs/ovs-vsctl.go | 43 ++++++++++++++-- pkg/ovs/util.go | 44 ++++++++++++++++ pkg/ovs/util_test.go | 91 +++++++++++++++++++++++++++++++++ yamls/kube-ovn-dual-stack.yaml | 1 + yamls/kube-ovn-ipv6.yaml | 1 + 10 files changed, 185 insertions(+), 5 deletions(-) diff --git a/charts/templates/ovncni-ds.yaml b/charts/templates/ovncni-ds.yaml index 16f6a142c74..3cee02330d9 100644 --- a/charts/templates/ovncni-ds.yaml +++ b/charts/templates/ovncni-ds.yaml @@ -79,6 +79,7 @@ spec: - --enable-metrics={{- .Values.networking.ENABLE_METRICS }} - --kubelet-dir={{ .Values.kubelet_conf.KUBELET_DIR }} - --enable-tproxy={{ .Values.func.ENABLE_TPROXY }} + - --ovs-vsctl-concurrency={{ .Values.performance.OVS_VSCTL_CONCURRENCY }} securityContext: runAsUser: 0 privileged: true diff --git a/charts/values.yaml b/charts/values.yaml index ad947b22970..861c3b56ef4 100644 --- a/charts/values.yaml +++ b/charts/values.yaml @@ -97,6 +97,7 @@ performance: RPMS: "openvswitch-kmod" GC_INTERVAL: 360 INSPECT_INTERVAL: 20 + OVS_VSCTL_CONCURRENCY: 100 debug: ENABLE_MIRROR: false diff --git a/cmd/daemon/cniserver.go b/cmd/daemon/cniserver.go index a8776c09beb..58d6a105df0 100644 --- a/cmd/daemon/cniserver.go +++ b/cmd/daemon/cniserver.go @@ -20,6 +20,7 @@ import ( kubeovninformer "github.com/kubeovn/kube-ovn/pkg/client/informers/externalversions" "github.com/kubeovn/kube-ovn/pkg/daemon" + "github.com/kubeovn/kube-ovn/pkg/ovs" "github.com/kubeovn/kube-ovn/pkg/util" "github.com/kubeovn/kube-ovn/versions" ) @@ -37,6 +38,8 @@ func CmdMain() { util.LogFatalAndExit(err, "failed to do the OS initialization") } + ovs.UpdateOVSVsctlLimiter(config.OVSVsctlConcurrency) + nicBridgeMappings, err := daemon.InitOVSBridges() if err != nil { util.LogFatalAndExit(err, "failed to initialize OVS bridges") diff --git a/dist/images/install.sh b/dist/images/install.sh index 5bcb7656eb9..d1be46ed2e8 100755 --- a/dist/images/install.sh +++ b/dist/images/install.sh @@ -33,6 +33,7 @@ IFACE=${IFACE:-} DPDK_TUNNEL_IFACE=${DPDK_TUNNEL_IFACE:-br-phy} ENABLE_BIND_LOCAL_IP=${ENABLE_BIND_LOCAL_IP:-true} ENABLE_TPROXY=${ENABLE_TPROXY:-false} +OVS_VSCTL_CONCURRENCY=${OVS_VSCTL_CONCURRENCY:-100} # debug DEBUG_WRAPPER=${DEBUG_WRAPPER:-} @@ -4069,6 +4070,7 @@ spec: - --log_file_max_size=0 - --kubelet-dir=$KUBELET_DIR - --enable-tproxy=$ENABLE_TPROXY + - --ovs-vsctl-concurrency=$OVS_VSCTL_CONCURRENCY securityContext: runAsUser: 0 privileged: true diff --git a/pkg/daemon/config.go b/pkg/daemon/config.go index 6396caa6dd0..bfcfb8f689b 100644 --- a/pkg/daemon/config.go +++ b/pkg/daemon/config.go @@ -64,6 +64,7 @@ type Configuration struct { TCPConnCheckPort int UDPConnCheckPort int EnableTProxy bool + OVSVsctlConcurrency int32 } // ParseFlags will parse cmd args then init kubeClient and configuration @@ -102,6 +103,7 @@ func ParseFlags() *Configuration { argTCPConnectivityCheckPort = pflag.Int("tcp-conn-check-port", 8100, "TCP connectivity Check Port") argUDPConnectivityCheckPort = pflag.Int("udp-conn-check-port", 8101, "UDP connectivity Check Port") argEnableTProxy = pflag.Bool("enable-tproxy", false, "enable tproxy for vpc pod liveness or readiness probe") + argOVSVsctlConcurrency = pflag.Int32("ovs-vsctl-concurrency", 100, "concurrency limit of ovs-vsctl") ) // mute info log for ipset lib @@ -157,6 +159,7 @@ func ParseFlags() *Configuration { TCPConnCheckPort: *argTCPConnectivityCheckPort, UDPConnCheckPort: *argUDPConnectivityCheckPort, EnableTProxy: *argEnableTProxy, + OVSVsctlConcurrency: *argOVSVsctlConcurrency, } return config } diff --git a/pkg/ovs/ovs-vsctl.go b/pkg/ovs/ovs-vsctl.go index 681e312c0f5..05c50c760f6 100644 --- a/pkg/ovs/ovs-vsctl.go +++ b/pkg/ovs/ovs-vsctl.go @@ -1,6 +1,7 @@ package ovs import ( + "context" "fmt" "os/exec" "regexp" @@ -13,25 +14,57 @@ import ( "github.com/kubeovn/kube-ovn/pkg/util" ) +var limiter *Limiter + +func init() { + limiter = new(Limiter) +} + +func UpdateOVSVsctlLimiter(c int32) { + if c >= 0 { + limiter.Update(c) + klog.V(4).Infof("update ovs-vsctl concurrency limit to %d", limiter.Limit()) + } +} + // Glory belongs to openvswitch/ovn-kubernetes // https://github.com/openvswitch/ovn-kubernetes/blob/master/go-controller/pkg/util/ovs.go var podNetNsRegexp = regexp.MustCompile(`pod_netns="([^"]+)"`) func Exec(args ...string) (string, error) { - start := time.Now() + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + var ( + start time.Time + elapsed float64 + output []byte + method, code string + err error + ) + + if err = limiter.Wait(ctx); err != nil { + klog.V(4).Infof("command %s %s waiting for execution timeout by concurrency limit of %d", OvsVsCtl, strings.Join(args, " "), limiter.Limit()) + return "", err + } + defer limiter.Done() + klog.V(4).Infof("command %s %s waiting for execution concurrency %d/%d", OvsVsCtl, strings.Join(args, " "), limiter.Current(), limiter.Limit()) + + start = time.Now() args = append([]string{"--timeout=30"}, args...) - output, err := exec.Command(OvsVsCtl, args...).CombinedOutput() - elapsed := float64((time.Since(start)) / time.Millisecond) + output, err = exec.Command(OvsVsCtl, args...).CombinedOutput() + elapsed = float64((time.Since(start)) / time.Millisecond) klog.V(4).Infof("command %s %s in %vms", OvsVsCtl, strings.Join(args, " "), elapsed) - method := "" + for _, arg := range args { if !strings.HasPrefix(arg, "--") { method = arg break } } - code := "0" + + code = "0" defer func() { ovsClientRequestLatency.WithLabelValues("ovsdb", method, code).Observe(elapsed) }() diff --git a/pkg/ovs/util.go b/pkg/ovs/util.go index 43cd59a920e..e16daf3fca2 100644 --- a/pkg/ovs/util.go +++ b/pkg/ovs/util.go @@ -1,9 +1,12 @@ package ovs import ( + "context" "fmt" "regexp" "strings" + "sync/atomic" + "time" kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/util" @@ -235,3 +238,44 @@ func (m aclMatch) String() string { rule, _ := m.Match() return rule } + +type Limiter struct { + limit int32 + current int32 +} + +func (l *Limiter) Limit() int32 { + return l.limit +} + +func (l *Limiter) Current() int32 { + return atomic.LoadInt32(&l.current) +} + +func (l *Limiter) Update(limit int32) { + l.limit = limit +} + +func (l *Limiter) Wait(ctx context.Context) error { + for { + select { + case <-ctx.Done(): + return fmt.Errorf("context canceled by timeout") + default: + if l.limit == 0 { + atomic.AddInt32(&l.current, 1) + return nil + } + + if atomic.LoadInt32(&l.current) < l.limit { + atomic.AddInt32(&l.current, 1) + return nil + } + time.Sleep(10 * time.Millisecond) + } + } +} + +func (l *Limiter) Done() { + atomic.AddInt32(&l.current, -1) +} diff --git a/pkg/ovs/util_test.go b/pkg/ovs/util_test.go index 0fd0c57e9e2..9a54a9fd801 100644 --- a/pkg/ovs/util_test.go +++ b/pkg/ovs/util_test.go @@ -1,7 +1,9 @@ package ovs import ( + "context" "testing" + "time" "github.com/stretchr/testify/require" ) @@ -229,3 +231,92 @@ func Test_OrAclMatch_Match(t *testing.T) { require.ErrorContains(t, err, "acl rule key is required") }) } + +func Test_Limiter(t *testing.T) { + t.Parallel() + + t.Run("without limit", func(t *testing.T) { + t.Parallel() + + var ( + limiter *Limiter + err error + ) + + limiter = new(Limiter) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(1), limiter.Current()) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(2), limiter.Current()) + + limiter.Done() + require.Equal(t, int32(1), limiter.Current()) + + limiter.Done() + require.Equal(t, int32(0), limiter.Current()) + }) + + t.Run("with limit", func(t *testing.T) { + t.Parallel() + + var ( + limiter *Limiter + err error + ) + + limiter = new(Limiter) + limiter.Update(2) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(1), limiter.Current()) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(2), limiter.Current()) + + time.AfterFunc(10*time.Second, func() { + limiter.Done() + require.Equal(t, int32(1), limiter.Current()) + }) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(2), limiter.Current()) + }) + + t.Run("with timeout", func(t *testing.T) { + t.Parallel() + + var ( + limiter *Limiter + err error + ) + + limiter = new(Limiter) + limiter.Update(2) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(1), limiter.Current()) + + err = limiter.Wait(context.Background()) + require.NoError(t, err) + require.Equal(t, int32(2), limiter.Current()) + + time.AfterFunc(10*time.Second, func() { + limiter.Done() + }) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = limiter.Wait(ctx) + require.ErrorContains(t, err, "context canceled by timeout") + require.Equal(t, int32(2), limiter.Current()) + }) +} diff --git a/yamls/kube-ovn-dual-stack.yaml b/yamls/kube-ovn-dual-stack.yaml index a8cfe7a11ff..dde6e05e04a 100644 --- a/yamls/kube-ovn-dual-stack.yaml +++ b/yamls/kube-ovn-dual-stack.yaml @@ -201,6 +201,7 @@ spec: - --log_file=/var/log/kube-ovn/kube-ovn-cni.log - --log_file_max_size=0 - --enable-tproxy=false + - --ovs-vsctl-concurrency=100 securityContext: runAsUser: 0 privileged: true diff --git a/yamls/kube-ovn-ipv6.yaml b/yamls/kube-ovn-ipv6.yaml index a0d3e8a2b20..1ecd23c9cfd 100644 --- a/yamls/kube-ovn-ipv6.yaml +++ b/yamls/kube-ovn-ipv6.yaml @@ -201,6 +201,7 @@ spec: - --log_file=/var/log/kube-ovn/kube-ovn-cni.log - --log_file_max_size=0 - --enable-tproxy=false + - --ovs-vsctl-concurrency=100 securityContext: runAsUser: 0 privileged: true From 01df3964521c7a1fb028944d6468f6b67d6ced0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:43:13 +0800 Subject: [PATCH 7/8] build(deps): bump golang.org/x/net from 0.16.0 to 0.17.0 (#3296) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.16.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b04aa75a492..dd189ffa864 100644 --- a/go.mod +++ b/go.mod @@ -231,7 +231,7 @@ require ( go.uber.org/zap v1.25.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/net v0.16.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/sync v0.4.0 // indirect golang.org/x/term v0.13.0 // indirect diff --git a/go.sum b/go.sum index 3cd6d0aec09..ba81b921dd2 100644 --- a/go.sum +++ b/go.sum @@ -2299,8 +2299,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From 9f93981d676813a6d10bfc9b96cf290f8931066d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:43:30 +0800 Subject: [PATCH 8/8] build(deps): bump google.golang.org/grpc from 1.58.2 to 1.58.3 (#3295) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.2 to 1.58.3. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.58.2...v1.58.3) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dd189ffa864..3e778dd6624 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( golang.org/x/mod v0.13.0 golang.org/x/sys v0.13.0 golang.org/x/time v0.3.0 - google.golang.org/grpc v1.58.2 + google.golang.org/grpc v1.58.3 google.golang.org/protobuf v1.31.0 gopkg.in/k8snetworkplumbingwg/multus-cni.v4 v4.0.2 k8s.io/api v0.28.2 diff --git a/go.sum b/go.sum index ba81b921dd2..db7928d09b4 100644 --- a/go.sum +++ b/go.sum @@ -2923,8 +2923,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= -google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=