WHAT TO EXPECT
Before running the desired application in the cloud, it is a good idea to test with swXtch.io's provided tools/examples.
In this article, users will learn how to test xNIC with K8s. Please complete the installation process outlined in Install xNIC Daemonset on K8s Cluster before testing.
Prerequisites
For this test to work, a user should have at least two nodes, and each node must be in a different pod.
STEP ONE: Create A Consumer
Create a TestConsumer.yaml file using the example below.
Replace the AAA.BBB.CCC.DDD in the section SWXTCH_CONTROL_ADDRESS and the image: value, with the cloudSwXtch control IP address.apiVersion: v1 kind: Pod metadata: name: consumer-a labels: app: consumer-a spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - producer-a - consumer-b topologyKey: kubernetes.io/hostname containers: - name: consumer-a securityContext: privileged: true image: AAA.BBB.CCC.DDD:443/xnicv2:sha-3b0a471 imagePullPolicy: Always env: - name: SWXTCH_CONTROL_ADDRESS value: "AAA.BBB.CCC.DDD" - name: IS_DAEMON value: "false" - name: PERF_TYPE value: "consumer" - name: PERF_NIC value: "eth0" - name: PERF_MCGIP value: "239.0.0.10" - name: PERF_MCGPORT value: "8410" - name: PERF_PPS value: "" - name: AIRGAP value: "true"PLEASE NOTE
If the user needs to use
hostNetwork: true(under spec:) so the Pod sees the actual physical network interfaces of the AWS node, then the line with PERF_NIC must have the correct interface name. For example, on AWS that isens5on most common families.If the YAML file does not have
hostNetwork: true, the standar interface name iseth0.
STEP TWO: Create a Producer
Create a TestProducer.yaml file using the example below.
Replace the AAA.BBB.CCC.DDD in the section SWXTCH_CONTROL_ADDRESS and the image: value, with the cloudSwXtch control IP address.apiVersion: v1 kind: Pod metadata: name: producer-a labels: app: producer-a spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - consumer-a - producer-b topologyKey: kubernetes.io/hostname containers: - name: producer-a securityContext: privileged: true image: AAA.BBB.CCC.DDD:443/xnicv2:sha-3b0a471 imagePullPolicy: Always env: - name: SWXTCH_CONTROL_ADDRESS value: "AAA.BBB.CCC.DDD" - name: IS_DAEMON value: "false" - name: PERF_TYPE value: "producer" - name: PERF_NIC value: "eth0" - name: PERF_MCGIP value: "239.0.0.10" - name: PERF_MCGPORT value: "8410" - name: PERF_PPS value: "100" - name: AIRGAP value: "true"
STEP THREE: Run Test
Deploy the producer pod by running this command in a shell connected to the Kubernetes cluster.
kubectl create -f TestProducer.yamlDeploy the consumer pod by running this command in a shell connected to the Kubernetes cluster.
kubectl create -f TestConsumer.yaml
Validate they are running using this command:
kubectl get pods -o wide -ABelow is an example in Azure showing the consumer-a and producer-a running:
$ kubectl get pods -o wide -A
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default consumer-a 1/1 Running 0 26m 192.168.80.114 ip-192-168-93-187.ec2.internal <none> <none>
default producer-a 1/1 Running 0 25m 192.168.105.153 ip-192-168-100-230.ec2.internal <none> <none>
kube-system aws-node-fgjrq 2/2 Running 0 7h30m 192.168.100.230 ip-192-168-100-230.ec2.internal <none> <none>
kube-system aws-node-sjsb7 2/2 Running 0 7h30m 192.168.93.187 ip-192-168-93-187.ec2.internal <none> <none>
kube-system coredns-6b9575c64c-2kgvd 1/1 Running 0 7h34m 192.168.117.26 ip-192-168-100-230.ec2.internal <none> <none>
kube-system coredns-6b9575c64c-t4f9v 1/1 Running 0 7h34m 192.168.113.184 ip-192-168-100-230.ec2.internal <none> <none>
kube-system kube-proxy-8x2m2 1/1 Running 0 7h30m 192.168.100.230 ip-192-168-100-230.ec2.internal <none> <none>
kube-system kube-proxy-svtpx 1/1 Running 0 7h30m 192.168.93.187 ip-192-168-93-187.ec2.internal <none> <none>
kube-system metrics-server-86dfffd966-74t8s 1/1 Running 0 7h29m 192.168.86.205 ip-192-168-93-187.ec2.internal <none> <none>
kube-system metrics-server-86dfffd966-82xjw 1/1 Running 0 7h29m 192.168.125.9 ip-192-168-100-230.ec2.internal <none> <none>
kube-system swx-xnic-5qfsg 1/1 Running 0 5h5m 192.168.93.187 ip-192-168-93-187.ec2.internal <none> <none>
kube-system swx-xnic-s66zg 1/1 Running 0 5h5m 192.168.100.230 ip-192-168-100-230.ec2.internal <none> <none>Step Four: Validate The Test Is Running
Users can validate it is working by viewing logs with these commands:
Producer
kubectl logs pods/producer-a -fThe console will show something similar to:
$ kubectl logs pods/producer-a -f
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 88391 0 88391 0 0 24.9M 0 --:--:-- --:--:-- --:--:-- 28.0M
===== Downloading swx-tools package =====
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5953k 100 5953k 0 0 518M 0 --:--:-- --:--:-- --:--:-- 528M
===== Starting swx-perf application =====
Selected Mode: Producer
Config:
Sending traffic.
Ip Address: 239.0.0.10 - Port: 8410
Interface IP Address: 192.168.89.216
Running without a total packet counter limit
Running the application without a timing limit
|------------------------------------------------------------------------------------|
| TX TOTALS | TX THIS PERIOD |
|--------------------------------------------|---------------------------------------|
| PKTS | BYTES | MISSING | PPS | BPS | MISSING |
|---------------|------------|---------------|-----------|-----------|---------------|
| 1 | 100 | 0 | 0 | 0 | 0 |
| 102 | 10.19K | 0 | 100 | 80.3K | 0 |
| 202 | 20.19K | 0 | 99 | 79.3K | 0 |
| 303 | 30.29K | 0 | 100 | 80.0K | 0 |
| 404 | 40.39K | 0 | 100 | 80.1K | 0 |
| 504 | 50.39K | 0 | 100 | 79.8K | 0 |
| 605 | 60.50K | 0 | 100 | 80.0K | 0 |
| 705 | 70.50K | 0 | 100 | 79.8K | 0 |
| 806 | 80.59K | 0 | 100 | 80.2K | 0 |
| 906 | 90.59K | 0 | 99 | 79.2K | 0 |
| 1,006 | 100K | 0 | 100 | 79.9K | 0 |
| 1,106 | 110K | 0 | 100 | 79.8K | 0 |
| 1,207 | 120K | 0 | 100 | 80.0K | 0 |
| 1,308 | 130K | 0 | 100 | 80.1K | 0 |
| 1,408 | 140K | 0 | 99 | 79.4K | 0 |
| 1,509 | 150K | 0 | 100 | 80.0K | 0 |
|------------------------------------------------------------------------------------|That shows the producer sending the multicast stream correctly.
Consumer
Then, for the consumer:
kubectl logs pods/consumer-a -fIt will show something similar to:
$ kubectl logs pods/consumer-a -f
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 88391 0 88391 0 0 24.6M 0 --:--:-- --:--:-- --:--:-- 28.0M
===== Downloading swx-tools package =====
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5953k 100 5953k 0 0 445M 0 --:--:-- --:--:-- --:--:-- 447M
===== Starting swx-perf application =====
Selected Mode: Consumer
Config:
Waiting traffic
Ip Address: 239.0.0.10 - Port: 8410
Interface IP Address: 192.168.122.121
Running without a total packet counter limit
Running the application without a timing limit
|-------------------------------------------------------------------------------------------------------|
| RX TOTALS | RX THIS PERIOD |
|-----------------------------------------------|-------------------------------------------------------|
| PKTS | OOO | MISSING | OOO | MISSING | PPS | BPS |
|---------------|---------------|---------------|---------------|---------------|-----------|-----------|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 74 | 0 | 0 | 0 | 0 | 74 | 58.8K |
| 175 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 275 | 0 | 0 | 0 | 0 | 99 | 79.5K |
| 376 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 477 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 577 | 0 | 0 | 0 | 0 | 99 | 79.5K |
| 678 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 778 | 0 | 0 | 0 | 0 | 99 | 79.4K |
| 879 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 979 | 0 | 0 | 0 | 0 | 99 | 79.4K |
| 1,080 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 1,180 | 0 | 0 | 0 | 0 | 99 | 79.4K |
| 1,281 | 0 | 0 | 0 | 0 | 100 | 80.2K |
| 1,381 | 0 | 0 | 0 | 0 | 100 | 79.8K |
|-------------------------------------------------------------------------------------------------------|That shows the consumer receiving the multicast stream.
Using the UI
Alternatively, users can see the UI of the cloudSwXtch like swx-top or . For example, looking at the terminal UI executing:
swx-topswx-top should show the traffic of the producer (TX) and the consumer (RX).
┌─────────────────────────────────────────────────────────────────────────────── Information - dev [ + ] ──────────────────────────────────────────────────────────────────────────────┐
│ip-172-31-25-167 | Status OK NEW NOTIFICATIONS │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
╔═══════════════════════════════════════════════════════════════════════════════════ Components (4) ═══════════════════════════════════════════════════════════════════════════════════╗
║Filter Class X ║
║--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------║
║[+] Name Class Type Rx (bps) Rx (pps) Tx (bps) Tx (pps) Primary IP OS Version Primary Swxtches ║
║ ip-172-31-25-167 swXtch X1 153.3K 100 153.3K 100 172.31.25.167 Ubuntu 24.04 v4.1.0 -- ║
║ ip-192-168-93-187.ec2.internal xNIC 2 153.3K 100 0 0 192.168.93.187 Ubuntu 24.04 v4.1.0 ip-172-31-25-167 ║
║ ip-192-168-100-230.ec2.internal xNIC 2 0 0 153.4K 100 192.168.100.230 Ubuntu 24.04 v4.1.0 ip-172-31-25-167 ║
║ 192.168.105.153 VM -- 0 0 152.1K 99 192.168.105.153 -- -- -- ║
║ ║
║ ║
║ ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
┌──────────────────────────────────────────────────────────────────────────── Interfaces ip-172-31-25-167 ────────────────────────────────────────────────────────────────────────────┐
│[+] Name Index Ip SubnetPrefix Public Ip MTU Driver PciAddress │
│ dpdk-0 0 172.31.31.37 172.31.16.0/20 -- -- igb_uio 0000:00:06.0 │
│ ens5 2 172.31.25.167 172.31.16.0/20 -- 9001 ena 0000:00:05.0 │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Views │ Adaptors Notifications Components Streams │ Colors HelpStep Five: Cleaning the Pods
Stop the test consumer by running this command in the CloudShell window:
Run:
kubectl delete -f TestConsumer.yamlswx-top should no longer show the consumer. Additionally, running kubectl get pods -o wide should now show just the test consumer, as shown below (the consumer is being terminated):
$ kubectl get pods -o wide -A NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES consumer-a 1/1 Terminating 0 15m 10.0.1.91 aks-nodepool1-23351669-vmss000006 <none> <none> producer-a 1/1 Running 0 15m 10.0.1.90 aks-nodepool1-23351669-vmss000005 <none> <none> swxtch-xnic-46qgg 1/1 Running 0 39m 10.2.128.96 aks-nodepool1-23351669-vmss000005 <none> <none> swxtch-xnic-szdk7 1/1 Running 0 40m 10.2.128.95 aks-nodepool1-23351669-vmss000004 <none> <none>
Stop the test producer by running this command in the CloudShell window.
Run:
kubectl delete -f TestProducer.yamlswx-top should no longer show the producer. This may take a minute to display. Additionally, running kubectl get pods -o wide should now show just the test producer as shown below:
donna@Azure:~$ kubectl get pods -o wide -A NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES producer-a 1/1 Terminating 0 15m 10.0.1.90 aks-nodepool1-23351669-vmss000005 <none> <none> swxtch-xnic-46qgg 1/1 Running 0 42m 10.2.128.96 aks-nodepool1-23351669-vmss000005 <none> <none> swxtch-xnic-szdk7 1/1 Running 0 42m 10.2.128.95 aks-nodepool1-23351669-vmss000004 <none> <none>
Now that the system is validated using swXtch.io tools, the user can test with his K8s application.