github.com/cilium/cilium@v1.16.2/test/k8s/bandwidth.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package k8sTest
     5  
     6  import (
     7  	"fmt"
     8  
     9  	. "github.com/onsi/gomega"
    10  
    11  	. "github.com/cilium/cilium/test/ginkgo-ext"
    12  	"github.com/cilium/cilium/test/helpers"
    13  )
    14  
    15  var _ = SkipDescribeIf(helpers.DoesNotRunOnNetNextKernel, "K8sDatapathBandwidthTest", func() {
    16  	var (
    17  		kubectl        *helpers.Kubectl
    18  		ciliumFilename string
    19  		demoYAML       string
    20  	)
    21  
    22  	BeforeAll(func() {
    23  		kubectl = helpers.CreateKubectl(helpers.K8s1VMName(), logger)
    24  
    25  		ciliumFilename = helpers.TimestampFilename("cilium.yaml")
    26  
    27  		demoYAML = helpers.ManifestGet(kubectl.BasePath(), "demo_bw.yaml")
    28  		res := kubectl.ApplyDefault(demoYAML)
    29  		res.ExpectSuccess("Unable to apply %s", demoYAML)
    30  	})
    31  
    32  	AfterAll(func() {
    33  		kubectl.Delete(demoYAML)
    34  		ExpectAllPodsTerminated(kubectl)
    35  
    36  		UninstallCiliumFromManifest(kubectl, ciliumFilename)
    37  		ExpectAllPodsTerminated(kubectl)
    38  
    39  		kubectl.CloseSSHClient()
    40  	})
    41  
    42  	Context("Checks Bandwidth Rate-Limiting", func() {
    43  		const (
    44  			testDS10       = "run=netperf-10"
    45  			testDS25       = "run=netperf-25"
    46  			testClientPod  = "run=netperf-client-pod"
    47  			testClientHost = "run=netperf-client-host"
    48  
    49  			maxRateDeviation = 5
    50  			minBandwidth     = 1
    51  		)
    52  
    53  		var (
    54  			podLabels = []string{
    55  				testDS10,
    56  				testDS25,
    57  			}
    58  		)
    59  
    60  		AfterFailed(func() {
    61  			kubectl.CiliumReport("cilium-dbg bpf bandwidth list", "cilium-dbg endpoint list")
    62  		})
    63  
    64  		JustAfterEach(func() {
    65  			kubectl.ValidateNoErrorsInLogs(CurrentGinkgoTestDescription().Duration)
    66  		})
    67  
    68  		waitForTestPods := func() {
    69  			podLabels := []string{
    70  				testDS10,
    71  				testDS25,
    72  				testClientPod,
    73  				testClientHost,
    74  			}
    75  			for _, label := range podLabels {
    76  				err := kubectl.WaitforPods(helpers.DefaultNamespace,
    77  					fmt.Sprintf("-l %s", label), helpers.HelperTimeout)
    78  				Expect(err).Should(BeNil())
    79  			}
    80  		}
    81  
    82  		testNetperfFromPods := func(clientPodLabel, targetIP string, maxSessions, rate int) {
    83  			pods, err := kubectl.GetPodNames(helpers.DefaultNamespace, clientPodLabel)
    84  			ExpectWithOffset(1, err).Should(BeNil(), "cannot retrieve pod names by filter %q",
    85  				clientPodLabel)
    86  			for i := 1; i <= maxSessions; i++ {
    87  				cmd := helpers.SuperNetperf(i, targetIP, helpers.TCP_MAERTS, "")
    88  				for _, pod := range pods {
    89  					By("Running %d netperf session from %s pod to pod with IP %s (expected rate: %d)",
    90  						i, pod, targetIP, rate)
    91  					res := kubectl.ExecPodCmd(helpers.DefaultNamespace, pod, cmd)
    92  					ExpectWithOffset(1, res).Should(helpers.CMDSuccess(),
    93  						"Request from %s pod to pod with IP %s failed", pod, targetIP)
    94  					By("Session test completed, netperf result raw: %s", res.SingleOut())
    95  					if rate > 0 {
    96  						ExpectWithOffset(1, res.InRange(minBandwidth, rate+maxRateDeviation)).To(BeNil(),
    97  							"Rate mismatch")
    98  					}
    99  				}
   100  			}
   101  		}
   102  
   103  		testNetperf := func(podLabels []string, fromLabel string) {
   104  			for _, label := range podLabels {
   105  				podIPs, err := kubectl.GetPodsIPs(helpers.DefaultNamespace, label)
   106  				ExpectWithOffset(1, err).Should(BeNil(), "Cannot retrieve pod IPs for %s", label)
   107  				ExpectWithOffset(1, len(podIPs)).To(Equal(int(1)), "Expected pod IPs mismatch")
   108  				rate := 0
   109  				fmt.Sscanf(label, "run=netperf-%d", &rate)
   110  				for _, podIP := range podIPs {
   111  					testNetperfFromPods(fromLabel, podIP, 1, rate)
   112  				}
   113  			}
   114  		}
   115  
   116  		It("Checks Pod to Pod bandwidth, vxlan tunneling", func() {
   117  			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
   118  				"bandwidthManager.enabled": "true",
   119  				"tunnelProtocol":           "vxlan",
   120  			})
   121  			waitForTestPods()
   122  			testNetperf(podLabels, testClientPod)
   123  			testNetperf(podLabels, testClientHost)
   124  		})
   125  		It("Checks Pod to Pod bandwidth, geneve tunneling", func() {
   126  			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
   127  				"bandwidthManager.enabled": "true",
   128  				"tunnelProtocol":           "geneve",
   129  			})
   130  			waitForTestPods()
   131  			testNetperf(podLabels, testClientPod)
   132  			testNetperf(podLabels, testClientHost)
   133  		})
   134  		It("Checks Pod to Pod bandwidth, direct routing", func() {
   135  			DeployCiliumOptionsAndDNS(kubectl, ciliumFilename, map[string]string{
   136  				"bandwidthManager.enabled": "true",
   137  				"routingMode":              "native",
   138  				"autoDirectNodeRoutes":     "true",
   139  			})
   140  			waitForTestPods()
   141  			testNetperf(podLabels, testClientPod)
   142  			testNetperf(podLabels, testClientHost)
   143  		})
   144  	})
   145  })