Skip to content

Commit

Permalink
move to CNI controller and remove bridge plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
aojea committed May 26, 2024
1 parent af0a651 commit 96b3d5d
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 462 deletions.
10 changes: 1 addition & 9 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ jobs:
fail-fast: false
matrix:
ipFamily: ["ipv4", "ipv6", "dual"]
cniMode: ["ptp", "bridge"]
env:
JOB_NAME: "kindnetd-e2e-${{ matrix.ipFamily }}-${{ matrix.cniMode }}"
JOB_NAME: "kindnetd-e2e-${{ matrix.ipFamily }}"
IP_FAMILY: ${{ matrix.ipFamily }}
steps:
- name: Check out code
Expand Down Expand Up @@ -118,17 +117,10 @@ jobs:
/usr/local/bin/kind load docker-image ghcr.io/aojea/kindnetd:test --name ${{ env.KIND_CLUSTER_NAME}}
- name: install ptp plugin
if: ${{ matrix.cniMode == 'ptp' }}
run: |
sed -i s#aojea/kindnetd.*#aojea/kindnetd:test# install-kindnet.yaml
/usr/local/bin/kubectl apply -f ./install-kindnet.yaml
- name: install bridge plugin
if: ${{ matrix.cniMode == 'bridge' }}
run: |
sed -i s#aojea/kindnetd.*#aojea/kindnetd:test# install-kindnet-bridge.yaml
/usr/local/bin/kubectl apply -f ./install-kindnet-bridge.yaml
- name: Get Cluster status
run: |
# wait network is ready
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ RUN echo "Installing CNI binaries ..." \
&& find /opt/cni/bin -type f -not \( \
-iname host-local \
-o -iname ptp \
-o -iname bridge \
-o -iname portmap \
\) \
-delete
Expand Down
146 changes: 15 additions & 131 deletions cmd/kindnetd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,8 @@ import (
"golang.org/x/sys/unix"

"github.com/aojea/kindnet/pkg/cni"
utilnet "github.com/aojea/kindnet/pkg/net"
"github.com/aojea/kindnet/pkg/router"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -60,7 +56,7 @@ const (
AllFamily IPFamily = unix.AF_UNSPEC
IPv4Family IPFamily = unix.AF_INET
IPv6Family IPFamily = unix.AF_INET6
DualStackFamily IPFamily = 12 // AF_INET + AF_INET6
DualStackFamily IPFamily = unix.AF_UNSPEC
)

var (
Expand Down Expand Up @@ -119,18 +115,8 @@ func main() {
}()
signal.Notify(signalCh, os.Interrupt, unix.SIGINT)

go func() {
select {
case <-signalCh:
klog.Infof("Exiting: received signal")
cancel()
case <-ctx.Done():
}
}()

informersFactory := informers.NewSharedInformerFactory(clientset, 0)
nodeInformer := informersFactory.Core().V1().Nodes()
nodeLister := nodeInformer.Lister()

// obtain the host and pod ip addresses
hostIP, podIP := os.Getenv("HOST_IP"), os.Getenv("POD_IP")
Expand All @@ -142,28 +128,6 @@ func main() {
))
}

mtu, err := utilnet.GetMTU(int(AllFamily))
klog.Infof("setting mtu %d for CNI \n", mtu)
if err != nil {
klog.Infof("Failed to get MTU size from interface eth0, using kernel default MTU size error:%v", err)
}

// CNI_BRIDGE env variable uses the CNI bridge plugin, defaults to ptp
useBridge := len(os.Getenv("CNI_BRIDGE")) > 0
// disable offloading in the bridge if exists
disableOffload := false
if useBridge {
disableOffload = len(os.Getenv("DISABLE_CNI_BRIDGE_OFFLOAD")) > 0
}
// used to track if the cni config inputs changed and write the config
cniConfigWriter := &cni.CNIConfigWriter{
Path: cni.CNIConfigPath,
Bridge: useBridge,
MTU: mtu,
}
klog.Infof("Configuring CNI path: %s bridge: %v disableOffload: %v mtu: %d",
cni.CNIConfigPath, useBridge, disableOffload, mtu)

// enforce ip masquerade rules
noMaskIPv4Subnets, noMaskIPv6Subnets := getNoMasqueradeSubnets(clientset)
// detect the cluster IP family based on the Cluster CIDR akka PodSubnet
Expand Down Expand Up @@ -209,111 +173,31 @@ func main() {
}()
}

// setup nodes reconcile function, closes over arguments
reconcileNodes := makeNodesReconciler(cniConfigWriter, hostIP, ipFamily, clientset)

// main control loop
informersFactory.Start(ctx.Done())

// routes controller
// CNI config controller
go func() {
err := router.New(hostname, clientset, nodeInformer).Run(ctx, 5)
err := cni.New(hostname, clientset, nodeInformer, int(ipFamily)).Run(ctx, 1)
if err != nil {
klog.Infof("error running router controller: %v", err)
}
}()

for {
// Gets the Nodes information from the API
// TODO: use a proper controller instead
var nodes []*corev1.Node
var err error
for i := 0; i < 5; i++ {
nodes, err = nodeLister.List(labels.Everything())
if err == nil {
break
}
klog.Infof("Failed to get nodes, retrying after error: %v", err)
time.Sleep(time.Second * time.Duration(i))
}
if err != nil {
panic("Reached maximum retries obtaining node list: " + err.Error())
}

// reconcile the nodes with retries
for i := 0; i < 5; i++ {
err = reconcileNodes(nodes)
if err == nil {
break
}
klog.Infof("Failed to reconcile routes, retrying after error: %v", err)
time.Sleep(time.Second * time.Duration(i))
}
// routes controller
go func() {
err := router.New(hostname, clientset, nodeInformer).Run(ctx, 5)
if err != nil {
panic("Maximum retries reconciling node routes: " + err.Error())
}

// disable offload if required
if disableOffload {
err = SetChecksumOffloading("kind-br", false, false)
if err != nil {
klog.Infof("Failed to disable offloading on interface kind-br: %v", err)
} else {
disableOffload = false
}
}

// rate limit
select {
case <-ctx.Done():
return
default:
time.Sleep(10 * time.Second)
}
}
}

// nodeNodesReconciler returns a reconciliation func for nodes
func makeNodesReconciler(cniConfig *cni.CNIConfigWriter, hostIP string, ipFamily IPFamily, clientset *kubernetes.Clientset) func([]*corev1.Node) error {
// reconciles a node
reconcileNode := func(node *corev1.Node) error {
// first get this node's IPs
// we don't support more than one IP address per IP family for simplification
nodeIPs := internalIPs(node)
klog.Infof("Handling node with IPs: %v\n", nodeIPs)
// This is our node. We don't need to add routes, but we might need to
// update the cni config and "annotate" our external IPs
if nodeIPs.Has(hostIP) {
klog.Info("handling current node\n")
// compute the current cni config inputs
if err := cniConfig.Write(
cni.ComputeCNIConfigInputs(node),
); err != nil {
return err
}
}
return nil
}

// return a reconciler for all the nodes
return func(nodes []*corev1.Node) error {
for _, node := range nodes {
if err := reconcileNode(node); err != nil {
return err
}
klog.Infof("error running router controller: %v", err)
}
return nil
}
}
}()

// internalIPs returns the internal IP address for node
func internalIPs(node *corev1.Node) sets.Set[string] {
ips := sets.New[string]()
// check the node.Status.Addresses
for _, address := range node.Status.Addresses {
if address.Type == "InternalIP" {
ips.Insert(address.Address)
}
select {
case <-signalCh:
klog.Infof("Exiting: received signal")
cancel()
case <-ctx.Done():
}
return ips
// Time for gracefully shutdown
time.Sleep(1 * time.Second)
}
123 changes: 0 additions & 123 deletions install-kindnet-bridge.yaml

This file was deleted.

Loading

0 comments on commit 96b3d5d

Please sign in to comment.