chore: initial import from KNEL/PFVCluster@041d311 [#769]
Split per O&M lane work order. Full history: KNEL/PFVCluster. https://projects.knownelement.com/issues/769#note-4152
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# perfbench container — #709. Same toolset as the fleet LXC/guest installer.
|
||||
# Build: docker build -t git.knownelement.com/reachableceo/perfbench:1.0 .
|
||||
FROM debian:12-slim
|
||||
|
||||
RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
|
||||
fio iperf3 jq libaio1 ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY bench-run.sh /usr/local/bin/bench-run.sh
|
||||
RUN chmod +x /usr/local/bin/bench-run.sh
|
||||
|
||||
# storage bench: mount the path to test at /mnt/bench
|
||||
# network bench: run as server: docker run ... bench-run.sh --server
|
||||
ENV BENCH_DIR=/mnt/bench
|
||||
ENTRYPOINT ["/usr/local/bin/bench-run.sh"]
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# bench-run.sh — standardized fleet benchmark (fio + iperf3). [#709]
|
||||
# Same tool, same shape, everywhere: Proxmox LXCs, guests, containers.
|
||||
# Non-destructive: fio writes only its own files under BENCH_DIR.
|
||||
#
|
||||
# Usage:
|
||||
# BENCH_DIR=/path bench-run.sh # storage bench on /path (default /var/tmp)
|
||||
# IPERF_SERVER=host bench-run.sh # + network test to that iperf3 server
|
||||
# bench-run.sh --server # run as iperf3 server (one shot)
|
||||
# Output: one "BENCH|key|value" line per metric (grep-friendly), plus meta.
|
||||
set -u
|
||||
|
||||
RUNTIME="${BENCH_RUNTIME:-20}"
|
||||
SIZE="${BENCH_SIZE:-1G}"
|
||||
BENCH_DIR="${BENCH_DIR:-/var/tmp}"
|
||||
STAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
HOSTID="$(hostname -s)"
|
||||
|
||||
b() { printf 'BENCH|%s|%s|%s\n' "$HOSTID" "$1" "$2"; }
|
||||
|
||||
if [ "${1:-}" = "--server" ]; then
|
||||
exec iperf3 -s -1
|
||||
fi
|
||||
|
||||
command -v fio >/dev/null 2>&1 || { echo "ERROR: fio not installed (see install-bench.sh)" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$BENCH_DIR"
|
||||
b meta stamp "$STAMP"
|
||||
b meta path "$BENCH_DIR"
|
||||
b meta runtime "$RUNTIME"
|
||||
b meta size "$SIZE"
|
||||
|
||||
# context: load, PSI latency (pressure stall info — the latencytop
|
||||
# replacement on modern kernels), and the backing device of BENCH_DIR
|
||||
b meta load "$(cat /proc/loadavg)"
|
||||
if [ -d /proc/pressure ]; then
|
||||
for rsc in io cpu memory; do
|
||||
[ -r "/proc/pressure/$rsc" ] && \
|
||||
b "psi_${rsc}_some_avg10" "$(awk '{for(i=1;i<=NF;i++) if($i ~ /^avg10=/) sub("avg10=","",$i)} /^some/ {print $2; exit}' "/proc/pressure/$rsc" 2>/dev/null)"
|
||||
done
|
||||
fi
|
||||
DEV=$(df -P "$BENCH_DIR" | awk 'NR==2 {print $1}')
|
||||
b meta bench_device "$DEV"
|
||||
[ -r "/sys/block/$(basename "$DEV")/queue/rotational" ] && \
|
||||
b meta bench_device_rotational "$(cat "/sys/block/$(basename "$DEV")/queue/rotational")"
|
||||
|
||||
# fio may print human notes (e.g. sync-engine warnings) before the JSON on
|
||||
# stdout; strip everything before the opening brace so jq always gets JSON.
|
||||
parse_fio() { # $1=json-file $2=testname $3=read|write
|
||||
sed -n '/^{/,$p' "$1" | jq -r --arg n "$2" --arg d "$3" '
|
||||
.jobs[0] as $j |
|
||||
($n) + "|iops=" + ($j[$d].iops | tostring) + "|" +
|
||||
"bw_kbps=" + ($j[$d].bw | tostring) + "|" +
|
||||
"p99_ms=" + (($j[$d].clat_ns.percentile["99.000000"] // 0) / 1000000 | tostring)' | while IFS='|' read -r n rest; do
|
||||
printf 'BENCH|%s|%s|%s\n' "$HOSTID" "$n" "$rest"
|
||||
done
|
||||
}
|
||||
|
||||
run_fio() { # $1=testname $2=read|write $3+=fio-args
|
||||
local name="$1"; local dir="$2"; shift 2
|
||||
fio --name="$name" --output-format=json --timeout=120 "$@" \
|
||||
> "$BENCH_DIR/.fio-out.json" 2>"$BENCH_DIR/.fio-err" || {
|
||||
b "fio_${name}" ERROR; return; }
|
||||
parse_fio "$BENCH_DIR/.fio-out.json" "$name" "$dir"
|
||||
}
|
||||
|
||||
# 4k random read/write (IOPS), 1M sequential read/write (MB/s); direct to skip cache
|
||||
run_fio randread4k read --filename="$BENCH_DIR/perf-test-file" --rw=randread --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
||||
run_fio randwrite4k write --filename="$BENCH_DIR/perf-test-file" --rw=randwrite --bs=4k --direct=1 --iodepth=16 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
||||
run_fio seqread1m read --filename="$BENCH_DIR/perf-test-file" --rw=read --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
||||
run_fio seqwrite1m write --filename="$BENCH_DIR/perf-test-file" --rw=write --bs=1M --direct=1 --iodepth=8 --time_based --runtime="$RUNTIME" --size="$SIZE"
|
||||
|
||||
rm -f "$BENCH_DIR/.fio-out.json" "$BENCH_DIR/.fio-err"
|
||||
|
||||
# post-run pressure + load (did the bench itself saturate the box?)
|
||||
b meta load_end "$(cat /proc/loadavg)"
|
||||
[ -r /proc/pressure/io ] && \
|
||||
b psi_io_some_avg10_end "$(awk '/^some/ {for(i=1;i<=NF;i++) if($i ~ /^avg10=/) {sub("avg10=","",$i); print $i; exit}}' /proc/pressure/io)"
|
||||
|
||||
# network: only when a server is provided
|
||||
if [ -n "${IPERF_SERVER:-}" ] && command -v iperf3 >/dev/null 2>&1; then
|
||||
NET=$(iperf3 -c "$IPERF_SERVER" -t 10 -P 4 -J 2>/dev/null | jq -r '.end.sum_received.bits_per_second' 2>/dev/null)
|
||||
[ -n "$NET" ] && b iperf3_rx_bps "$NET"
|
||||
fi
|
||||
|
||||
b meta end "$STAMP"
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# install-bench.sh — install the #709 benchmark toolset (fio + iperf3 + jq)
|
||||
# on a Debian-based guest or LXC. Idempotent. Not for Proxmox hosts directly:
|
||||
# on hosts, create the bench LXC (see lxc-bench-setup.sh) and run this inside.
|
||||
set -eu
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq fio iperf3 jq >/dev/null
|
||||
# libaio package name differs: libaio1 (bookworm) vs libaio1t64 (trixie+)
|
||||
apt-get install -y -qq libaio1 2>/dev/null || apt-get install -y -qq libaio1t64 >/dev/null
|
||||
echo "bench toolset installed: fio=$(fio --version 2>/dev/null | awk '{print $3}') iperf3=$(iperf3 --version 2>/dev/null | awk 'NR==1{print $2}')"
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# lxc-bench-setup.sh — run ON a Proxmox host: stand up the #709 bench LXC
|
||||
# (Proxmox cannot run docker; this is the host-side packaging of the same
|
||||
# toolset) and optionally bench a storage path through it.
|
||||
#
|
||||
# Usage (from workstation, via tests/remote.sh prox-file):
|
||||
# lxc-bench-setup.sh [--ctid N] [--store /mnt/path] [--keep]
|
||||
# --store PATH bind-mount host PATH into the LXC at /mnt/bench and bench it
|
||||
# --keep leave the LXC running (default: destroyed after the run)
|
||||
set -eu
|
||||
|
||||
CTID="${BENCH_CTID:-30099}"
|
||||
STORE=""
|
||||
KEEP=0
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--ctid) CTID="$2"; shift 2 ;;
|
||||
--store) STORE="$2"; shift 2 ;;
|
||||
--keep) KEEP=1; shift ;;
|
||||
*) echo "unknown arg $1" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
cleanup() {
|
||||
if [ "$KEEP" != 1 ] && pct status "$CTID" >/dev/null 2>&1; then
|
||||
pct stop "$CTID" >/dev/null 2>&1 || true
|
||||
pct destroy "$CTID" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# template: fetch the standard Debian 12 LXC template if missing
|
||||
TPL=$(pveam list local 2>/dev/null | grep -oE 'local:vztmpl/[a-z0-9-]*debian-12-standard[^ ]*\.tar\.zst' | head -1 || true)
|
||||
if [ -z "$TPL" ]; then
|
||||
pveam update >/dev/null
|
||||
DL=$(pveam available --section system 2>/dev/null | grep -oE 'debian-12-standard[^ ]*\.tar\.zst' | sort -V | tail -1)
|
||||
[ -n "$DL" ] || { echo "[bench-lxc] ERROR: no debian-12 LXC template in pveam" >&2; exit 1; }
|
||||
pveam download local "$DL" >/dev/null
|
||||
TPL=$(pveam list local | grep -oE "local:vztmpl/$DL" | head -1)
|
||||
fi
|
||||
echo "[bench-lxc] template: $TPL"
|
||||
|
||||
MP=()
|
||||
if [ -n "$STORE" ]; then
|
||||
MP=(-mp0 "$STORE,mp=/mnt/bench")
|
||||
fi
|
||||
|
||||
pct create "$CTID" "$TPL" --hostname perfbench --memory 1024 --cores 2 \
|
||||
--rootfs local-lvm:8 --net0 name=eth0,bridge=vmbr0,ip=dhcp \
|
||||
--unprivileged 1 --features nesting=0 "${MP[@]}" >/dev/null
|
||||
pct start "$CTID"
|
||||
sleep 5
|
||||
|
||||
# toolset in (same installer the guests use; piped in, nothing fetched from outside)
|
||||
# libaio1 is gone on trixie (t64 transition); fio pulls the right one itself
|
||||
pct exec "$CTID" -- bash -c "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq >/dev/null; apt-get install -y -qq fio iperf3 jq libaio1 >/dev/null || apt-get install -y -qq fio iperf3 jq >/dev/null"
|
||||
|
||||
BDIR="/mnt/bench"
|
||||
[ -z "$STORE" ] && BDIR="/var/tmp"
|
||||
echo "[bench-lxc] benching $BDIR on CT $CTID"
|
||||
pct exec "$CTID" -- env BENCH_DIR="$BDIR" bash -s < "$(dirname "$0")/bench-run.sh"
|
||||
echo "[bench-lxc] done"
|
||||
Reference in New Issue
Block a user