From e66a76235e9c3e332b0c1d0fcf1a8e419fd57323 Mon Sep 17 00:00:00 2001 From: Takeshi Yoshino <4511440+tyoshino@users.noreply.github.com> Date: Mon, 4 May 2026 12:55:22 +0000 Subject: [PATCH] feat(wish/cpp): make it able to run the benchmark on Kubernetes --- wish/cpp/.dockerignore | 6 +++ wish/cpp/Dockerfile.benchmark | 54 +++++++++++++++++++ wish/cpp/Dockerfile.echo_server | 54 +++++++++++++++++++ wish/cpp/deployments/benchmark.yaml | 29 ++++++++++ wish/cpp/deployments/echo-server.yaml | 50 ++++++++++++++++++ wish/cpp/deployments/tls-echo-server.yaml | 50 ++++++++++++++++++ wish/cpp/scripts/build-and-push.sh | 64 +++++++++++++++++++++++ 7 files changed, 307 insertions(+) create mode 100644 wish/cpp/.dockerignore create mode 100644 wish/cpp/Dockerfile.benchmark create mode 100644 wish/cpp/Dockerfile.echo_server create mode 100644 wish/cpp/deployments/benchmark.yaml create mode 100644 wish/cpp/deployments/echo-server.yaml create mode 100644 wish/cpp/deployments/tls-echo-server.yaml create mode 100755 wish/cpp/scripts/build-and-push.sh diff --git a/wish/cpp/.dockerignore b/wish/cpp/.dockerignore new file mode 100644 index 0000000..7c32211 --- /dev/null +++ b/wish/cpp/.dockerignore @@ -0,0 +1,6 @@ +build/ +*.o +*.a +certs/ca.key +certs/server.key +certs/client.key diff --git a/wish/cpp/Dockerfile.benchmark b/wish/cpp/Dockerfile.benchmark new file mode 100644 index 0000000..ab929f8 --- /dev/null +++ b/wish/cpp/Dockerfile.benchmark @@ -0,0 +1,54 @@ +# syntax=docker/dockerfile:1 +# --------------------------------------------------------------------------- +# Stage 1: Build +# --------------------------------------------------------------------------- +FROM debian:bookworm AS builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + git \ + ninja-build \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /src + +# Copy CMakeLists, patches, and source files before configure. +# CMake validates source file existence during the configure phase, +# so src/ must be present before `cmake -B build` runs. +# FetchContent downloads are still cached as long as CMakeLists.txt, +# patches/, src/, and benchmark/ are unchanged. +COPY CMakeLists.txt . +COPY patches/ patches/ +COPY src/ src/ +COPY benchmark/ benchmark/ + +# Configure: triggers FetchContent downloads (cached as a Docker layer). +RUN cmake -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DWISH_BUILD_TESTS=OFF \ + -DWISH_BUILD_BENCHMARKS=ON \ + -DWISH_BUILD_EXAMPLES=OFF + +RUN cmake --build build \ + --target benchmark_client tls_benchmark_client high_qps_benchmark_client \ + -- -j"$(nproc)" + +# --------------------------------------------------------------------------- +# Stage 2: Runtime +# --------------------------------------------------------------------------- +FROM debian:bookworm-slim AS runtime + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libstdc++6 \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /src/build/benchmark/benchmark_client /usr/local/bin/benchmark_client +COPY --from=builder /src/build/benchmark/tls_benchmark_client /usr/local/bin/tls_benchmark_client +COPY --from=builder /src/build/benchmark/high_qps_benchmark_client /usr/local/bin/high_qps_benchmark_client + +# Default: latency benchmark client. +# Override the ENTRYPOINT or CMD in the Job spec to switch clients. +ENTRYPOINT ["/usr/local/bin/benchmark_client"] +CMD ["--host=wish-echo-server", "--port=8080"] diff --git a/wish/cpp/Dockerfile.echo_server b/wish/cpp/Dockerfile.echo_server new file mode 100644 index 0000000..852483d --- /dev/null +++ b/wish/cpp/Dockerfile.echo_server @@ -0,0 +1,54 @@ +# syntax=docker/dockerfile:1 +# --------------------------------------------------------------------------- +# Stage 1: Build +# --------------------------------------------------------------------------- +FROM debian:bookworm AS builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + git \ + ninja-build \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /src + +# Copy CMakeLists, patches, and source files before configure. +# CMake validates source file existence during the configure phase, +# so src/ must be present before `cmake -B build` runs. +# FetchContent downloads are still cached as long as CMakeLists.txt, +# patches/, and src/ are unchanged. +COPY CMakeLists.txt . +COPY patches/ patches/ +COPY src/ src/ +COPY examples/ examples/ + +# Configure: triggers FetchContent downloads (cached as a Docker layer). +RUN cmake -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DWISH_BUILD_TESTS=OFF \ + -DWISH_BUILD_BENCHMARKS=OFF \ + -DWISH_BUILD_EXAMPLES=ON + +RUN cmake --build build \ + --target echo_server tls_echo_server \ + -- -j"$(nproc)" + +# --------------------------------------------------------------------------- +# Stage 2: Runtime +# --------------------------------------------------------------------------- +FROM debian:bookworm-slim AS runtime + +RUN apt-get update && apt-get install -y --no-install-recommends \ + libstdc++6 \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /src/build/examples/echo_server /usr/local/bin/echo_server +COPY --from=builder /src/build/examples/tls_echo_server /usr/local/bin/tls_echo_server + +EXPOSE 8080 + +# Default: plain-text echo server. Override CMD in the Pod spec for TLS. +ENTRYPOINT ["/usr/local/bin/echo_server"] +CMD ["--port=8080"] diff --git a/wish/cpp/deployments/benchmark.yaml b/wish/cpp/deployments/benchmark.yaml new file mode 100644 index 0000000..56987ee --- /dev/null +++ b/wish/cpp/deployments/benchmark.yaml @@ -0,0 +1,29 @@ +apiVersion: batch/v1 +kind: Job +metadata: + # Append a unique suffix (e.g. timestamp) to run multiple benchmarks: + # kubectl create job wish-benchmark-$(date +%s) --from=job/wish-benchmark-client + name: wish-benchmark +spec: + # Do not retry on failure so a broken binary doesn't loop. + backoffLimit: 0 + template: + spec: + restartPolicy: Never + containers: + - name: client + image: us-central1-docker.pkg.dev/black-outlet-487003-v4/wish/benchmark:latest + command: ["high_qps_benchmark_client"] + args: + - "--stderrthreshold=0" + - "--benchmark_counters_tabular=true" + - "--host=wish-echo-server" + - "--port=8080" + - "--benchmark_min_time=5s" + resources: + requests: + cpu: "0.5" + memory: "500Mi" + limits: + cpu: "0.5" + memory: "500Mi" diff --git a/wish/cpp/deployments/echo-server.yaml b/wish/cpp/deployments/echo-server.yaml new file mode 100644 index 0000000..5a19ea7 --- /dev/null +++ b/wish/cpp/deployments/echo-server.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: wish-echo-server + labels: + app: wish-echo-server +spec: + replicas: 1 + selector: + matchLabels: + app: wish-echo-server + template: + metadata: + labels: + app: wish-echo-server + spec: + containers: + - name: server + image: us-central1-docker.pkg.dev/black-outlet-487003-v4/wish/echo-server:latest + args: + - "--port=8080" + ports: + - name: http + containerPort: 8080 + protocol: TCP + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 2 + periodSeconds: 5 + resources: + requests: + cpu: "1" + memory: "500Mi" + limits: + cpu: "1" + memory: "500Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: wish-echo-server +spec: + selector: + app: wish-echo-server + ports: + - port: 8080 + targetPort: 8080 + protocol: TCP + type: ClusterIP diff --git a/wish/cpp/deployments/tls-echo-server.yaml b/wish/cpp/deployments/tls-echo-server.yaml new file mode 100644 index 0000000..249f869 --- /dev/null +++ b/wish/cpp/deployments/tls-echo-server.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: wish-tls-echo-server + labels: + app: wish-tls-echo-server +spec: + replicas: 1 + selector: + matchLabels: + app: wish-tls-echo-server + template: + metadata: + labels: + app: wish-tls-echo-server + spec: + containers: + - name: server + image: us-central1-docker.pkg.dev/black-outlet-487003-v4/wish/tls-echo-server:latest + args: + - "--port=8443" + ports: + - name: https + containerPort: 8443 + protocol: TCP + readinessProbe: + tcpSocket: + port: 8443 + initialDelaySeconds: 2 + periodSeconds: 5 + resources: + requests: + cpu: "1" + memory: "500Mi" + limits: + cpu: "1" + memory: "500Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: wish-tls-echo-server +spec: + selector: + app: wish-tls-echo-server + ports: + - port: 8443 + targetPort: 8443 + protocol: TCP + type: ClusterIP diff --git a/wish/cpp/scripts/build-and-push.sh b/wish/cpp/scripts/build-and-push.sh new file mode 100755 index 0000000..adb576a --- /dev/null +++ b/wish/cpp/scripts/build-and-push.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# build-and-push.sh +# Builds wish-server and wish-bench-client images, pushes them to Artifact Registry. +# +# Prerequisites: +# gcloud auth configure-docker "${REGION}-docker.pkg.dev" +# (or: gcloud auth login && gcloud auth application-default login) +# +# Usage: +# cd wish/cpp +# REGION=asia-northeast1 PROJECT=my-gcp-project REPOSITORY=wish ./scripts/build-and-push.sh +# +# Optional env vars: +# TAG – image tag (default: git short SHA or "latest") +# PUSH – set to "false" to build only without pushing + +set -euo pipefail + +REGION="${REGION:?Set REGION, e.g. asia-northeast1}" +PROJECT="${PROJECT:?Set PROJECT to your GCP project ID}" +REPOSITORY="${REPOSITORY:?Set REPOSITORY to your Artifact Registry repo name}" + +REGISTRY="${REGION}-docker.pkg.dev/${PROJECT}/${REPOSITORY}" + +# Use git short SHA as default tag for reproducibility; fall back to "latest". +if git rev-parse --short HEAD &>/dev/null; then + DEFAULT_TAG="$(git rev-parse --short HEAD)" +else + DEFAULT_TAG="latest" +fi +TAG="${TAG:-${DEFAULT_TAG}}" +PUSH="${PUSH:-true}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# The build context is wish/cpp (one level above scripts/). +CTX="$(cd "${SCRIPT_DIR}/.." && pwd)" + +echo "==> Build context : ${CTX}" +echo "==> Registry : ${REGISTRY}" +echo "==> Tag : ${TAG}" +echo "" + +build_and_push() { + local name="$1" + local dockerfile="$2" + local full_tag="${REGISTRY}/${name}:${TAG}" + local latest_tag="${REGISTRY}/${name}:latest" + + echo "==> Building ${full_tag} ..." + DOCKER_BUILDKIT=1 docker build \ + --file "${CTX}/${dockerfile}" \ + --tag "${full_tag}" \ + --tag "${latest_tag}" \ + "${CTX}" + + if [[ "${PUSH}" == "true" ]]; then + echo "==> Pushing ${full_tag} ..." + docker push "${full_tag}" + docker push "${latest_tag}" + fi +} + +build_and_push "echo-server" "Dockerfile.echo_server" +build_and_push "benchmark" "Dockerfile.benchmark"