Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
darox committed Sep 6, 2024
0 parents commit 635afda
Show file tree
Hide file tree
Showing 10 changed files with 1,227 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
k8s-iperf
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Build stage
FROM alpine:3.18 AS builder

# Update and upgrade all packages, including openssl
RUN apk update && apk upgrade

# Install iperf3 and create a non-root user
RUN apk add --no-cache iperf3 && \
adduser -D -H -u 10000 -s /sbin/nologin iperf

# Final stage
FROM alpine:3.18

# Update and upgrade all packages, including openssl
RUN apk update && apk upgrade

# Install iperf3 and necessary runtime dependencies
RUN apk add --no-cache iperf3 libgcc libstdc++

# Copy user information
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group

# Set working directory
WORKDIR /tmp

# Drop privileges
USER iperf

# Set the entrypoint to the iperf3 binary
ENTRYPOINT ["/usr/bin/iperf3"]

# Default command (can be overridden)
CMD ["-s"]
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Variables
BINARY_NAME := k8s-iperf
DOCKER_IMAGE := dariomader/iperf3
DOCKER_TAG := latest

# Go build flags
GO_BUILD_FLAGS := -ldflags="-s -w"

.PHONY: all build docker clean

all: build docker push

build:
@echo "Building Go binary..."
go build $(GO_BUILD_FLAGS) -o $(BINARY_NAME) ./cmd/main.go

docker: build
@echo "Building multi-platform Docker image..."
docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) .

clean:
@echo "Cleaning up..."
rm -f $(BINARY_NAME)
docker rmi $(DOCKER_IMAGE):$(DOCKER_TAG)

push: docker
@echo "Pushing multi-platform Docker image..."
docker buildx build --platform linux/amd64,linux/arm64 -t $(DOCKER_IMAGE):$(DOCKER_TAG) --push .
70 changes: 70 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# k8s-iperf

k8s-iperf is a tool to test the network performance between two nodes in a Kubernetes cluster using iperf3.

## Installation

To use k8s-iperf, you need to have access to a Kubernetes cluster and the `kubectl` command-line tool configured.

## Usage

The basic command to run an iperf test is:

```
k8s-iperf run
```

### Flags

- `--k8s-namespace` Specify the Kubernetes namespace to run the test in (default: "default")
- `--k8s-image` Specify the Docker image to use for the test (default: "dariomader/iperf3:latest")
- `--k8s-server-node` Specify the Kubernetes node to run the iperf3 server on
- `--k8s-client-node` Specify the Kubernetes node to run the iperf3 client on

### Iperf Arguments

You can pass additional iperf3 arguments after the `--` separator. These will be forwarded to the iperf3 client.

### Examples

1. Run a basic iperf test in the default namespace:
```
k8s-iperf run
```

2. Run a test in a specific namespace:
```
k8s-iperf run --k8s-namespace mynetwork
```

3. Use a custom iperf3 image:
```
k8s-iperf run --k8s-image myrepo/custom-iperf3:v1
```

4. Run a test between specific nodes:
```
k8s-iperf run --k8s-server-node node1 --k8s-client-node node2
```

5. Pass additional iperf3 arguments:
```
k8s-iperf run -- -t 30 -P 4
```
This runs a 30-second test with 4 parallel streams.

6. Combine flags and iperf3 arguments:
```
k8s-iperf run --k8s-namespace mynetwork --k8s-server-node node1 --k8s-client-node node2 -- -t 60 -R
```
This runs a 60-second test in reverse mode in the "mynetwork" namespace between node1 and node2.

## Docker Image

The default iperf3 image is hosted on Docker Hub:

```
docker pull dariomader/iperf3:latest
```

You can also build the image yourself using the Dockerfile in this repository.
15 changes: 15 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"os"

"github.com/darox/k8s-iperf/pkg/cli"
)

func main() {
if err := cli.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/darox/k8s-iperf

go 1.16

require (
github.com/spf13/cobra v1.2.1
k8s.io/api v0.22.1
k8s.io/apimachinery v0.22.1
k8s.io/client-go v0.22.1
)
696 changes: 696 additions & 0 deletions go.sum

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions pkg/cli/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cli

import (
"fmt"

"github.com/darox/k8s-iperf/pkg/k8s"

"github.com/darox/k8s-iperf/pkg/iperf"

"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "k8s-iperf",
Short: "Run iperf tests on Kubernetes clusters",
}

var runCmd = &cobra.Command{
Use: "run [flags] -- [iperf args]",
Short: "Run an iperf test",
RunE: func(cmd *cobra.Command, args []string) error {
namespace, _ := cmd.Flags().GetString("k8s-namespace")
image, _ := cmd.Flags().GetString("k8s-image")
serverNode, _ := cmd.Flags().GetString("k8s-server-node")
clientNode, _ := cmd.Flags().GetString("k8s-client-node")
client, err := k8s.NewClient()
if err != nil {
return fmt.Errorf("failed to create Kubernetes client: %w", err)
}

// Extract iperf args
iperfArgs := []string{}
if cmd.ArgsLenAtDash() != -1 {
iperfArgs = args[cmd.ArgsLenAtDash():]
}

config := iperf.TestConfig{
Client: client,
Namespace: namespace,
Image: image,
IperfArgs: iperfArgs,
ServerNode: serverNode,
ClientNode: clientNode,
}

return iperf.RunTest(config)
},
}

func init() {
runCmd.Flags().StringP("k8s-namespace", "", "default", "Kubernetes namespace to run the test in")
runCmd.Flags().StringP("k8s-image", "", "dariomader/iperf3:latest", "Docker image to use for the test")
runCmd.Flags().StringP("k8s-server-node", "", "", "Server node to use for the test")
runCmd.Flags().StringP("k8s-client-node", "", "", "Client node to use for the test")
rootCmd.AddCommand(runCmd)
}

func Execute() error {
return rootCmd.Execute()
}
Loading

0 comments on commit 635afda

Please sign in to comment.