Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some load testing tools to the sandbox #351

Merged
merged 4 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,32 @@

# Use bullseye as build image instead of Bookworm as ubi9 does not not have GLIBCXX_3.4.30
# https://access.redhat.com/solutions/6969351
FROM --platform=${BUILDPLATFORM} rust:1.78.0-bullseye as limitador-build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this breaking cross platform builds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would it? This Dockerfile works fine on my arm mac.

Copy link
Contributor

@eguzki eguzki Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.docker.com/reference/dockerfile/#from

The optional --platform flag can be used to specify the platform of the image in case FROM references a multi-platform image. 
For example, linux/amd64, linux/arm64, or windows/amd64. By default, the target platform of the build request is used. Global build arguments can be used in the value of this flag, for example [automatic platform ARGs](https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope) 
allow you to force a stage to native build platform (--platform=$BUILDPLATFORM), and use it to cross-compile to the target platform inside the stage.

When I need to do cross-compile, I need that rust:1.78.0-bullseye be native to my current machine platform. When docker buildx build --platform=linux/amd64, without that FROM --platform=${BUILDPLATFORM} the rust:1.78.0-bullseye will be linux/amd64 and my current machine platform might be something else (like arm). Which is not correct.

Copy link
Contributor Author

@chirino chirino Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best if the plain Dockerfile just does a container build that matches the host, and then we have additional Dockerfiles to do the cross compiles like Dockerfile.aarch64.

Your saying your on arm trying to build linux/amd64 with that Dockerfile?? Shouldn't that work if the host is running QEMU?

FROM rust:1.78.0-bullseye as limitador-build

RUN apt update && apt upgrade -y \
&& apt install -y protobuf-compiler clang

WORKDIR /usr/src/limitador

ARG GITHUB_SHA
ARG CARGO_ARGS
ENV GITHUB_SHA=${GITHUB_SHA:-unknown}
ENV RUSTFLAGS="-C target-feature=-crt-static"

COPY . .
# We set the env here just to make sure that the build is invalidated if the args change
ENV CARGO_ARGS=${CARGO_ARGS}

RUN cargo build --release
# The following allows us to cache the Cargo dependency downloads with image layers
COPY Cargo.toml Cargo.lock ./
COPY limitador/Cargo.toml ./limitador/
COPY limitador-server/Cargo.toml ./limitador-server/
RUN mkdir -p limitador-server/src && echo 'fn main() {}' > limitador-server/src/main.rs
RUN cargo build --release ${CARGO_ARGS}

COPY ./limitador ./limitador
COPY ./limitador-server ./limitador-server

RUN cargo build --release ${CARGO_ARGS}

# ------------------------------------------------------------------------------
# Run Stage
Expand Down
1 change: 1 addition & 0 deletions limitador-server/sandbox/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
*.key
*.pem
*.csr
report.html
28 changes: 26 additions & 2 deletions limitador-server/sandbox/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,19 @@ deploy-redis-otel: clean ## Uses Redis to store counters, instrumented with open
deploy-disk: clean ## Uses disk to store counters
$(DOCKER) compose -f docker-compose-envoy.yaml -f docker-compose-limitador-disk.yaml up

deploy-distributed: clean ## Counters are held in Limitador (ephemeral) but replicated to other Limitador servers.
$(DOCKER) compose -f docker-compose-envoy.yaml -f docker-compose-limitador-distributed.yaml up

deploy-distributed-3-node: clean ## Counters are held in Limitador (ephemeral) but replicated to 3 other local Limitador servers.
$(DOCKER) compose -f docker-compose-envoy-3-node.yaml -f docker-compose-limitador-distributed-3-node.yaml up

##@ Helper targets

build: ## Build "limitador-testing" image
$(DOCKER) build -t limitador-testing -f ../../Dockerfile ../../
build: clean ## Build the "limitador-testing" image
$(DOCKER) compose -f docker-compose-limitador-memory.yaml build

build-all-features: clean ## Build the image "limitador-testing-all-features" image
$(DOCKER) compose -f docker-compose-limitador-distributed.yaml build

ca: ## Create CA cert
openssl genrsa -out ca.key 2048
Expand Down Expand Up @@ -88,6 +97,21 @@ $(GRPCURL):
.PHONY: grpcurl
grpcurl: $(GRPCURL) ## Download grpcurl locally if necessary.

.PHONY: ghz
ghz:
$(call go-install-tool,$(PROJECT_PATH)/bin/ghz,github.com/bojand/ghz/cmd/ghz@latest)

RPS?=1000
.PHONY: load-test
load-test: ghz
# see https://ghz.sh/docs/load for usage details
$(PROJECT_PATH)/bin/ghz 127.0.0.1:18081 --insecure \
--call envoy.service.ratelimit.v3.RateLimitService.ShouldRateLimit \
--async --concurrency=50 \
--rps=$(RPS) \
--total=$(RPS)0 \
--data-file load-test.json

# go-install-tool will 'go install' any package $2 and install it to $1.
define go-install-tool
@[ -f $(1) ] || { \
Expand Down
68 changes: 60 additions & 8 deletions limitador-server/sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,40 @@ Check out `make help` for all the targets.

### Deployment options

| Limitador's configuration | Command | Info |
| ------------- | ----- | ----- |
| In-memory configuration | `make deploy-in-memory` | Counters are held in Limitador (ephemeral) |
| Redis | `make deploy-redis` | Uses Redis to store counters |
| Redis Secured | `make deploy-redis-tls` | Uses Redis with TLS and password protected to store counters |
| Redis Cached | `make deploy-redis-cached` | Uses Redis to store counters, with an in-memory cache |
| Redis Otel Instrumented | `make deploy-redis-otel` | Uses redis to store counters, [instrumented with opentelemetry](redis-otel/README.md) |
| Disk | `make deploy-disk` | Uses disk to store counters |
| Limitador's configuration | Command | Info |
|--------------------------| ----- |----------------------------------------------------------------------------------------------------------------|
| In-memory configuration | `make deploy-in-memory` | Counters are held in Limitador (ephemeral) |
| Redis | `make deploy-redis` | Uses Redis to store counters |
| Redis Secured | `make deploy-redis-tls` | Uses Redis with TLS and password protected to store counters |
| Redis Cached | `make deploy-redis-cached` | Uses Redis to store counters, with an in-memory cache |
| Redis Otel Instrumented | `make deploy-redis-otel` | Uses redis to store counters, [instrumented with opentelemetry](redis-otel/README.md) |
| Disk | `make deploy-disk` | Uses disk to store counters |
| Distributed | `make deploy-distributed` | Counters are held in Limitador (ephemeral) but replicated to other Limitador servers. |

| Distributed 3 Node | `make deploy-distributed-3-node` | Counters are held in Limitador (ephemeral) but replicated to 3 other Limitador servers. |

### Running Multi Node Distributed Deployments

The `make deploy-distributed` target can be connected to other Limitador servers but requires you to set the `PEER_ID` and `PEER_URLS` environment variables when you run the target.
eguzki marked this conversation as resolved.
Show resolved Hide resolved

If you have 3 servers you want to replicate between, you would run the following commands:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to have 3 servers, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you might still want to do this on 3 machines if you are benchmarking. Doing it all on one would not be very representative.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I buy that


```bash
# on server where: hostname=server1
PEER_ID=`hostname` PEER_URLS="http://server2:15001 http://server3:15001" make deploy-distributed
```

```bash
# on server where: hostname=server2
PEER_ID=`hostname` PEER_URLS="http://server1:15001 http://server3:15001" make deploy-distributed
```

```bash
# on server where: hostname=server3
PEER_ID=`hostname` PEER_URLS="http://server1:15001 http://server2:15001" make deploy-distributed
```

The `PEER_ID` just need to be unique between the servers, and the `PEER_URLS` should be a space-separated list of the other servers' URLs.

### Limitador's admin HTTP endpoint

Expand Down Expand Up @@ -75,6 +101,10 @@ bin/grpcurl -plaintext -d @ 127.0.0.1:18081 envoy.service.ratelimit.v3.RateLimit
{
"key": "req.method",
"value": "POST"
},
{
"key": "req.path",
"value": "/"
}
]
}
Expand All @@ -97,6 +127,10 @@ while :; do bin/grpcurl -plaintext -d @ 127.0.0.1:18081 envoy.service.ratelimit.
{
"key": "req.method",
"value": "POST"
},
{
"key": "req.path",
"value": "/"
}
]
}
Expand All @@ -113,6 +147,24 @@ EOM
curl -i -H "Host: example.com" http://127.0.0.1:18000/get
```

### Load Testing the GRPC RateLimitService directly

This load test will use `grpcurl`. You need [Go SDK](https://golang.org/doc/install) installed.

Run a load test a 5000 requests per second (RPS) for 10 seconds:

```bash
RPS=5000 make load-test
```

### Load Testing via Envoy Proxy

```bash
cargo run --manifest-path loadtest/Cargo.toml --package loadtest --release -- --report-file=report.htm
```

The report will be saved in `report.htm` file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexsnaps see above re: how to use

### Limitador Image

By default, the sandbox will run Limitador's `limitador-testing:latest` image.
Expand Down
74 changes: 74 additions & 0 deletions limitador-server/sandbox/docker-compose-envoy-3-node.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
version: '3.8'
services:
envoy:
image: envoyproxy/envoy:v1.20-latest
depends_on:
- upstream
- limitador
command:
- /usr/local/bin/envoy
- --config-path
- /etc/envoy.yaml
- --log-level
- info
- --component-log-level
- http:debug,router:debug
- --service-cluster
- proxy
expose:
- "80"
- "8001"
ports:
- "18000:80"
- "18001:8001"
volumes:
- ./envoy.yaml:/etc/envoy.yaml
envoy2:
image: envoyproxy/envoy:v1.20-latest
depends_on:
- upstream
- limitador
command:
- /usr/local/bin/envoy
- --config-path
- /etc/envoy.yaml
- --log-level
- info
- --component-log-level
- http:debug,router:debug
- --service-cluster
- proxy
expose:
- "80"
- "8001"
ports:
- "18100:80"
- "18101:8001"
volumes:
- ./envoy.yaml:/etc/envoy.yaml
envoy3:
image: envoyproxy/envoy:v1.20-latest
depends_on:
- upstream
- limitador
command:
- /usr/local/bin/envoy
- --config-path
- /etc/envoy.yaml
- --log-level
- info
- --component-log-level
- http:debug,router:debug
- --service-cluster
- proxy
expose:
- "80"
- "8001"
ports:
- "18200:80"
- "18201:8001"
volumes:
- ./envoy.yaml:/etc/envoy.yaml
upstream:
image: kennethreitz/httpbin
1 change: 1 addition & 0 deletions limitador-server/sandbox/docker-compose-envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
image: envoyproxy/envoy:v1.20-latest
depends_on:
- upstream
- limitador
command:
- /usr/local/bin/envoy
- --config-path
Expand Down
5 changes: 3 additions & 2 deletions limitador-server/sandbox/docker-compose-limitador-disk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ version: '3.8'
services:
limitador:
image: ${LIMITADOR_IMAGE:-limitador-testing}
depends_on:
- envoy
build:
context: ../..
dockerfile: Dockerfile
command:
- limitador-server
- --rls-ip
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
version: '3.8'
services:
limitador:
image: limitador-testing-all-features
build:
context: ../..
dockerfile: Dockerfile
args:
- CARGO_ARGS=--all-features
command: |
limitador-server --rls-ip 0.0.0.0 --rls-port 8081 --http-ip 0.0.0.0 --http-port "8080"
-vv --grpc-reflection-service /opt/kuadrant/limits/limits.yaml
distributed limitador 0.0.0.0:5001 http://limitador2:5001 http://limitador3:5001
expose:
- "8080"
- "8081"
- "5001"
ports:
- "18080:8080"
- "18081:8081"
- "15001:5001"
volumes:
- ./limits.yaml:/opt/kuadrant/limits/limits.yaml
limitador2:
image: limitador-testing-all-features
build:
context: ../..
dockerfile: Dockerfile
args:
- CARGO_ARGS=--all-features
command: |
limitador-server --rls-ip 0.0.0.0 --rls-port 8081 --http-ip 0.0.0.0 --http-port "8080"
-vv --grpc-reflection-service /opt/kuadrant/limits/limits.yaml
distributed limitador2 0.0.0.0:5001 http://limitador:5001 http://limitador3:5001
expose:
- "8080"
- "8081"
- "5001"
volumes:
- ./limits.yaml:/opt/kuadrant/limits/limits.yaml
limitador3:
image: limitador-testing-all-features
build:
context: ../..
dockerfile: Dockerfile
args:
- CARGO_ARGS=--all-features
command: |
limitador-server --rls-ip 0.0.0.0 --rls-port 8081 --http-ip 0.0.0.0 --http-port "8080"
-vv --grpc-reflection-service /opt/kuadrant/limits/limits.yaml
distributed limitador3 0.0.0.0:5001 http://limitador:5001 http://limitador2:5001
expose:
- "8080"
- "8081"
- "5001"
volumes:
- ./limits.yaml:/opt/kuadrant/limits/limits.yaml
24 changes: 24 additions & 0 deletions limitador-server/sandbox/docker-compose-limitador-distributed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
version: '3.8'
services:
limitador:
image: limitador-testing-all-features
build:
context: ../..
dockerfile: Dockerfile
args:
- CARGO_ARGS=--all-features
command: |
limitador-server --rls-ip 0.0.0.0 --rls-port 8081 --http-ip 0.0.0.0 --http-port "8080"
-vv --grpc-reflection-service /opt/kuadrant/limits/limits.yaml
distributed ${PEER_ID:-node1} 0.0.0.0:5001 ${PEER_URLS:-}
expose:
- "8080"
- "8081"
- "5001"
ports:
- "18080:8080"
- "18081:8081"
- "15001:5001"
volumes:
- ./limits.yaml:/opt/kuadrant/limits/limits.yaml
5 changes: 3 additions & 2 deletions limitador-server/sandbox/docker-compose-limitador-memory.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ version: '3.8'
services:
limitador:
image: ${LIMITADOR_IMAGE:-limitador-testing}
depends_on:
- envoy
build:
eguzki marked this conversation as resolved.
Show resolved Hide resolved
context: ../..
dockerfile: Dockerfile
command:
- limitador-server
- --rls-ip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ version: '3.8'
services:
limitador:
image: ${LIMITADOR_IMAGE:-limitador-testing}
build:
context: ../..
dockerfile: Dockerfile
depends_on:
- envoy
- redis
command:
- limitador-server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ version: '3.8'
services:
limitador:
image: ${LIMITADOR_IMAGE:-limitador-testing}
build:
context: ../..
dockerfile: Dockerfile
depends_on:
- jaeger
- envoy
- redis
command:
- limitador-server
Expand Down
Loading
Loading