Skip to content
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

[Gateway] Geneve interface cleanup #2938

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions cmd/gateway/geneve/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

networkingv1beta1 "github.com/liqotech/liqo/apis/networking/v1beta1"
"github.com/liqotech/liqo/pkg/gateway"
"github.com/liqotech/liqo/pkg/gateway/cleanup"
"github.com/liqotech/liqo/pkg/gateway/concurrent"
"github.com/liqotech/liqo/pkg/gateway/fabric"
"github.com/liqotech/liqo/pkg/gateway/fabric/geneve"
Expand Down Expand Up @@ -118,14 +119,23 @@ func run(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("unable to setup internalnode reconciler: %w", err)
}

runnable, err := concurrent.NewRunnableGuest(options.GwOptions.ContainerName)
runnableGuest, err := concurrent.NewRunnableGuest(options.GwOptions.ContainerName)
if err != nil {
return fmt.Errorf("unable to create runnable guest: %w", err)
}
if err := runnable.Start(cmd.Context()); err != nil {
if err := runnableGuest.Start(cmd.Context()); err != nil {
return fmt.Errorf("unable to start runnable guest: %w", err)
}
defer runnable.Close()
defer runnableGuest.Close()

runnableGeneveCleanup, err := cleanup.NewRunnableGeneveCleanup(mgr.GetClient(), options.GeneveCleanupInterval)
if err != nil {
return fmt.Errorf("unable to create runnable geneve cleanup: %w", err)
}

if err := mgr.Add(runnableGeneveCleanup); err != nil {
return fmt.Errorf("unable to add geneve cleanup runnable: %w", err)
}

// Start the manager.
return mgr.Start(cmd.Context())
Expand Down
2 changes: 1 addition & 1 deletion cmd/gateway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func run(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("unable to setup firewall configuration reconciler: %w", err)
}

runnable, err := concurrent.NewRunnableGateway(
runnable, err := concurrent.NewRunnableGatewayStartup(
cl,
connoptions.GwOptions.PodName,
connoptions.GwOptions.Name,
Expand Down
4 changes: 4 additions & 0 deletions pkg/consts/internalnetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@

package consts

import "time"

const (
// DefaultGenevePort is the default port used for the geneve tunnel.
DefaultGenevePort uint16 = 6091
// DefaultGeneveCleanupInterval is the default interval used to cleanup the geneve tunnels.
DefaultGeneveCleanupInterval = time.Minute * 30
// DefaultRouteTable is the name of the default table used for routes.
DefaultRouteTable = "liqo"
// InternalFabricName is the label used to identify the internal fabric name.
Expand Down
12 changes: 6 additions & 6 deletions pkg/fabric/finalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ const (
)

func (r *InternalFabricReconciler) ensureinternalfabricFinalizerPresence(
ctx context.Context, fwcfg *networkingv1beta1.InternalFabric) error {
ctrlutil.AddFinalizer(fwcfg, internalfabricControllerFinalizer)
return r.Client.Update(ctx, fwcfg)
ctx context.Context, internalfabric *networkingv1beta1.InternalFabric) error {
ctrlutil.AddFinalizer(internalfabric, internalfabricControllerFinalizer)
return r.Client.Update(ctx, internalfabric)
}

func (r *InternalFabricReconciler) ensureinternalfabricFinalizerAbsence(
ctx context.Context, fwcfg *networkingv1beta1.InternalFabric) error {
ctrlutil.RemoveFinalizer(fwcfg, internalfabricControllerFinalizer)
return r.Client.Update(ctx, fwcfg)
ctx context.Context, internalfabric *networkingv1beta1.InternalFabric) error {
ctrlutil.RemoveFinalizer(internalfabric, internalfabricControllerFinalizer)
return r.Client.Update(ctx, internalfabric)
}
93 changes: 93 additions & 0 deletions pkg/gateway/cleanup/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2019-2025 The Liqo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cleanup

import (
"context"
"fmt"
"time"

"k8s.io/apimachinery/pkg/labels"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"

"github.com/liqotech/liqo/pkg/utils/getters"
"github.com/liqotech/liqo/pkg/utils/network/geneve"
)

var _ manager.Runnable = &RunnableGeneveCleanup{}

// RunnableGeneveCleanup is a RunnableGeneveCleanup that manages concurrency.
type RunnableGeneveCleanup struct {
Client client.Client
Interval time.Duration
}

// NewRunnableGeneveCleanup creates a new Runnable.
func NewRunnableGeneveCleanup(cl client.Client, interval time.Duration) (*RunnableGeneveCleanup, error) {
return &RunnableGeneveCleanup{
Client: cl,
Interval: interval,
}, nil
}

// Start implements manager.Runnable.
func (rgc *RunnableGeneveCleanup) Start(ctx context.Context) error {
klog.Infof("Running geneve cleanup every %s", rgc.Interval)

ticker := time.NewTicker(rgc.Interval)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return nil
case <-ticker.C:
if err := geneveCleanup(ctx, rgc.Client); err != nil {
return fmt.Errorf("geneve cleanup failed: %w", err)
}
}
}
}

func geneveCleanup(ctx context.Context, cl client.Client) error {
interfaceList, err := geneve.ListGeneveInterfaces()
if err != nil {
return fmt.Errorf("failed to list geneve interfaces: %w", err)
}

internalnodesList, err := getters.ListInternalNodesByLabels(ctx, cl, labels.Everything())
if err != nil {
return fmt.Errorf("failed to list internal nodes: %w", err)
}

internalnodesMap := make(map[string]any)
for i := range internalnodesList.Items {
internalnodesMap[internalnodesList.Items[i].Spec.Interface.Gateway.Name] = struct{}{}
}

for _, interfaceItem := range interfaceList {
if _, ok := internalnodesMap[interfaceItem.Attrs().Name]; !ok {
klog.Infof("geneve interface %s is not needed anymore", interfaceItem.Attrs().Name)
if err := geneve.EnsureGeneveInterfaceAbsence(interfaceItem.Attrs().Name); err != nil {
return fmt.Errorf("failed to delete geneve interface %s: %w", interfaceItem, err)
}
klog.Infof("geneve interface %s deleted", interfaceItem.Attrs().Name)
}
}

return nil
}
16 changes: 16 additions & 0 deletions pkg/gateway/cleanup/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019-2025 The Liqo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cleanup provides a gateway to the cleanup service.
package cleanup
4 changes: 2 additions & 2 deletions pkg/gateway/concurrent/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ type RunnableGateway struct {
GuestConnections ipc.GuestConnections
}

// NewRunnableGateway creates a new Runnable.
func NewRunnableGateway(cl client.Client, podName, gatewayName, namespace string, containerNames []string) (*RunnableGateway, error) {
// NewRunnableGatewayStartup creates a new Runnable.
func NewRunnableGatewayStartup(cl client.Client, podName, gatewayName, namespace string, containerNames []string) (*RunnableGateway, error) {
guestConnections := ipc.NewGuestConnections(containerNames)

socket, err := ipc.CreateListenSocket(unixSocketPath)
Expand Down
4 changes: 4 additions & 0 deletions pkg/gateway/fabric/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ const (
FlagNameDisableARP FlagName = "disable-arp"
// FlagNameGenevePort is the flag to set the Geneve port.
FlagNameGenevePort FlagName = "geneve-port"
// FlagNameGeneveCleanupInterval is the flag to set the Geneve cleanup interval.
FlagNameGeneveCleanupInterval FlagName = "geneve-cleanup-interval"
)

// InitFlags initializes the flags for the gateway.
func InitFlags(flagset *pflag.FlagSet, opts *Options) {
flagset.BoolVar(&opts.DisableARP, FlagNameDisableARP.String(), false, "Disable ARP")
flagset.Uint16Var(&opts.GenevePort, FlagNameGenevePort.String(), consts.DefaultGenevePort, "Geneve port")
flagset.DurationVar(&opts.GeneveCleanupInterval, FlagNameGeneveCleanupInterval.String(),
consts.DefaultGeneveCleanupInterval, "Geneve cleanup interval")
}
9 changes: 6 additions & 3 deletions pkg/gateway/fabric/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
package fabric

import (
"time"

"github.com/liqotech/liqo/pkg/gateway"
)

// Options contains the options for the wireguard interface.
type Options struct {
GwOptions *gateway.Options
DisableARP bool
GenevePort uint16
GwOptions *gateway.Options
DisableARP bool
GenevePort uint16
GeneveCleanupInterval time.Duration
}

// NewOptions returns a new Options struct.
Expand Down
15 changes: 15 additions & 0 deletions pkg/utils/network/geneve/netlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,18 @@ func ExistGeneveInterfaceAddr(link netlink.Link, addr net.IP) *netlink.Addr {
}
return nil
}

// ListGeneveInterfaces returns all the geneve interfaces.
func ListGeneveInterfaces() ([]netlink.Link, error) {
links, err := netlink.LinkList()
if err != nil {
return nil, fmt.Errorf("cannot list geneve links: %w", err)
}
var geneveLinks []netlink.Link
for i := range links {
if links[i].Type() == "geneve" {
geneveLinks = append(geneveLinks, links[i])
}
}
return geneveLinks, nil
}
Loading