mirror of
https://github.com/kerberos-io/deployment.git
synced 2026-11-05 20:10:26 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef9876072a |
@@ -27,10 +27,6 @@ jobs:
|
||||
kubectl get sc
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Check promoted Hub runtime
|
||||
run: |
|
||||
helm repo add kerberos https://charts.kerberos.io
|
||||
bash scripts/check-hub-runtime.sh
|
||||
- name: Install OpenEBS
|
||||
run: |
|
||||
kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Self-hosted with Docker Compose
|
||||
|
||||
For a dedicated disposable pipeline test environment, see the [local load-test stack](loadtest/README.md).
|
||||
|
||||
....
|
||||
|
||||
@@ -17,21 +17,6 @@ The Kerberos.io stack offers flexible installation options, supporting deploymen
|
||||
|
||||
This repository continuously tests the Kerberos.io deployment using GitHub Actions across various platforms. Refer to the badges for an overview of the operating systems and Kubernetes distributions we are deploying to. We welcome suggestions for additional automations to consider.
|
||||
|
||||
### Hardened Hub frontend
|
||||
|
||||
The promoted frontend image requires Hub chart **0.170.0 or newer**, which
|
||||
provides port `8080`, non-root/read-only runtime settings and a writable `/tmp`
|
||||
mount. Both primary and demo frontends use these settings; Admin remains on its
|
||||
legacy image and port `80`. Keep `global.imageRegistry` empty for the supplied
|
||||
fully qualified `ghcr.io` image names. Service ports remain `80` and the frontend
|
||||
NodePort remains `32080`, targeting the container port named `http`.
|
||||
|
||||
Run `bash scripts/check-hub-runtime.sh` to check the published chart with these
|
||||
values before installation, or pass a local chart path as the first argument.
|
||||
When adding custom branding mounts, preserve the chart's `frontend-tmp` volume
|
||||
and `/tmp` mount. Existing deployments may require the explicit
|
||||
[HTTP port migration](https://github.com/kerberos-io/helm-charts/blob/main/charts/hub/README.md#recovering-a-duplicate-http-port-during-upgrades).
|
||||
|
||||
## Architecture
|
||||
|
||||
As previously indicated, several integral components, including Object Storage, Database, and Message Brokers, are deployed and configured to ensure the proper functionality of Kerberos.io. The architecture diagrams below aims to provide a visual representation of these components and their interactions with one another depending the deployment; self-hosted or managed cloud deployment.
|
||||
|
||||
@@ -9,7 +9,7 @@ spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
targetPort: 80
|
||||
nodePort: 32080 # You can specify a port in the range 30000-32767 or let Kubernetes assign one automatically
|
||||
name: frontend
|
||||
protocol: TCP
|
||||
|
||||
@@ -19,7 +19,7 @@ licenseServer:
|
||||
|
||||
# When using a private registry, you can specify the registry here.
|
||||
global:
|
||||
imageRegistry: ""
|
||||
imageRegistry: "docker.io/"
|
||||
# Environment: set to 'production', 'develop', 'demo', 'staging' or 'acceptance'.
|
||||
# Set to 'true' if this is a private deployment.
|
||||
environment: "production"
|
||||
@@ -157,7 +157,7 @@ kerberoshub:
|
||||
api:
|
||||
repository: ghcr.io/uug-ai/hub-api
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.11.31"
|
||||
tag: "v1.9.48"
|
||||
replicas: 1
|
||||
jwtSecret: "I1JcwzW3A0t_THIS-IS_NOT_A_SECRET_WJK9jnPkipbnVTpf0efMy" # change to a random value, this is for generating JWT tokens.
|
||||
schema: "http"
|
||||
@@ -240,9 +240,7 @@ kerberoshub:
|
||||
frontend:
|
||||
repository: ghcr.io/uug-ai/hub-frontend
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.19.28"
|
||||
# Requires Hub chart 0.170.0+ for the matching hardened runtime defaults.
|
||||
containerPort: 8080
|
||||
tag: "v1.13.0"
|
||||
replicas: 1
|
||||
schema: "http"
|
||||
url: "yourdomain.com"
|
||||
@@ -357,7 +355,7 @@ kerberoshub:
|
||||
cleanup:
|
||||
repository: ghcr.io/uug-ai/hub-cleanup
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.4.26"
|
||||
tag: "v1.4.16"
|
||||
resources:
|
||||
requests:
|
||||
memory: 50Mi
|
||||
@@ -365,7 +363,7 @@ kerberoshub:
|
||||
monitordevice:
|
||||
repository: ghcr.io/uug-ai/hub-monitor-device
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.4.10"
|
||||
tag: "v1.4.1"
|
||||
resources:
|
||||
requests:
|
||||
memory: 50Mi
|
||||
@@ -417,7 +415,7 @@ kerberospipeline:
|
||||
event:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-event
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.9"
|
||||
tag: "v1.3.1"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -429,7 +427,7 @@ kerberospipeline:
|
||||
monitor:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-monitor
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.29"
|
||||
tag: "v1.3.11"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -441,7 +439,7 @@ kerberospipeline:
|
||||
sequence:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-sequence
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.7.14"
|
||||
tag: "v1.6.23"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -451,9 +449,9 @@ kerberospipeline:
|
||||
memory: 50Mi
|
||||
cpu: 50m
|
||||
throttler:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-throttler
|
||||
repository: uugai/hub-pipeline-throttler
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.2.10"
|
||||
tag: "v1.2.0"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -465,7 +463,7 @@ kerberospipeline:
|
||||
notify:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-notification
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.46"
|
||||
tag: "v1.3.17"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -483,9 +481,9 @@ kerberospipeline:
|
||||
# persistentVolumeClaim:
|
||||
# claimName: custom-layout-claim
|
||||
notifyTest:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-notification-test
|
||||
repository: uugai/hub-pipeline-notification-test
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.2.6"
|
||||
tag: "v1.2.1"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -505,7 +503,7 @@ kerberospipeline:
|
||||
analysis:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-analysis
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.8.29"
|
||||
tag: "v1.8.4"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -517,7 +515,7 @@ kerberospipeline:
|
||||
dominantColor:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-dominantcolors
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v2.0.9"
|
||||
tag: "v2.0.3"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -529,7 +527,7 @@ kerberospipeline:
|
||||
thumbnail:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-thumbnail
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.22"
|
||||
tag: "v1.3.10"
|
||||
replicas: 1
|
||||
quality: "1" # 1 (best) - 31 (worst)
|
||||
width: "600"
|
||||
@@ -544,9 +542,9 @@ kerberospipeline:
|
||||
memory: 50Mi
|
||||
cpu: 50m
|
||||
counting:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-counting
|
||||
repository: uugai/hub-pipeline-counting
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v2.0.6"
|
||||
tag: "v1.6.3"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
@@ -556,7 +554,7 @@ kerberospipeline:
|
||||
enabled: true # Enable or disable the sprite generation 'true' or 'false
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-sprite
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.1.27"
|
||||
tag: "v1.1.16"
|
||||
replicas: 1
|
||||
interval: "1" # Number of secondes between each thumbnail in the sprite
|
||||
width: "240" # Should not be changed for the moment (hard coded in UI)
|
||||
@@ -571,7 +569,7 @@ kerberospipeline:
|
||||
export:
|
||||
repository: ghcr.io/uug-ai/hub-pipeline-export
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.2.20"
|
||||
tag: "v1.2.9"
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
|
||||
@@ -24,7 +24,7 @@ spec:
|
||||
command: ["sh", "-c", "until nc -z mongodb.mongodb 27017 > /dev/null; do echo Waiting for master.; sleep 2; done;"]
|
||||
containers:
|
||||
- name: vault
|
||||
image: ghcr.io/uug-ai/vault:v1.7.19
|
||||
image: ghcr.io/uug-ai/vault:v1.4.9
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
@@ -43,4 +43,4 @@ spec:
|
||||
optional: true
|
||||
env:
|
||||
- name: GIN_MODE
|
||||
value: release
|
||||
value: release
|
||||
@@ -0,0 +1,16 @@
|
||||
# Optional Docker Compose substitutions; copy to .env if needed.
|
||||
# Host binds are always 127.0.0.1. Update the CLI URLs when changing these ports.
|
||||
LOADTEST_MONGODB_PORT=27028
|
||||
LOADTEST_RABBITMQ_PORT=5673
|
||||
LOADTEST_RABBITMQ_MANAGEMENT_PORT=15673
|
||||
|
||||
# Pinned release defaults; use image@sha256:... for immutable repeat runs.
|
||||
LOADTEST_MONGODB_IMAGE=mongo:8.0.13
|
||||
LOADTEST_RABBITMQ_IMAGE=rabbitmq:4.1.4-management
|
||||
LOADTEST_EVENT_IMAGE=ghcr.io/uug-ai/hub-pipeline-event:v1.3.2
|
||||
LOADTEST_MONITOR_IMAGE=ghcr.io/uug-ai/hub-pipeline-monitor:v1.3.19
|
||||
LOADTEST_SEQUENCE_IMAGE=ghcr.io/uug-ai/hub-pipeline-sequence:v1.7.1
|
||||
|
||||
# CLI host connections. Compose does not export .env into your host shell.
|
||||
LOADTEST_MONGODB_URI=mongodb://127.0.0.1:27028/Kerberos?replicaSet=loadtest-rs&directConnection=true&readConcernLevel=majority&w=majority&journal=true&wtimeoutMS=10000
|
||||
LOADTEST_RABBITMQ_URL=amqp://loadtest:disposable-loadtest-only@127.0.0.1:5673/
|
||||
@@ -0,0 +1,2 @@
|
||||
.env
|
||||
reports/
|
||||
@@ -0,0 +1,195 @@
|
||||
# Disposable local pipeline load test
|
||||
|
||||
This dedicated Compose project exercises **real disk-backed MongoDB and RabbitMQ**
|
||||
and the released event router, monitor, and sequence workers. The CLI runs on the
|
||||
host; no CLI container image is needed. Synthetic recording events pass through
|
||||
`monitor,sequence,loadtest-<run-id>`; the CLI consumes the final completion queue.
|
||||
There is no Vault, video upload, GPU, inference, or notification worker in this
|
||||
initial mode. This is a functional/local throughput baseline, **not an enterprise
|
||||
capacity claim** or a substitute for representative full-scale testing.
|
||||
|
||||
## Isolation and prerequisites
|
||||
|
||||
- Docker Engine with Compose v2 and permission to use its daemon. If access is
|
||||
denied, stop: do not use sudo, change socket permissions, or bypass that policy.
|
||||
- Host Go matching the CLI's `go.mod`, or an existing CLI installation containing
|
||||
`load-test`. The commands below assume adjacent `deployment/` and `cli/` checkouts.
|
||||
- Access to the pinned GHCR images. Private images may require an existing
|
||||
authorized Docker registry login; this stack does not obtain credentials.
|
||||
- Available loopback ports 27028, 5673, and 15673, and disk space for retained data.
|
||||
|
||||
The project name is `uug-loadtest`. Its network is private/internal and its named
|
||||
volumes are project-scoped; no external database, broker, production volume, or
|
||||
production configuration is mounted. All published ports bind **127.0.0.1 only**.
|
||||
MongoDB deliberately has no authentication on this isolated local test network.
|
||||
RabbitMQ's public **disposable test credentials** are
|
||||
`loadtest` / `disposable-loadtest-only`, not the restricted `guest` account.
|
||||
Other local processes can access these services: use only synthetic test data.
|
||||
|
||||
The released monitor hardcodes database **`Kerberos`**, and the released queue
|
||||
builders use RabbitMQ's root vhost **`/`**. Consequently, these must be dedicated
|
||||
instances, not a test database/vhost on shared production infrastructure.
|
||||
Every CLI invocation below deliberately includes
|
||||
`--database Kerberos --allow-default-names --run-id smoke`. This safety exception
|
||||
is appropriate **only for this disposable stack**.
|
||||
|
||||
## Start and inspect
|
||||
|
||||
From the monorepo root:
|
||||
|
||||
```sh
|
||||
cd deployment/loadtest
|
||||
docker compose config --quiet
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker compose ps -a
|
||||
docker compose images
|
||||
```
|
||||
|
||||
Do not run these daemon commands where Docker access is denied. `config --quiet`
|
||||
can still validate the manifest without launching containers.
|
||||
|
||||
An idempotent init job creates the single-node `loadtest-rs` replica set and waits
|
||||
for a writable primary. Mongo health checks first verify server availability;
|
||||
workers start only after the init job succeeds and RabbitMQ is healthy. The init
|
||||
job refuses to reconfigure an unexpected existing replica set. A successful
|
||||
`mongo-init` exit is expected, not a failed service. Compose startup is **not**
|
||||
proof of pipeline readiness: the CLI checks that the required stage queues have
|
||||
consumers before running.
|
||||
|
||||
The host CLI uses `directConnection=true` because the replica advertises
|
||||
`mongo:27017`, which is resolvable only inside Compose. Workers use that internal
|
||||
address directly. Both URI configurations request majority reads, journaled
|
||||
majority writes, and a 10-second write concern timeout. Worker retryable writes
|
||||
are enabled. A single member exercises replica-set semantics but provides **no
|
||||
redundancy** and does not model a multi-node majority's latency.
|
||||
|
||||
Tracing is deliberately off: `OTEL_SDK_DISABLED=true` and an explicitly empty
|
||||
`OTEL_EXPORTER_OTLP_ENDPOINT`. The pinned monitor's trace library treats the empty
|
||||
endpoint as no-op; the pinned sequence ignores its older library's missing-endpoint
|
||||
error and uses the global no-op provider. No fake collector endpoint or recurring
|
||||
export failures are needed. Recheck this behavior when overriding worker images.
|
||||
|
||||
## Prepare, smoke, and verify
|
||||
|
||||
See the [CLI README](https://github.com/uug-ai/cli/blob/main/README.md) for the
|
||||
load-test command reference.
|
||||
|
||||
Fixture preparation is a **separate, untimed step**. Start small: one organisation,
|
||||
one project, two devices, and no historical recordings. History defaults to zero;
|
||||
increase `--history-per-device` only when explicitly testing a larger database.
|
||||
Workload dimensions, rate, duration, concurrency, and deployment label are set
|
||||
only on `prepare` and frozen in its stored manifest. `run`, `verify`, and `cleanup`
|
||||
load that manifest by run ID and reject workload overrides.
|
||||
|
||||
In the same host shell:
|
||||
|
||||
```sh
|
||||
export LOADTEST_MONGODB_URI='mongodb://127.0.0.1:27028/Kerberos?replicaSet=loadtest-rs&directConnection=true&readConcernLevel=majority&w=majority&journal=true&wtimeoutMS=10000'
|
||||
export LOADTEST_RABBITMQ_URL='amqp://loadtest:disposable-loadtest-only@127.0.0.1:5673/'
|
||||
mkdir -p reports
|
||||
cd ../../cli
|
||||
|
||||
# Safe preview: no writes or publication without both execution flags.
|
||||
go run . load-test prepare \
|
||||
--database Kerberos --allow-default-names --run-id smoke \
|
||||
--organisations 1 --projects 1 --devices 2 --history-per-device 0 \
|
||||
--rate 5 --duration 10s --concurrency 4 --deployment-label local-compose-smoke
|
||||
|
||||
# Explicitly seed only this dedicated test target.
|
||||
go run . load-test prepare \
|
||||
--database Kerberos --allow-default-names --run-id smoke \
|
||||
--organisations 1 --projects 1 --devices 2 --history-per-device 0 \
|
||||
--rate 5 --duration 10s --concurrency 4 --deployment-label local-compose-smoke \
|
||||
--execute --confirm-test-target
|
||||
|
||||
# First warm/smoke run: 5 events/sec for 10 seconds, 4 publishers.
|
||||
go run . load-test run \
|
||||
--database Kerberos --allow-default-names --run-id smoke \
|
||||
--drain-timeout 60s --max-p99 10s \
|
||||
--report ../deployment/loadtest/reports/smoke.json \
|
||||
--execute --confirm-test-target
|
||||
|
||||
go run . load-test verify \
|
||||
--database Kerberos --allow-default-names --run-id smoke \
|
||||
--execute --confirm-test-target
|
||||
```
|
||||
|
||||
`--max-p99 10s` is a deliberately generous smoke-test gate, not a production SLO.
|
||||
Let the run drain and inspect verification/report failures before preparing a new
|
||||
run with increased rate or concurrency. Cleanup retains a manifest tombstone:
|
||||
use a **new run ID** and prepare new fixtures for each subsequent test, never
|
||||
reuse an ID after cleanup. There is no automatic cleanup after a run.
|
||||
Preparation, execution and cleanup share one database-wide lock so their load
|
||||
cannot overlap. Success releases the active-run lock;
|
||||
failed or interrupted runs retain it indefinitely to prevent overlap with
|
||||
unfinished work. Investigate and retain reports first, then reset this dedicated
|
||||
stack's volumes before starting fresh. A different run ID alone does not bypass
|
||||
that lock.
|
||||
|
||||
The CLI uses **only** `LOADTEST_MONGODB_URI` and `LOADTEST_RABBITMQ_URL` for these
|
||||
connections, never generic application environment fallbacks. The explicit
|
||||
`MONGODB_*`/`RABBITMQ_*` entries in Compose are worker settings, not CLI settings.
|
||||
The `.env.example` lists Compose port/image overrides. If you copy it to `.env`,
|
||||
Compose reads it automatically, but your host shell does not. Export the CLI URLs
|
||||
explicitly and change their ports to match `LOADTEST_MONGODB_PORT` and
|
||||
`LOADTEST_RABBITMQ_PORT`. The management UI is at http://127.0.0.1:15673/ by default;
|
||||
`LOADTEST_RABBITMQ_MANAGEMENT_PORT` changes that port.
|
||||
|
||||
## Results, provenance, and troubleshooting
|
||||
|
||||
Record the CLI git revision, fixture dimensions/history, run ID, rate, duration,
|
||||
concurrency, drain timeout, latency gate, host CPU/RAM/disk, and competing workloads
|
||||
alongside each report. Record `docker compose images` and
|
||||
`docker image inspect <image> --format '{{json .RepoDigests}}'` for resolved images;
|
||||
the defaults are release **tags**, not a claim of immutable image identity or a
|
||||
known build digest. For reproducible comparisons, retain the resolved digests and
|
||||
set `LOADTEST_EVENT_IMAGE`, `LOADTEST_MONITOR_IMAGE`, and `LOADTEST_SEQUENCE_IMAGE`
|
||||
to those immutable references. Pin `LOADTEST_MONGODB_IMAGE` and
|
||||
`LOADTEST_RABBITMQ_IMAGE` to the resolved digests of MongoDB `8.0.13` and RabbitMQ
|
||||
`4.1.4-management` as well. Override only with compatible images and record the
|
||||
change.
|
||||
|
||||
From `deployment/loadtest`, inspect `docker compose ps -a` and
|
||||
`docker compose logs --tail=100 mongo-init event monitor sequence`. If the CLI
|
||||
reports missing consumers, fix worker startup before retrying. Do not bypass
|
||||
readiness. `docker compose exec rabbitmq rabbitmqctl list_queues name consumers messages`
|
||||
can confirm routing and backlog. The worker libraries also declare unrelated
|
||||
analysis/dead-letter queues; their existence does not mean those workers run.
|
||||
Do not treat a broker acknowledgement alone as persistence or pipeline completion.
|
||||
|
||||
## Explicit cleanup and persistent storage
|
||||
|
||||
From `cli/`, first preview and then explicitly remove this run's fixtures:
|
||||
|
||||
```sh
|
||||
go run . load-test cleanup \
|
||||
--database Kerberos --allow-default-names --run-id smoke
|
||||
go run . load-test cleanup \
|
||||
--database Kerberos --allow-default-names --run-id smoke \
|
||||
--execute --confirm-test-target
|
||||
```
|
||||
|
||||
Wait for a completed/drained run before cleanup. Run-scoped CLI cleanup does not
|
||||
destroy the shared stage queues or this stack's volumes, and retains a manifest
|
||||
tombstone so the cleaned run ID cannot be reused. Stop workers before a full reset
|
||||
if a failed run left messages behind. Cleanup is available only for a finished,
|
||||
passed run; it does not discard prepared, running,
|
||||
or failed runs or release their retained active-run lock. The empty, unused
|
||||
completion queue is retained to preserve late deliveries; it is removed only
|
||||
when the disposable broker data is explicitly reset.
|
||||
|
||||
From `deployment/loadtest`:
|
||||
|
||||
```sh
|
||||
# Stops and removes this stack; retains all database/broker volumes and reports.
|
||||
docker compose down
|
||||
|
||||
# DESTRUCTIVE: only for this dedicated stack. Deletes ALL its persisted test data.
|
||||
docker compose down --volumes
|
||||
```
|
||||
|
||||
Named volumes persist across stop/start and ordinary `down`; RabbitMQ has a stable
|
||||
hostname to preserve its on-disk node identity. Reports remain under `reports/`
|
||||
even after volume reset. Do not prune global Docker resources or reuse these
|
||||
commands against another Compose project.
|
||||
@@ -0,0 +1,103 @@
|
||||
name: uug-loadtest
|
||||
|
||||
x-worker-environment: &worker-environment
|
||||
ENVIRONMENT: disposable-local-loadtest
|
||||
LOG_LEVEL: error
|
||||
RABBITMQ_HOST: rabbitmq:5672
|
||||
RABBITMQ_EXCHANGE: ""
|
||||
RABBITMQ_USERNAME: loadtest
|
||||
# Public disposable test credentials, never production credentials.
|
||||
RABBITMQ_PASSWORD: disposable-loadtest-only
|
||||
MONGODB_URI: "mongodb://mongo:27017/Kerberos?replicaSet=loadtest-rs&readConcernLevel=majority&w=majority&journal=true&wtimeoutMS=10000"
|
||||
MONGODB_DATABASE_CLOUD: Kerberos
|
||||
MONGODB_RETRY_WRITES: "true"
|
||||
OTEL_SDK_DISABLED: "true"
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT: ""
|
||||
|
||||
x-worker: &worker
|
||||
networks:
|
||||
- loadtest
|
||||
restart: "no"
|
||||
depends_on:
|
||||
mongo-init:
|
||||
condition: service_completed_successfully
|
||||
rabbitmq:
|
||||
condition: service_healthy
|
||||
environment: *worker-environment
|
||||
|
||||
services:
|
||||
mongo:
|
||||
image: ${LOADTEST_MONGODB_IMAGE:-mongo:8.0.13}
|
||||
command: ["mongod", "--replSet", "loadtest-rs", "--bind_ip_all", "--noauth"]
|
||||
ports:
|
||||
- "127.0.0.1:${LOADTEST_MONGODB_PORT:-27028}:27017"
|
||||
networks:
|
||||
- loadtest
|
||||
volumes:
|
||||
- mongo-data:/data/db
|
||||
- mongo-config:/data/configdb
|
||||
healthcheck:
|
||||
test: ["CMD", "mongosh", "--quiet", "--eval", "quit(db.adminCommand({ping: 1}).ok ? 0 : 1)"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 10s
|
||||
|
||||
mongo-init:
|
||||
image: ${LOADTEST_MONGODB_IMAGE:-mongo:8.0.13}
|
||||
command:
|
||||
- mongosh
|
||||
- "mongodb://mongo:27017/admin?directConnection=true"
|
||||
- --quiet
|
||||
- --file
|
||||
- /init/replica-set.js
|
||||
networks:
|
||||
- loadtest
|
||||
volumes:
|
||||
- ./replica-set.js:/init/replica-set.js:ro
|
||||
restart: "no"
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_healthy
|
||||
|
||||
rabbitmq:
|
||||
image: ${LOADTEST_RABBITMQ_IMAGE:-rabbitmq:4.1.4-management}
|
||||
hostname: rabbitmq
|
||||
environment:
|
||||
RABBITMQ_DEFAULT_USER: loadtest
|
||||
RABBITMQ_DEFAULT_PASS: disposable-loadtest-only
|
||||
RABBITMQ_DEFAULT_VHOST: /
|
||||
ports:
|
||||
- "127.0.0.1:${LOADTEST_RABBITMQ_PORT:-5673}:5672"
|
||||
- "127.0.0.1:${LOADTEST_RABBITMQ_MANAGEMENT_PORT:-15673}:15672"
|
||||
networks:
|
||||
- loadtest
|
||||
volumes:
|
||||
- rabbitmq-data:/var/lib/rabbitmq
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "rabbitmq-diagnostics -q ping && rabbitmq-diagnostics -q check_port_connectivity && rabbitmq-diagnostics -q check_local_alarms"]
|
||||
interval: 10s
|
||||
timeout: 15s
|
||||
retries: 30
|
||||
start_period: 20s
|
||||
|
||||
event:
|
||||
<<: *worker
|
||||
image: ${LOADTEST_EVENT_IMAGE:-ghcr.io/uug-ai/hub-pipeline-event:v1.3.2}
|
||||
|
||||
monitor:
|
||||
<<: *worker
|
||||
image: ${LOADTEST_MONITOR_IMAGE:-ghcr.io/uug-ai/hub-pipeline-monitor:v1.3.19}
|
||||
|
||||
sequence:
|
||||
<<: *worker
|
||||
image: ${LOADTEST_SEQUENCE_IMAGE:-ghcr.io/uug-ai/hub-pipeline-sequence:v1.7.1}
|
||||
|
||||
networks:
|
||||
loadtest:
|
||||
internal: true
|
||||
|
||||
volumes:
|
||||
mongo-data:
|
||||
mongo-config:
|
||||
rabbitmq-data:
|
||||
@@ -0,0 +1,38 @@
|
||||
const expected = {
|
||||
_id: "loadtest-rs",
|
||||
members: [{ _id: 0, host: "mongo:27017" }],
|
||||
};
|
||||
|
||||
let config;
|
||||
try {
|
||||
config = rs.conf();
|
||||
} catch (error) {
|
||||
if (error.code !== 94) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (config) {
|
||||
if (
|
||||
config._id !== expected._id ||
|
||||
config.members.length !== 1 ||
|
||||
config.members[0].host !== expected.members[0].host
|
||||
) {
|
||||
throw new Error("Refusing to reconfigure an unexpected replica set");
|
||||
}
|
||||
} else {
|
||||
const result = rs.initiate(expected);
|
||||
if (!result.ok) {
|
||||
throw new Error(`Replica set initialization failed: ${JSON.stringify(result)}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (let attempt = 0; attempt < 60; attempt++) {
|
||||
if (db.adminCommand({ hello: 1 }).isWritablePrimary) {
|
||||
print("Dedicated load-test replica set is writable");
|
||||
quit(0);
|
||||
}
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
throw new Error("Timed out waiting for the load-test primary");
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
CHART="${1:-kerberos/hub}"
|
||||
|
||||
assert_contains() {
|
||||
if ! grep -Eq -- "$2" <<< "$1"; then
|
||||
printf 'Missing expected deployment runtime setting: %s\n' "$2" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
nodeport="$(awk '
|
||||
/^---/ { selected=0 }
|
||||
/name: hub-frontend-nodeport$/ { selected=1 }
|
||||
selected { print }
|
||||
' "$ROOT/base/hub/kerberos-hub-nodeports.yaml")"
|
||||
assert_contains "$nodeport" 'targetPort: http$'
|
||||
assert_contains "$nodeport" 'nodePort: 32080'
|
||||
|
||||
rendered="$(helm template hub "$CHART" --values "$ROOT/base/hub/kerberos-hub-values.yaml" \
|
||||
--set mode=ui --set kerberoshub.frontend.demoEnabled=true)"
|
||||
if grep -q 'image: "docker.io/ghcr.io/' <<< "$rendered"; then
|
||||
echo "Fully qualified GHCR image was prefixed with docker.io" >&2
|
||||
exit 1
|
||||
fi
|
||||
for name in hub-frontend hub-frontend-demo; do
|
||||
deployment="$(awk -v name="$name" '
|
||||
function emit() { if (deployment && matched) printf "%s", block }
|
||||
/^---$/ { emit(); block=""; deployment=0; matched=0 }
|
||||
{ block=block $0 "\n" }
|
||||
/^kind: Deployment$/ { deployment=1 }
|
||||
$0 == " name: " name { matched=1 }
|
||||
END { emit() }
|
||||
' <<< "$rendered")"
|
||||
for setting in 'containerPort: 8080' 'runAsNonRoot: true' 'runAsUser: 65532' \
|
||||
'readOnlyRootFilesystem: true' 'mountPath: /tmp' 'name: frontend-tmp'; do
|
||||
assert_contains "$deployment" "^[[:space:]]*(- )?$setting$"
|
||||
done
|
||||
assert_contains "$deployment" 'image: "ghcr.io/uug-ai/hub-frontend:v1.19.28"$'
|
||||
echo "OK: $name uses the promoted image and matching hardened runtime"
|
||||
done
|
||||
echo "Deployment Hub runtime preflight passed."
|
||||
Reference in New Issue
Block a user