diff --git a/ambient-tests/.gitignore b/ambient-tests/.gitignore new file mode 100644 index 0000000000..b5305e6ecc --- /dev/null +++ b/ambient-tests/.gitignore @@ -0,0 +1,8 @@ +data +graphs +results +secrets +.venv +*.pcap +dumps +__pycache__ diff --git a/ambient-tests/Makefile b/ambient-tests/Makefile new file mode 100644 index 0000000000..ec911f3dcc --- /dev/null +++ b/ambient-tests/Makefile @@ -0,0 +1,15 @@ +.PHONY: docker-build run-netperf + +run-netperf: + ./scripts/netperf/run.sh + ./scripts/netperf/gen-csv.sh + python ./scripts/netperf/graphs.py + +run-fortio: + ./scripts/fortio/run.sh + ./scripts/fortio/gen-csv.sh + python ./scripts/fortio/graphs.py + +docker-build: + make build push -C netperf + diff --git a/ambient-tests/README.md b/ambient-tests/README.md new file mode 100644 index 0000000000..c53ff99459 --- /dev/null +++ b/ambient-tests/README.md @@ -0,0 +1,53 @@ +# Performance Tests for Ztunnel + +Performance tests for Istio Ambient, Istio Ambient + Waypoint, Istio Sidecar. +Uses [netperf](https://github.com/HewlettPackard/netperf) and [fortio](https://github.com/fortio/fortio). + +## Setup + +To run, first set up a cluster with two user nodes: one with the `role=server` label and one with the `role=client` label. +You can recreate this in a kind cluster using `yaml/cluster.yaml`. +If you use a kind cluster, will either have to connect it to a local registry, or upload the images using `make push-local` in the `docker` directory. +You will also have to modify the `imagePullPolicy` fields of the pods in `yaml/deploy.yaml` to `Never`. + +Note that if you are using AKS to set up your cluster, make sure that you use Azure CNI as your network plugin and **DO NOT** use a network policy. +Also, make sure to attach to container registry to your cluster/that your container registry is accessible from your cluster. +This ensures that client and server pods get deployed in different servers. + +Next, go into `docker/Makefile` and change the value of `CR` to your container registry and the image names in `yaml/deploy.yaml` accordingly. + +You will also need a Python 3 with `matplotlib`, `pandas`, and `python-dotenv`. +Also, make sure that `python -V` is some version of Python 3. +An easy way to get this on Ubuntu is running + +```bash +sudo apt install python-is-python3 +sudo apt install python3-pip +pip install matplotlib pandas python-dotenv +``` + +Install Istio Ambient. +I don't automate this process because there are many installation methods and you might be testing a custom build. +To install the latest release of Istio Ambient [install `istioctl`](https://istio.io/latest/docs/setup/getting-started/#download) and run + +```bash +istioctl install --set profile=ambient +``` + +## Building + +To build the necessary containers, inside `docker/`, run + +```bash +make build +make push-cr +# or `push-local` if running in a kind cluster. +``` + +## Running Benchmarks + +Now, update `scripts/config.sh` as desired or keep the default values, and run `./scripts/setup.sh` from the root of the repository to deploy the pods. +Once the deployments are complete, run the tests with `make run-netperf run-fortio`. +This will create graphs in the `graphs/` directory and put intermediate files in `results/` by default. + +For more configuration options, see `scripts/run.sh`. diff --git a/ambient-tests/docker/.dockerignore b/ambient-tests/docker/.dockerignore new file mode 100644 index 0000000000..94143827ed --- /dev/null +++ b/ambient-tests/docker/.dockerignore @@ -0,0 +1 @@ +Dockerfile diff --git a/ambient-tests/docker/Dockerfile b/ambient-tests/docker/Dockerfile new file mode 100644 index 0000000000..f0fd6c0faf --- /dev/null +++ b/ambient-tests/docker/Dockerfile @@ -0,0 +1,37 @@ +# This is the only version that is available +# hadolint ignore=DL3007 +FROM networkstatic/netserver:latest +RUN apt-get update -y && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + netcat \ + net-tools \ + tcpdump \ + netperf \ + less \ + ncat \ + termshark \ + python3 \ + curl \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -OL https://github.com/fortio/fortio/releases/download/v1.17.0/fortio_1.17.0_amd64.deb \ + && dpkg -i fortio_1.17.0_amd64.deb + +# tcp echo port +EXPOSE 6789 +# data port for netperf +EXPOSE 35000 +# config port netperf +EXPOSE 12865 +# python http server +EXPOSE 8000 +# fortio server +EXPOSE 8080 +EXPOSE 8078 +EXPOSE 8079 + +WORKDIR "/ambient-performance" + +COPY . . +ENTRYPOINT ["./server-and-sleep.sh"] diff --git a/ambient-tests/docker/Makefile b/ambient-tests/docker/Makefile new file mode 100644 index 0000000000..353ef6de04 --- /dev/null +++ b/ambient-tests/docker/Makefile @@ -0,0 +1,21 @@ +CR=stjinxuan.azurecr.io +NAME=ambient-performance +CR_NAME=$(CR)/$(NAME) + +.PHONY: build push run push-cr push-local + +default: build + +build: + docker build . -t $(CR_NAME) -t $(NAME) + +push-cr: + docker push $(CR_NAME) + +push-local: + kind load docker-image $(CR_NAME) + +push: push-cr + +run: + docker run --rm --name $(NAME) $(NAME) -P diff --git a/ambient-tests/docker/README.md b/ambient-tests/docker/README.md new file mode 100644 index 0000000000..4049c9dcfe --- /dev/null +++ b/ambient-tests/docker/README.md @@ -0,0 +1,4 @@ +# Netperf + +Lightweight Docker image running netperf and an echo server. +Also includes various network debugging utilities. diff --git a/ambient-tests/docker/server-and-sleep.sh b/ambient-tests/docker/server-and-sleep.sh new file mode 100755 index 0000000000..5146429347 --- /dev/null +++ b/ambient-tests/docker/server-and-sleep.sh @@ -0,0 +1,23 @@ +#! /bin/bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eux +netserver "$@" +ncat -e /bin/cat -k -l 6789 & +python ./tcp_ping/server.py & +fortio server & +python3 -m http.server & +sleep 365d diff --git a/ambient-tests/requirements.txt b/ambient-tests/requirements.txt new file mode 100644 index 0000000000..c0db47539a --- /dev/null +++ b/ambient-tests/requirements.txt @@ -0,0 +1,3 @@ +matplotlib +pandas +python-dotenv diff --git a/ambient-tests/scripts/config.sh b/ambient-tests/scripts/config.sh new file mode 100644 index 0000000000..ab09f306a6 --- /dev/null +++ b/ambient-tests/scripts/config.sh @@ -0,0 +1,72 @@ +# shellcheck shell=bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# server-client config +export YAML_PATH=./yaml/deploy.yaml + +# name of the deployments +export BENCHMARK_SERVER=server +export BENCHMARK_CLIENT=client + +# where to store primary and intermediate results +export NETPERF_RESULTS=results/netperf +export FORTIO_RESULTS=results/fortio + +# name of the namespaces for each mesh setup +export NS_NO_MESH=no-mesh +export NS_SIDECAR=sidecar +export NS_AMBIENT=ambient +export NS_WAYPOINT=waypoint # ambient w/ waypoint proxy +# name of service account for server. Used for waypoint configuration. +# This is also hardcoded in deployment configuration +export SA_SERVER=server-sa + +# Separator for tests runs. Doesn't really matter. Just set to something weird +export TEST_RUN_SEPARATOR="~~~~~~~~~~~~~~~~" +# How many runs of each test +export N_RUNS=2 + +# Extra arguments for TCP_RR and TCP_CRR tests. +# These are necessary because by default *RR tests send only one byte. +# However, Envoy proxies won't create a connection until more bytes are sent. +# This also means that reverse tests _DO NOT WORK_. +export NETPERF_RR_ARGS="-r 100" + +# -P Have the data connection listen on port 35000 on the server. +# -k Output all fields in key=value from. +# We will pick and choose later. +export NETPERF_TEST_ARGS="-P ,35000 -k all" + +# -P toggles the tests banner. +# This is very confusing because it has nothing to do with ports. +# -j to measure latency +export NETPERF_GLOBAL_ARGS="-P 0 -j" + +# Args for serial tests +# -qps As many queries per second as possible +# -c Number of sending threads +# -payload-file POST request with Makefile as data. +# +# This configuration seems to trigger the Nagle's + delayed ack interaction. +export FORTIO_SERIAL_HTTP_ARGS="-qps -1 -c 1 -payload-size 300" + +# Arguments for prallel http tests +# 3 sending threads should be enough(?) +export FORTIO_PARALLEL_HTTP_ARGS="-qps -1 -c 3" + +# where to output the graphs +export NETPERF_GRAPHS="graphs/netperf" +export FORTIO_GRAPHS="graphs/fortio" diff --git a/ambient-tests/scripts/fortio/gen-csv.sh b/ambient-tests/scripts/fortio/gen-csv.sh new file mode 100755 index 0000000000..fba3b051d4 --- /dev/null +++ b/ambient-tests/scripts/fortio/gen-csv.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eux + +# shellcheck disable=SC1091 +source scripts/config.sh + +# TODO: names? +python scripts/fortio/results_to_csv.py < "$FORTIO_RESULTS/serial" > "$FORTIO_RESULTS/serial.csv" +python scripts/fortio/results_to_csv.py < "$FORTIO_RESULTS/parallel" > "$FORTIO_RESULTS/parallel.csv" + diff --git a/ambient-tests/scripts/fortio/graphs.py b/ambient-tests/scripts/fortio/graphs.py new file mode 100644 index 0000000000..75253a695c --- /dev/null +++ b/ambient-tests/scripts/fortio/graphs.py @@ -0,0 +1,39 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from scripts.lib import latency_graph +import os +import sys + +import dotenv +import matplotlib.pyplot as plt +import pandas as pd + +sys.path.append(".") # kinda hacky, but easy + + +# load data +# TCP_STREAM figure +dotenv.load_dotenv("./scripts/config.sh") +FORTIO_RESULTS = os.environ["FORTIO_RESULTS"] +FORTIO_GRAPHS = os.environ["FORTIO_GRAPHS"] + + +if __name__ == "__main__": + os.makedirs(FORTIO_GRAPHS, exist_ok=True) + serial = latency_graph(f"{FORTIO_RESULTS}/serial.csv", "HTTP Echo (serial)") + serial.savefig(f"{FORTIO_GRAPHS}/serial.png") + + serial = latency_graph(f"{FORTIO_RESULTS}/parallel.csv", "HTTP Echo (parallel)") + serial.savefig(f"{FORTIO_GRAPHS}/parallel.png") diff --git a/ambient-tests/scripts/fortio/results_to_csv.py b/ambient-tests/scripts/fortio/results_to_csv.py new file mode 100644 index 0000000000..fd5473775d --- /dev/null +++ b/ambient-tests/scripts/fortio/results_to_csv.py @@ -0,0 +1,70 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import csv +import dotenv +import os +import json +import sys + +dotenv.load_dotenv("./scripts/config.sh") + +TEST_RUN_SEPARATOR = os.environ["TEST_RUN_SEPARATOR"] + +# Format is +# : +# +# TEST_RUN_SEPARATOR + +raw = sys.stdin.read() +raw = raw.replace("\r", "").strip() +runs = raw.split(TEST_RUN_SEPARATOR) +if not runs[-1]: + runs = runs[:-1] + +writer = csv.DictWriter( + sys.stdout, + fieldnames=[ + "NAMESPACES", + "THROUGHPUT", + "THROUGHPUT_UNITS", + "P50_LATENCY", + "P90_LATENCY", + "P99_LATENCY", + "SOCKET_COUNT", + ], + extrasaction="ignore", +) + +writer.writeheader() + +for run in runs: + row = dict() + run = run.strip() + run = run.split("\n") + + # Hardcode field mappings + row["NAMESPACES"] = run[0] + run = "".join(run[1:]) + run = json.loads(run) + row["THROUGHPUT"] = run["ActualQPS"] + row["THROUGHPUT_UNITS"] = "Trans/s" + for p in run["DurationHistogram"]["Percentiles"]: + # cursed fstring + row[f"P{p['Percentile']}_LATENCY"] = ( + p["Value"] * 10**6 + ) # seconds to microseconds + row["SOCKET_COUNT"] = run["SocketCount"] + + writer.writerow(row) diff --git a/ambient-tests/scripts/fortio/run.sh b/ambient-tests/scripts/fortio/run.sh new file mode 100755 index 0000000000..ba3802c9e7 --- /dev/null +++ b/ambient-tests/scripts/fortio/run.sh @@ -0,0 +1,58 @@ +#! /bin/bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Run netperf performance benchmarks + +set -eux + +# shellcheck disable=SC1091 +source scripts/config.sh + +mkdir -p "$FORTIO_RESULTS" + +function run-tests() { + client_ns=$1 + server_ns=$2 + + for _ in $(seq "$N_RUNS") + do + # shellcheck disable=SC2086 + kubectl exec -it -n "$client_ns" deploy/client \ + -- fortio load $FORTIO_SERIAL_HTTP_ARGS -json serial.json "http://$BENCHMARK_SERVER.$server_ns:8080" \ + > /dev/null + echo "$client_ns:$server_ns" + kubectl exec -it -n "$client_ns" deploy/client -- cat serial.json + echo "$TEST_RUN_SEPARATOR" + done >> "$FORTIO_RESULTS/serial" + + for _ in $(seq "$N_RUNS") + do + # shellcheck disable=SC2086 + kubectl exec -it -n "$client_ns" deploy/client \ + -- fortio load $FORTIO_PARALLEL_HTTP_ARGS -json parallel.json "http://$BENCHMARK_SERVER.$server_ns:8080" \ + > /dev/null + echo "$client_ns:$server_ns" + kubectl exec -it -n "$client_ns" deploy/client -- cat parallel.json + echo "$TEST_RUN_SEPARATOR" + done >> "$FORTIO_RESULTS/parallel" +} + +true > "$FORTIO_RESULTS/serial" +true > "$FORTIO_RESULTS/parallel" +run-tests "$NS_AMBIENT" "$NS_AMBIENT" +run-tests "$NS_SIDECAR" "$NS_SIDECAR" +run-tests "$NS_NO_MESH" "$NS_NO_MESH" +run-tests "$NS_WAYPOINT" "$NS_WAYPOINT" diff --git a/ambient-tests/scripts/lib.py b/ambient-tests/scripts/lib.py new file mode 100644 index 0000000000..bcf953fd95 --- /dev/null +++ b/ambient-tests/scripts/lib.py @@ -0,0 +1,50 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pandas as pd +import matplotlib.pyplot as plt + + +def latency_graph(source_csv: str, title: str): + stream_df = pd.read_csv( + source_csv, + usecols=[ + "P90_LATENCY", + "P99_LATENCY", + "P50_LATENCY", + "NAMESPACES", + ], + ) + gb = stream_df.groupby("NAMESPACES") + groups = sorted(gb.groups.keys()) # list for consistent ordering + fig: plt.Figure + ax: plt.Axes + fig, ax = plt.subplots() + + height50 = [gb["P50_LATENCY"].median()[g] for g in groups] + height90 = [gb["P90_LATENCY"].median()[g] for g in groups] + height99 = [gb["P99_LATENCY"].median()[g] for g in groups] + x = list(range(len(groups))) + + ax.bar(x=x, height=height99, label="P99") + ax.bar(x=x, height=height90, label="P90") + ax.bar(x=x, height=height50, label="P50") + + ax.set_title(title) + ax.set_xlabel("src:dst") + ax.set_ylabel("Transaction speed (usec/transaction)") + ax.legend() + ax.set_xticks(x, groups, rotation=11) + + return fig diff --git a/ambient-tests/scripts/netperf/gen-csv.sh b/ambient-tests/scripts/netperf/gen-csv.sh new file mode 100755 index 0000000000..9b8db9f002 --- /dev/null +++ b/ambient-tests/scripts/netperf/gen-csv.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Create csv from key-value pairs. + +set -eu +shopt -s extglob +# shellcheck disable=SC1091 +source scripts/config.sh + +# non csv files +for file in $NETPERF_RESULTS/{TCP_STREAM,TCP_CRR,TCP_RR} +do + echo "$file" + base=$(basename "$file") + python ./scripts/netperf/results_to_csv.py \ + "$TEST_RUN_SEPARATOR" \ + < "$file" \ + > "$NETPERF_RESULTS/$base.csv" +done diff --git a/ambient-tests/scripts/netperf/graphs.py b/ambient-tests/scripts/netperf/graphs.py new file mode 100644 index 0000000000..5dda41e7a0 --- /dev/null +++ b/ambient-tests/scripts/netperf/graphs.py @@ -0,0 +1,74 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from scripts.lib import latency_graph +import os +import sys + +import dotenv +import matplotlib.pyplot as plt +import pandas as pd + +sys.path.append(".") # kinda hacky, but easy + + +# load data +# TCP_STREAM figure +dotenv.load_dotenv("./scripts/config.sh") +NETPERF_RESULTS = os.environ["NETPERF_RESULTS"] +NETPERF_GRAPHS = os.environ["NETPERF_GRAPHS"] + + +def tcp_stream_graph(): + stream_df = pd.read_csv( + f"./{NETPERF_RESULTS}/TCP_STREAM.csv", usecols=["THROUGHPUT", "NAMESPACES"] + ) + gb = stream_df.groupby("NAMESPACES") + groups = sorted(list(gb.groups.keys())) # list for consistent ordering + fig: plt.Figure + ax: plt.Axes + fig, ax = plt.subplots() + + height = [gb["THROUGHPUT"].mean()[g] for g in groups] + yerr = [gb["THROUGHPUT"].std()[g] * 2 for g in groups] + x = list(range(len(groups))) + + ax.errorbar(x=x, y=height, yerr=yerr, fmt="|", color="r", label=r"2 $\cdot$ stddev") + ax.bar(x=x, height=height) + + ax.set_ylabel("Mean throughput ($10^6$ bits/second)") + ax.set_title("TCP THROUGHPUT") + ax.set_xticks(x, groups, rotation=11) + ax.legend() + + fig.savefig(f"./{NETPERF_GRAPHS}/TCP_STREAM.png") + + +def tcp_rr_graph(): + fig = latency_graph(f"./{NETPERF_RESULTS}/TCP_RR.csv", "TCP REQUEST RESPONSE") + fig.savefig(f"./{NETPERF_GRAPHS}/TCP_RR.png") + + +def tcp_crr_graph(): + fig = latency_graph( + f"./{NETPERF_RESULTS}/TCP_RR.csv", "TCP CONNECT REQUEST RESPONSE" + ) + fig.savefig(f"./{NETPERF_GRAPHS}/TCP_CRR.png") + + +if __name__ == "__main__": + os.makedirs(NETPERF_GRAPHS, exist_ok=True) + tcp_stream_graph() + tcp_rr_graph() + tcp_crr_graph() diff --git a/ambient-tests/scripts/netperf/results_to_csv.py b/ambient-tests/scripts/netperf/results_to_csv.py new file mode 100644 index 0000000000..0fd15baa7a --- /dev/null +++ b/ambient-tests/scripts/netperf/results_to_csv.py @@ -0,0 +1,43 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import csv +from typing import Set, List, Dict +import sys + +TEST_RUN_SEPARATOR = sys.argv[1] + +fieldnames: Set[str] = set() +rows: List[Dict[str, str]] = [] +row: Dict[str, str] = dict() + +for line in sys.stdin: + line = line.strip() + if line.strip() == TEST_RUN_SEPARATOR: + fieldnames.update(row.keys()) + rows.append(row) + row = dict() + continue + + line = line.split("=") + if len(line) != 2: + continue + + row[line[0]] = line[1] + +writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames) + +writer.writeheader() +for row in rows: + writer.writerow(row) diff --git a/ambient-tests/scripts/netperf/run.sh b/ambient-tests/scripts/netperf/run.sh new file mode 100755 index 0000000000..a7a39067db --- /dev/null +++ b/ambient-tests/scripts/netperf/run.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eux + +# shellcheck disable=SC1091 +source scripts/config.sh + +INTER_TEST_SLEEP=0.1s + +mkdir -p "$NETPERF_RESULTS" + +# First argument is the client namespace +# Second argument is the server namespace +function run-tests() { + # give values names + client_ns=$1 + server_ns=$2 + for _ in $(seq "$N_RUNS") + do + # shellcheck disable=SC2086 + kubectl exec "deploy/$BENCHMARK_CLIENT" -n "$client_ns" \ + -- netperf $NETPERF_GLOBAL_ARGS -H "$BENCHMARK_SERVER.$server_ns" -t TCP_STREAM \ + -- $NETPERF_TEST_ARGS + echo "NAMESPACES=$client_ns:$server_ns" + echo "$TEST_RUN_SEPARATOR" + sleep "$INTER_TEST_SLEEP" + done >> "$NETPERF_RESULTS/TCP_STREAM" + + for _ in $(seq "$N_RUNS") + do + # shellcheck disable=SC2086 + kubectl exec "deploy/$BENCHMARK_CLIENT" -n "$client_ns" \ + -- netperf $NETPERF_GLOBAL_ARGS -H "$BENCHMARK_SERVER.$server_ns" -t TCP_CRR \ + -- $NETPERF_TEST_ARGS $NETPERF_RR_ARGS + echo "NAMESPACES=$client_ns:$server_ns" + echo "$TEST_RUN_SEPARATOR" + sleep "$INTER_TEST_SLEEP" + done >> "$NETPERF_RESULTS/TCP_CRR" + + for _ in $(seq "$N_RUNS") + do + # shellcheck disable=SC2086 + kubectl exec "deploy/$BENCHMARK_CLIENT" -n "$client_ns" \ + -- netperf $NETPERF_GLOBAL_ARGS -H "$BENCHMARK_SERVER.$server_ns" -t TCP_RR \ + -- $NETPERF_TEST_ARGS $NETPERF_RR_ARGS + echo "NAMESPACES=$client_ns:$server_ns" + echo "$TEST_RUN_SEPARATOR" + sleep "$INTER_TEST_SLEEP" + done >> "$NETPERF_RESULTS/TCP_RR" +} + +# clear output files +true > "$NETPERF_RESULTS/TCP_STREAM" +true > "$NETPERF_RESULTS/TCP_CRR" +true > "$NETPERF_RESULTS/TCP_RR" + +run-tests "$NS_AMBIENT" "$NS_AMBIENT" +run-tests "$NS_NO_MESH" "$NS_NO_MESH" +run-tests "$NS_SIDECAR" "$NS_SIDECAR" +run-tests "$NS_WAYPOINT" "$NS_WAYPOINT" +# For cross-mesh tests +# run-tests "$NS_SIDECAR" "$NS_AMBIENT" + diff --git a/ambient-tests/scripts/setup.sh b/ambient-tests/scripts/setup.sh new file mode 100755 index 0000000000..10ca482557 --- /dev/null +++ b/ambient-tests/scripts/setup.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# set up k8 environment +set -eux + +# set up config variables +# shellcheck disable=SC1091 +source scripts/config.sh + + + +# create the namespaces +kubectl create namespace "$NS_NO_MESH" || true # in case the namespace already exists +kubectl create namespace "$NS_SIDECAR" || true +kubectl create namespace "$NS_AMBIENT" || true +kubectl create namespace "$NS_WAYPOINT" || true + +# install both ambient and normal Istio +# they should be both work on the same mesh +# assume istio is already installed so I can use custom images +# istioctl install --set profile=ambient -y + +# inject Envoy sidecars into pods +kubectl label namespace "$NS_SIDECAR" istio-injection=enabled +# use ambient data plane +kubectl label namespace "$NS_AMBIENT" istio.io/dataplane-mode=ambient +kubectl label namespace "$NS_WAYPOINT" istio.io/dataplane-mode=ambient +# WARNING you can't have NS_SIDECAR == NS_AMBIENT + +# create the clients and server +kubectl apply -f "$YAML_PATH" -n "$NS_NO_MESH" +kubectl apply -f "$YAML_PATH" -n "$NS_SIDECAR" +kubectl apply -f "$YAML_PATH" -n "$NS_AMBIENT" +kubectl apply -f "$YAML_PATH" -n "$NS_WAYPOINT" +istioctl x waypoint apply -n "$NS_WAYPOINT" -s "$SA_SERVER" + +# wait for deployments to roll out +echo "If this takes a really long time, you might have forgotten to label you nodes." +kubectl rollout status -n "$NS_NO_MESH" -f yaml/deploy.yaml +kubectl rollout status -n "$NS_SIDECAR" -f yaml/deploy.yaml +kubectl rollout status -n "$NS_AMBIENT" -f yaml/deploy.yaml +kubectl rollout status -n "$NS_WAYPOINT" -f yaml/deploy.yaml + diff --git a/ambient-tests/yaml/cluster.yaml b/ambient-tests/yaml/cluster.yaml new file mode 100644 index 0000000000..4fc85fafeb --- /dev/null +++ b/ambient-tests/yaml/cluster.yaml @@ -0,0 +1,10 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker + labels: + role: server +- role: worker + labels: + role: client diff --git a/ambient-tests/yaml/deploy.yaml b/ambient-tests/yaml/deploy.yaml new file mode 100644 index 0000000000..5f14ce3065 --- /dev/null +++ b/ambient-tests/yaml/deploy.yaml @@ -0,0 +1,96 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: server-sa +--- +apiVersion: v1 +kind: Service +metadata: + name: server +spec: + ports: + - name: control + port: 12865 + protocol: TCP + - name: data0 + port: 35000 + protocol: TCP + - name: python-http + port: 8000 + protocol: TCP + - name: fortio-http80 + port: 8080 + protocol: TCP + - name: fortio-http79 + port: 8079 + protocol: TCP + - name: fortio-http78 + port: 8078 + protocol: TCP + selector: + app: server + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: server + name: server +spec: + replicas: 1 + selector: + matchLabels: + app: server + template: + metadata: + labels: + app: server + spec: + serviceAccountName: server-sa + nodeSelector: + role: server + containers: + - name: server + image: stjinxuan.azurecr.io/ambient-performance + imagePullPolicy: Always + command: ["./server-and-sleep.sh"] + ports: + - containerPort: 12865 + name: control + - containerPort: 6789 + name: echo + - containerPort: 35000 + name: data0 + - containerPort: 8000 + name: python-http + - containerPort: 8080 + name: fortio-http80 + - containerPort: 8079 + name: fortio-http79 + - containerPort: 8078 + name: fortio-http78 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: client + name: client +spec: + replicas: 1 + selector: + matchLabels: + app: client + template: + metadata: + labels: + app: client + spec: + nodeSelector: + role: client + containers: + - name: client + image: stjinxuan.azurecr.io/ambient-performance + imagePullPolicy: Always + command: ["/bin/sleep", "365d"]