Skip to content

Commit 635afda

Browse files
committed
initial
0 parents  commit 635afda

File tree

10 files changed

+1227
-0
lines changed

10 files changed

+1227
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
k8s-iperf

Dockerfile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Build stage
2+
FROM alpine:3.18 AS builder
3+
4+
# Update and upgrade all packages, including openssl
5+
RUN apk update && apk upgrade
6+
7+
# Install iperf3 and create a non-root user
8+
RUN apk add --no-cache iperf3 && \
9+
adduser -D -H -u 10000 -s /sbin/nologin iperf
10+
11+
# Final stage
12+
FROM alpine:3.18
13+
14+
# Update and upgrade all packages, including openssl
15+
RUN apk update && apk upgrade
16+
17+
# Install iperf3 and necessary runtime dependencies
18+
RUN apk add --no-cache iperf3 libgcc libstdc++
19+
20+
# Copy user information
21+
COPY --from=builder /etc/passwd /etc/passwd
22+
COPY --from=builder /etc/group /etc/group
23+
24+
# Set working directory
25+
WORKDIR /tmp
26+
27+
# Drop privileges
28+
USER iperf
29+
30+
# Set the entrypoint to the iperf3 binary
31+
ENTRYPOINT ["/usr/bin/iperf3"]
32+
33+
# Default command (can be overridden)
34+
CMD ["-s"]

Makefile

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Variables
2+
BINARY_NAME := k8s-iperf
3+
DOCKER_IMAGE := dariomader/iperf3
4+
DOCKER_TAG := latest
5+
6+
# Go build flags
7+
GO_BUILD_FLAGS := -ldflags="-s -w"
8+
9+
.PHONY: all build docker clean
10+
11+
all: build docker push
12+
13+
build:
14+
@echo "Building Go binary..."
15+
go build $(GO_BUILD_FLAGS) -o $(BINARY_NAME) ./cmd/main.go
16+
17+
docker: build
18+
@echo "Building multi-platform Docker image..."
19+
docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
20+
21+
clean:
22+
@echo "Cleaning up..."
23+
rm -f $(BINARY_NAME)
24+
docker rmi $(DOCKER_IMAGE):$(DOCKER_TAG)
25+
26+
push: docker
27+
@echo "Pushing multi-platform Docker image..."
28+
docker buildx build --platform linux/amd64,linux/arm64 -t $(DOCKER_IMAGE):$(DOCKER_TAG) --push .

Readme.md

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# k8s-iperf
2+
3+
k8s-iperf is a tool to test the network performance between two nodes in a Kubernetes cluster using iperf3.
4+
5+
## Installation
6+
7+
To use k8s-iperf, you need to have access to a Kubernetes cluster and the `kubectl` command-line tool configured.
8+
9+
## Usage
10+
11+
The basic command to run an iperf test is:
12+
13+
```
14+
k8s-iperf run
15+
```
16+
17+
### Flags
18+
19+
- `--k8s-namespace` Specify the Kubernetes namespace to run the test in (default: "default")
20+
- `--k8s-image` Specify the Docker image to use for the test (default: "dariomader/iperf3:latest")
21+
- `--k8s-server-node` Specify the Kubernetes node to run the iperf3 server on
22+
- `--k8s-client-node` Specify the Kubernetes node to run the iperf3 client on
23+
24+
### Iperf Arguments
25+
26+
You can pass additional iperf3 arguments after the `--` separator. These will be forwarded to the iperf3 client.
27+
28+
### Examples
29+
30+
1. Run a basic iperf test in the default namespace:
31+
```
32+
k8s-iperf run
33+
```
34+
35+
2. Run a test in a specific namespace:
36+
```
37+
k8s-iperf run --k8s-namespace mynetwork
38+
```
39+
40+
3. Use a custom iperf3 image:
41+
```
42+
k8s-iperf run --k8s-image myrepo/custom-iperf3:v1
43+
```
44+
45+
4. Run a test between specific nodes:
46+
```
47+
k8s-iperf run --k8s-server-node node1 --k8s-client-node node2
48+
```
49+
50+
5. Pass additional iperf3 arguments:
51+
```
52+
k8s-iperf run -- -t 30 -P 4
53+
```
54+
This runs a 30-second test with 4 parallel streams.
55+
56+
6. Combine flags and iperf3 arguments:
57+
```
58+
k8s-iperf run --k8s-namespace mynetwork --k8s-server-node node1 --k8s-client-node node2 -- -t 60 -R
59+
```
60+
This runs a 60-second test in reverse mode in the "mynetwork" namespace between node1 and node2.
61+
62+
## Docker Image
63+
64+
The default iperf3 image is hosted on Docker Hub:
65+
66+
```
67+
docker pull dariomader/iperf3:latest
68+
```
69+
70+
You can also build the image yourself using the Dockerfile in this repository.

cmd/main.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/darox/k8s-iperf/pkg/cli"
8+
)
9+
10+
func main() {
11+
if err := cli.Execute(); err != nil {
12+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
13+
os.Exit(1)
14+
}
15+
}

go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/darox/k8s-iperf
2+
3+
go 1.16
4+
5+
require (
6+
github.com/spf13/cobra v1.2.1
7+
k8s.io/api v0.22.1
8+
k8s.io/apimachinery v0.22.1
9+
k8s.io/client-go v0.22.1
10+
)

go.sum

+696
Large diffs are not rendered by default.

pkg/cli/commands.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/darox/k8s-iperf/pkg/k8s"
7+
8+
"github.com/darox/k8s-iperf/pkg/iperf"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var rootCmd = &cobra.Command{
14+
Use: "k8s-iperf",
15+
Short: "Run iperf tests on Kubernetes clusters",
16+
}
17+
18+
var runCmd = &cobra.Command{
19+
Use: "run [flags] -- [iperf args]",
20+
Short: "Run an iperf test",
21+
RunE: func(cmd *cobra.Command, args []string) error {
22+
namespace, _ := cmd.Flags().GetString("k8s-namespace")
23+
image, _ := cmd.Flags().GetString("k8s-image")
24+
serverNode, _ := cmd.Flags().GetString("k8s-server-node")
25+
clientNode, _ := cmd.Flags().GetString("k8s-client-node")
26+
client, err := k8s.NewClient()
27+
if err != nil {
28+
return fmt.Errorf("failed to create Kubernetes client: %w", err)
29+
}
30+
31+
// Extract iperf args
32+
iperfArgs := []string{}
33+
if cmd.ArgsLenAtDash() != -1 {
34+
iperfArgs = args[cmd.ArgsLenAtDash():]
35+
}
36+
37+
config := iperf.TestConfig{
38+
Client: client,
39+
Namespace: namespace,
40+
Image: image,
41+
IperfArgs: iperfArgs,
42+
ServerNode: serverNode,
43+
ClientNode: clientNode,
44+
}
45+
46+
return iperf.RunTest(config)
47+
},
48+
}
49+
50+
func init() {
51+
runCmd.Flags().StringP("k8s-namespace", "", "default", "Kubernetes namespace to run the test in")
52+
runCmd.Flags().StringP("k8s-image", "", "dariomader/iperf3:latest", "Docker image to use for the test")
53+
runCmd.Flags().StringP("k8s-server-node", "", "", "Server node to use for the test")
54+
runCmd.Flags().StringP("k8s-client-node", "", "", "Client node to use for the test")
55+
rootCmd.AddCommand(runCmd)
56+
}
57+
58+
func Execute() error {
59+
return rootCmd.Execute()
60+
}

0 commit comments

Comments
 (0)