Skip to content

Commit fb5c570

Browse files
authored
Add support to use existing bridge NetworkAttachementDefinition (#175)
- Add bridgeinfo to various output data targets
1 parent 433412e commit fb5c570

File tree

8 files changed

+225
-80
lines changed

8 files changed

+225
-80
lines changed

cmd/k8s-netperf/k8s-netperf.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var (
5151
debug bool
5252
bridge string
5353
bridgeNetwork string
54+
bridgeNamespace string
5455
promURL string
5556
id string
5657
searchURL string
@@ -123,12 +124,14 @@ var rootCmd = &cobra.Command{
123124
cleanup(client)
124125
}
125126
s := config.PerfScenarios{
126-
HostNetwork: full,
127-
NodeLocal: nl,
128-
AcrossAZ: acrossAZ,
129-
RestConfig: *rconfig,
130-
Configs: cfg,
131-
ClientSet: client,
127+
HostNetwork: full,
128+
NodeLocal: nl,
129+
AcrossAZ: acrossAZ,
130+
RestConfig: *rconfig,
131+
Configs: cfg,
132+
ClientSet: client,
133+
BridgeNetwork: bridge,
134+
BridgeNamespace: bridgeNamespace,
132135
}
133136
if serverIPAddr != "" {
134137
s.ExternalServer = true
@@ -213,6 +216,25 @@ var rootCmd = &cobra.Command{
213216
}
214217
}
215218

219+
// Validate bridge network configuration before creating pods
220+
if bridge != "" && !vm {
221+
// Create dynamic client for validation if not already created
222+
var dynClient dynamic.Interface
223+
if s.DClient != nil {
224+
dynClient = s.DClient
225+
} else {
226+
dynClient, err = dynamic.NewForConfig(rconfig)
227+
if err != nil {
228+
log.Fatalf("Failed to create dynamic client for bridge validation: %v", err)
229+
}
230+
}
231+
232+
err = k8s.ValidateBridgeNetwork(client, dynClient, bridge, bridgeNamespace)
233+
if err != nil {
234+
log.Fatalf("Bridge network validation failed: %v", err)
235+
}
236+
}
237+
216238
// Build the SUT (Deployments)
217239
err = k8s.BuildSUT(client, &s)
218240
if err != nil {
@@ -491,9 +513,22 @@ func executeWorkload(nc config.Config,
491513
if s.VM {
492514
npr.UdnInfo = npr.UdnInfo + " - " + s.UdnPluginBinding
493515
}
494-
//when using a bridge
516+
} else if s.BridgeNetwork != "" {
517+
// For regular pods, extract bridge IP from network status
518+
serverIP, err = k8s.ExtractBridgeIp(s.Server.Items[0], s.BridgeNetwork, s.BridgeNamespace)
519+
if err != nil {
520+
log.Errorf("Failed to extract bridge IP: %v", err)
521+
// Fall back to default IP
522+
serverIP = s.Server.Items[0].Status.PodIP
523+
}
524+
log.Debugf("Using bridge network IP: %s (interface: net1)", serverIP)
525+
526+
// Set bridge info similar to UdnInfo
527+
npr.BridgeInfo = fmt.Sprintf("%s/%s", s.BridgeNamespace, s.BridgeNetwork)
495528
} else if s.BridgeServerNetwork != "" {
529+
// For VMs, use static bridge IP from JSON config
496530
serverIP = strings.Split(s.BridgeServerNetwork, "/")[0]
531+
npr.BridgeInfo = fmt.Sprintf("VM Bridge (%s)", serverIP)
497532
} else {
498533
if hostNet {
499534
serverIP = s.ServerHost.Items[0].Status.PodIP
@@ -595,8 +630,9 @@ func main() {
595630
rootCmd.Flags().BoolVar(&udnl3, "udnl3", false, "Create and use a layer3 UDN as a primary network.")
596631
rootCmd.MarkFlagsMutuallyExclusive("udnl2", "udnl3")
597632
rootCmd.Flags().StringVar(&udnPluginBinding, "udnPluginBinding", "passt", "UDN with VMs only - the binding method of the UDN interface, select 'passt' or 'l2bridge'")
598-
rootCmd.Flags().StringVar(&bridge, "bridge", "", "Name of the NNCP to be used for creating bridge interface - VM only.")
599-
rootCmd.Flags().StringVar(&bridgeNetwork, "bridgeNetwork", "bridgeNetwork.json", "Json file for the network defined by the bridge interface - bridge should be enabled")
633+
rootCmd.Flags().StringVar(&bridge, "bridge", "", "Name of the NetworkAttachmentDefinition to be used for bridge interface")
634+
rootCmd.Flags().StringVar(&bridgeNamespace, "bridgeNamespace", "default", "Namespace of the NetworkAttachmentDefinition for bridge interface")
635+
rootCmd.Flags().StringVar(&bridgeNetwork, "bridgeNetwork", "bridgeNetwork.json", "Json file for the VM network defined by the bridge interface - bridge should be enabled")
600636
rootCmd.Flags().StringVar(&promURL, "prom", "", "Prometheus URL")
601637
rootCmd.Flags().StringVar(&id, "uuid", "", "User provided UUID")
602638
rootCmd.Flags().StringVar(&searchURL, "search", "", "OpenSearch URL, if you have auth, pass in the format of https://user:pass@url:port")

pkg/archive/archive.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Doc struct {
5757
ClientVSwiitchMem float64 `json:"clientVswitchMem"`
5858
ExternalServer bool `json:"externalServer"`
5959
UdnInfo string `json:"udnInfo"`
60+
BridgeInfo string `json:"bridgeInfo"`
6061
}
6162

6263
// Connect returns a client connected to the desired cluster.
@@ -130,6 +131,7 @@ func BuildDocs(sr result.ScenarioResults, uuid string) ([]interface{}, error) {
130131
ClientNodeInfo: r.ClientNodeInfo,
131132
ServerNodeInfo: r.ServerNodeInfo,
132133
UdnInfo: r.UdnInfo,
134+
BridgeInfo: r.BridgeInfo,
133135
}
134136
UDPLossPercent, e := result.Average(r.LossSummary)
135137
if e != nil {
@@ -174,6 +176,7 @@ func commonCsvHeaderFields() []string {
174176
"Service",
175177
"External Server",
176178
"UDN Info",
179+
"Bridge Info",
177180
"Duration",
178181
"Parallelism",
179182
"# of Samples",
@@ -198,6 +201,7 @@ func commonCsvDataFields(row result.Data) []string {
198201
fmt.Sprint(row.Service),
199202
fmt.Sprint(row.ExternalServer),
200203
fmt.Sprint(row.UdnInfo),
204+
fmt.Sprint(row.BridgeInfo),
201205
strconv.Itoa(row.Duration),
202206
strconv.Itoa(row.Parallelism),
203207
strconv.Itoa(row.Samples),

pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ type PerfScenarios struct {
4242
VMHost string
4343
Udn bool
4444
UdnPluginBinding string
45+
BridgeNetwork string
46+
BridgeNamespace string
4547
BridgeServerNetwork string
4648
BridgeClientNetwork string
4749
ServerNodeInfo metrics.NodeInfo

pkg/drivers/iperf.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,16 @@ func (i *iperf3) Run(c *kubernetes.Clientset,
6161
id := uuid.New()
6262
file := fmt.Sprintf("/tmp/iperf-%s", id.String())
6363
pod := client.Items[0]
64-
var clientIp string
64+
clientIp := pod.Status.PodIP
65+
6566
if perf.Udn {
66-
clientIp, _ = k8s.ExtractUdnIp(pod)
67-
} else {
68-
clientIp = pod.Status.PodIP
67+
if udnIp, _ := k8s.ExtractUdnIp(pod); udnIp != "" {
68+
clientIp = udnIp
69+
}
70+
} else if perf.BridgeNetwork != "" {
71+
if bridgeClientIp, err := k8s.ExtractBridgeIp(pod, perf.BridgeNetwork, perf.BridgeNamespace); err == nil {
72+
clientIp = bridgeClientIp
73+
}
6974
}
7075
log.Debugf("🔥 Client (%s,%s) starting iperf3 against server: %s", pod.Name, clientIp, serverIP)
7176
config.Show(nc, i.driverName)

pkg/drivers/netperf.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ const omniOptions = "rt_latency,p99_latency,throughput,throughput_units,remote_r
3939
func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) {
4040
var stdout, stderr bytes.Buffer
4141
pod := client.Items[0]
42-
var clientIp string
4342
log.Debugf("Server IP: %s", serverIP)
43+
clientIp := pod.Status.PodIP
44+
4445
if perf.Udn {
45-
clientIp, _ = k8s.ExtractUdnIp(pod)
46-
} else {
47-
clientIp = pod.Status.PodIP
46+
if udnIp, _ := k8s.ExtractUdnIp(pod); udnIp != "" {
47+
clientIp = udnIp
48+
}
49+
} else if perf.BridgeNetwork != "" {
50+
if bridgeClientIp, err := k8s.ExtractBridgeIp(pod, perf.BridgeNetwork, perf.BridgeNamespace); err == nil {
51+
clientIp = bridgeClientIp
52+
}
4853
}
4954
log.Debugf("🔥 Client (%s,%s) starting netperf against server: %s", pod.Name, clientIp, serverIP)
5055
config.Show(nc, n.driverName)

pkg/drivers/uperf.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,16 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c
160160
var exec remotecommand.Executor
161161

162162
pod := client.Items[0]
163-
var clientIp string
163+
clientIp := pod.Status.PodIP
164+
164165
if perf.Udn {
165-
clientIp, _ = k8s.ExtractUdnIp(pod)
166-
} else {
167-
clientIp = pod.Status.PodIP
166+
if udnIp, _ := k8s.ExtractUdnIp(pod); udnIp != "" {
167+
clientIp = udnIp
168+
}
169+
} else if perf.BridgeNetwork != "" {
170+
if bridgeClientIp, err := k8s.ExtractBridgeIp(pod, perf.BridgeNetwork, perf.BridgeNamespace); err == nil {
171+
clientIp = bridgeClientIp
172+
}
168173
}
169174
log.Debugf("🔥 Client (%s,%s) starting uperf against server: %s", pod.Name, clientIp, serverIP)
170175
config.Show(nc, u.driverName)

0 commit comments

Comments
 (0)