├── Makefile ├── .gitignore ├── LICENSE ├── README.md ├── k8s-iperf └── k8s-iperf.yaml /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: server client claen 2 | 3 | require-%: 4 | @ if [ "${${*}}" = "" ]; then \ 5 | echo "Environment variable $* not set"; \ 6 | exit 1; \ 7 | fi 8 | 9 | server: require-K8S_NODE 10 | cat k8s-iperf.yaml | sed -s "s/{NODE}/$(K8S_NODE)/g" | kubectl apply -f - 11 | 12 | client: require-K8S_NODE 13 | @if [[ "$$(kubectl get pod -l app=iperf-server 2> /dev/null)" == "" ]]; then \ 14 | >&2 echo "No server run."; exit 1;\ 15 | fi 16 | @POD=$$(kubectl get pod -o wide -l app=iperf-client | grep $(K8S_NODE) | awk '{print $$1}'); kubectl exec $${POD} -- iperf -c iperf-server 17 | 18 | clean: 19 | @if [[ "$$(kubectl get pod -l app=iperf-server)" != "" || "$$(kubectl get pod -l app=iperf-client)" != "" ]]; then \ 20 | kubectl delete --cascade -f k8s-iperf.yaml; \ 21 | fi -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/vim,git,visualstudiocode 3 | # Edit at https://www.gitignore.io/?templates=vim,git,visualstudiocode 4 | 5 | ### Git ### 6 | # Created by git for backups. To disable backups in Git: 7 | # $ git config --global mergetool.keepBackup false 8 | *.orig 9 | 10 | # Created by git when using merge tools for conflicts 11 | *.BACKUP.* 12 | *.BASE.* 13 | *.LOCAL.* 14 | *.REMOTE.* 15 | *_BACKUP_*.txt 16 | *_BASE_*.txt 17 | *_LOCAL_*.txt 18 | *_REMOTE_*.txt 19 | 20 | ### Vim ### 21 | # Swap 22 | [._]*.s[a-v][a-z] 23 | [._]*.sw[a-p] 24 | [._]s[a-rt-v][a-z] 25 | [._]ss[a-gi-z] 26 | [._]sw[a-p] 27 | 28 | # Session 29 | Session.vim 30 | Sessionx.vim 31 | 32 | # Temporary 33 | .netrwhist 34 | *~ 35 | # Auto-generated tag files 36 | tags 37 | # Persistent undo 38 | [._]*.un~ 39 | 40 | ### VisualStudioCode ### 41 | .vscode/* 42 | !.vscode/settings.json 43 | !.vscode/tasks.json 44 | !.vscode/launch.json 45 | !.vscode/extensions.json 46 | 47 | ### VisualStudioCode Patch ### 48 | # Ignore all local history of files 49 | .history 50 | 51 | # End of https://www.gitignore.io/api/vim,git,visualstudiocode -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Kent Huang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # k8s-iperf 2 | 3 | Modified from [kubernetes-iperf3](https://github.com/Pharb/kubernetes-iperf3) to benchmark kubernetes cluster network performance. Will use iperf to measure network performance with multiple connections from each nodes. 4 | 5 | ## How to use 6 | 7 | Select a node as iperf server, and all the other nodes in kubernetes cluster will try to connect to server at the same time. 8 | 9 | ```bash 10 | ./k8s-iperf 11 | ``` 12 | 13 | ## Output 14 | 15 | ```text 16 | [Start] iperf server 17 | deployment.apps/iperf-server-deployment created 18 | service/iperf-server created 19 | daemonset.apps/iperf-clients created 20 | Waiting for iperf server to start... 21 | 22 | [Start] iperf clients 23 | [Run] iperf-client pod iperf-clients-fffsm 24 | [Run] iperf-client pod iperf-clients-fxnhw 25 | ...... done 26 | 27 | ------------------------------------------------------------ 28 | Server listening on TCP port 5001 29 | TCP window size: 85.3 KByte (default) 30 | ------------------------------------------------------------ 31 | [ 4] local 10.233.66.68 port 5001 connected with 10.233.64.59 port 52912 32 | [ 5] local 10.233.66.68 port 5001 connected with 10.233.65.74 port 52236 33 | [ ID] Interval Transfer Bandwidth 34 | [ 4] 0.0-10.0 sec 2.98 GBytes 2.55 Gbits/sec 35 | [ 5] 0.0-10.0 sec 2.87 GBytes 2.47 Gbits/sec 36 | 37 | [Cleanup] 38 | deployment.apps "iperf-server-deployment" deleted 39 | service "iperf-server" deleted 40 | daemonset.apps "iperf-clients" deleted 41 | ``` 42 | -------------------------------------------------------------------------------- /k8s-iperf: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 3 | 4 | function print_usage() { 5 | >&2 echo "Usage: `basename $0` [iperf options]" 6 | } 7 | 8 | if [[ $# < 1 ]]; then 9 | print_usage 10 | exit 1 11 | fi 12 | SERVER_NODE=$1; shift 13 | 14 | if [[ ! $(kubectl get node -o name | grep "node/${SERVER_NODE}") ]]; then 15 | >&2 echo "[Error] Node ${SERVER_NODE} not found" 16 | print_usage 17 | exit 1 18 | fi 19 | 20 | echo "[Start] iperf server" 21 | if [[ ! $(kubectl get pods -l app=iperf-server 2> /dev/null) ]]; then 22 | cat ${DIR}/k8s-iperf.yaml | sed -s "s/{NODE}/${SERVER_NODE}/g" | kubectl apply -f - 23 | elif [[ $(kubectl get pod -l app=iperf-server -o jsonpath='{.items[0].metadata.labels.node}') != "${SERVER_NODE}" ]]; then 24 | >&2 echo "[Error] Another server had been launched." 25 | >&2 echo "$(kubectl get pods -l app=iperf-server -o wide)" 26 | exit 1 27 | fi 28 | 29 | until $(kubectl get pods -l app=iperf-server -o jsonpath='{.items[0].status.containerStatuses[0].ready}'); do 30 | echo "Waiting for iperf server to start..." 31 | sleep 5 32 | done 33 | echo 34 | 35 | echo "[Start] iperf clients" 36 | CLIENTS=$(kubectl get pods -l app=iperf-client -o name | cut -d'/' -f2) 37 | for POD in ${CLIENTS}; do 38 | until $(kubectl get pod ${POD} -o jsonpath='{.status.containerStatuses[0].ready}'); do 39 | echo "Waiting for ${POD} to start..." 40 | sleep 5 41 | done 42 | done 43 | 44 | for POD in ${CLIENTS}; do 45 | echo "[Run] iperf-client pod ${POD}" 46 | kubectl exec ${POD} -- iperf -c iperf-server $@ &> /dev/null & 47 | done 48 | 49 | until [[ $(jobs | grep -v Running) != "" ]]; do 50 | printf "." 51 | sleep 2 52 | done 53 | printf " done\n" 54 | 55 | echo 56 | kubectl logs -l app=iperf-server 57 | echo 58 | 59 | echo "[Cleanup]" 60 | kubectl delete --cascade -f ${DIR}/k8s-iperf.yaml 61 | -------------------------------------------------------------------------------- /k8s-iperf.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: iperf-server-deployment 5 | labels: 6 | app: iperf-server 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: iperf-server 12 | template: 13 | metadata: 14 | labels: 15 | app: iperf-server 16 | node: {NODE} 17 | spec: 18 | affinity: 19 | nodeAffinity: 20 | preferredDuringSchedulingIgnoredDuringExecution: 21 | - weight: 1 22 | preference: 23 | matchExpressions: 24 | - key: kubernetes.io/hostname 25 | operator: In 26 | values: 27 | - {NODE} 28 | tolerations: 29 | - key: node-role.kubernetes.io/master 30 | operator: Exists 31 | effect: NoSchedule 32 | containers: 33 | - name: iperf3-server 34 | image: mlabbe/iperf 35 | args: ['-s'] 36 | ports: 37 | - containerPort: 5001 38 | name: server 39 | terminationGracePeriodSeconds: 0 40 | 41 | --- 42 | 43 | apiVersion: v1 44 | kind: Service 45 | metadata: 46 | name: iperf-server 47 | spec: 48 | selector: 49 | app: iperf-server 50 | ports: 51 | - protocol: TCP 52 | port: 5001 53 | targetPort: server 54 | 55 | --- 56 | 57 | apiVersion: apps/v1 58 | kind: DaemonSet 59 | metadata: 60 | name: iperf-clients 61 | labels: 62 | app: iperf-client 63 | spec: 64 | selector: 65 | matchLabels: 66 | app: iperf-client 67 | template: 68 | metadata: 69 | labels: 70 | app: iperf-client 71 | spec: 72 | affinity: 73 | nodeAffinity: 74 | requiredDuringSchedulingIgnoredDuringExecution: 75 | nodeSelectorTerms: 76 | - matchExpressions: 77 | - key: kubernetes.io/hostname 78 | operator: NotIn 79 | values: 80 | - {NODE} 81 | tolerations: 82 | - key: node-role.kubernetes.io/master 83 | operator: Exists 84 | effect: NoSchedule 85 | containers: 86 | - name: iperf-client 87 | image: mlabbe/iperf 88 | command: ['/bin/sh', '-c', 'sleep 1d'] 89 | terminationGracePeriodSeconds: 0 --------------------------------------------------------------------------------