Compare commits

..

3 Commits

Author SHA1 Message Date
wpetit 2edd795ab8 feat: add configurable redis timeouts
Cadoles/bouncer/pipeline/pr-develop This commit looks good Details
2024-02-15 15:17:57 +01:00
wpetit 4d1ca1787c feat: generalize siege task 2024-02-15 15:17:28 +01:00
wpetit 6f61073d1f fix(k8s): redis configuration 2024-02-15 15:17:04 +01:00
19 changed files with 128 additions and 51 deletions

View File

@ -16,6 +16,9 @@ GOTEST_ARGS ?= -short
OPENWRT_DEVICE ?= 192.168.1.1 OPENWRT_DEVICE ?= 192.168.1.1
SIEGE_URLS_FILE ?= misc/siege/urls.txt
SIEGE_CONCURRENCY ?= 100
watch: tools/modd/bin/modd deps ## Watching updated files - live reload watch: tools/modd/bin/modd deps ## Watching updated files - live reload
( set -o allexport && source .env && set +o allexport && tools/modd/bin/modd ) ( set -o allexport && source .env && set +o allexport && tools/modd/bin/modd )
@ -105,7 +108,10 @@ grafterm: tools/grafterm/bin/grafterm
tools/grafterm/bin/grafterm -c ./misc/grafterm/dashboard.json -v job=bouncer-proxy -r 5s tools/grafterm/bin/grafterm -c ./misc/grafterm/dashboard.json -v job=bouncer-proxy -r 5s
siege: siege:
siege -i -c 100 -f ./misc/siege/urls.txt $(eval TMP := $(shell mktemp))
cat $(SIEGE_URLS_FILE) | envsubst > $(TMP)
siege -i -b -c $(SIEGE_CONCURRENCY) -f $(TMP)
rm -rf $(TMP)
tools/gitea-release/bin/gitea-release.sh: tools/gitea-release/bin/gitea-release.sh:
mkdir -p tools/gitea-release/bin mkdir -p tools/gitea-release/bin

View File

@ -1,5 +1,7 @@
package config package config
import "time"
const ( const (
RedisModeSimple = "simple" RedisModeSimple = "simple"
RedisModeSentinel = "sentinel" RedisModeSentinel = "sentinel"
@ -7,13 +9,19 @@ const (
) )
type RedisConfig struct { type RedisConfig struct {
Adresses InterpolatedStringSlice `yaml:"addresses"` Adresses InterpolatedStringSlice `yaml:"addresses"`
Master InterpolatedString `yaml:"master"` Master InterpolatedString `yaml:"master"`
ReadTimeout InterpolatedDuration `yaml:"readTimeout"`
WriteTimeout InterpolatedDuration `yaml:"writeTimeout"`
DialTimeout InterpolatedDuration `yaml:"dialTimeout"`
} }
func NewDefaultRedisConfig() RedisConfig { func NewDefaultRedisConfig() RedisConfig {
return RedisConfig{ return RedisConfig{
Adresses: InterpolatedStringSlice{"localhost:6379"}, Adresses: InterpolatedStringSlice{"localhost:6379"},
Master: "", Master: "",
ReadTimeout: InterpolatedDuration(30 * time.Second),
WriteTimeout: InterpolatedDuration(30 * time.Second),
DialTimeout: InterpolatedDuration(30 * time.Second),
} }
} }

View File

@ -4,7 +4,6 @@ import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"encoding/json" "encoding/json"
"io/ioutil"
"os" "os"
"github.com/btcsuite/btcd/btcutil/base58" "github.com/btcsuite/btcd/btcutil/base58"
@ -56,7 +55,7 @@ func PublicKeySet(keys ...jwk.Key) (jwk.Set, error) {
} }
func LoadOrGenerate(path string, size int) (jwk.Key, error) { func LoadOrGenerate(path string, size int) (jwk.Key, error) {
data, err := ioutil.ReadFile(path) data, err := os.ReadFile(path)
if err != nil && !errors.Is(err, os.ErrNotExist) { if err != nil && !errors.Is(err, os.ErrNotExist) {
return nil, errors.WithStack(err) return nil, errors.WithStack(err)
} }
@ -72,7 +71,7 @@ func LoadOrGenerate(path string, size int) (jwk.Key, error) {
return nil, errors.WithStack(err) return nil, errors.WithStack(err)
} }
if err := ioutil.WriteFile(path, data, 0o640); err != nil { if err := os.WriteFile(path, data, 0o640); err != nil {
return nil, errors.WithStack(err) return nil, errors.WithStack(err)
} }
} }

View File

@ -10,11 +10,7 @@ import (
) )
func NewProxyRepository(ctx context.Context, conf config.RedisConfig) (store.ProxyRepository, error) { func NewProxyRepository(ctx context.Context, conf config.RedisConfig) (store.ProxyRepository, error) {
rdb := redis.NewUniversalClient(&redis.UniversalOptions{ rdb := newRedisClient(conf)
Addrs: conf.Adresses,
MasterName: string(conf.Master),
})
return redisStore.NewProxyRepository(rdb), nil return redisStore.NewProxyRepository(rdb), nil
} }

View File

@ -8,7 +8,6 @@ import (
"forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/queue" "forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/queue"
queueRedis "forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/queue/redis" queueRedis "forge.cadoles.com/cadoles/bouncer/internal/proxy/director/layer/queue/redis"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/redis/go-redis/v9"
) )
func init() { func init() {
@ -36,10 +35,6 @@ func setupQueueLayer(conf *config.Config) (director.Layer, error) {
} }
func newQueueAdapter(redisConf config.RedisConfig) (queue.Adapter, error) { func newQueueAdapter(redisConf config.RedisConfig) (queue.Adapter, error) {
rdb := redis.NewUniversalClient(&redis.UniversalOptions{ rdb := newRedisClient(redisConf)
Addrs: redisConf.Adresses,
MasterName: string(redisConf.Master),
})
return queueRedis.NewAdapter(rdb, 2), nil return queueRedis.NewAdapter(rdb, 2), nil
} }

20
internal/setup/redis.go Normal file
View File

@ -0,0 +1,20 @@
package setup
import (
"time"
"forge.cadoles.com/cadoles/bouncer/internal/config"
"github.com/redis/go-redis/v9"
)
func newRedisClient(conf config.RedisConfig) redis.UniversalClient {
return redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: conf.Adresses,
MasterName: string(conf.Master),
ReadTimeout: time.Duration(conf.ReadTimeout),
WriteTimeout: time.Duration(conf.WriteTimeout),
DialTimeout: time.Duration(conf.DialTimeout),
RouteByLatency: true,
ContextTimeoutEnabled: true,
})
}

53
misc/k8s/README.md Normal file
View File

@ -0,0 +1,53 @@
# Kubernetes
## Getting started with Kind
1. Create your [Kind](https://kind.sigs.k8s.io/) cluster
```shell
kind create cluster --config misc/k8s/kind/bouncer-cluster.yaml
```
2. Deploy required operators
```shell
kubectl apply -k misc/k8s/kind/cluster --server-side
```
3. Deploy your Bouncer development environment
```shell
skaffold dev -p dev --cleanup=false --default-repo reg.cadoles.com/<YOUR_PERSONNAL_USER_NAME>
```
## Testing
1. Open shell in bouncer-admin pod
```shell
kubectl exec -it -n bouncer-dev bouncer-admin-<suffix> -- /bin/sh
```
2. Create an authentication token
```shell
bouncer auth create-token > .bouncer-token
```
3. Create a proxy and enable it
```shell
bouncer admin proxy create --proxy-to https://www.cadoles.com --proxy-name cadoles
bouncer admin proxy update --proxy-name cadoles --proxy-enabled=true
```
4. With you host web browser, open http://localhost:9000, you should see the Cadoles website.
## Benchmarking
You can use [`siege`](https://github.com/JoeDog/siege) to benchmark your instance with the Cadoles proxy.
```shell
BASE_URL=http://localhost:9000 make siege
```

View File

@ -0,0 +1,3 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: bouncer-dev

View File

@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://forge.cadoles.com/CadolesKube/c-kustom//base/redis?ref=develop

View File

@ -28,9 +28,9 @@ admin:
redis: redis:
addresses: addresses:
- ${REDIS_SENTINEL_HOST}:${REDIS_SENTINEL_PORT} - rfs-bouncer-redis:${RFS_BOUNCER_REDIS_SERVICE_PORT}
master: "${REDIS_MASTER_NAME}" master: mymaster
logger: logger:
level: 3 level: 2
format: human format: human

View File

@ -9,9 +9,4 @@ configMapGenerator:
- name: bouncer-admin-config - name: bouncer-admin-config
files: files:
- ./files/config.yml - ./files/config.yml
- ./files/admin-key.json - ./files/admin-key.json
- name: bouncer-admin-env
literals:
- REDIS_SENTINEL_HOST="rfs-$(REDIS_SERVICE_NAME)"
- REDIS_SENTINEL_PORT="26379"
- REDIS_MASTER_NAME="mymaster"

View File

@ -19,15 +19,9 @@ spec:
containers: containers:
- name: bouncer-admin - name: bouncer-admin
image: reg.cadoles.com/cadoles/bouncer:v2024.2.5-1602626 image: reg.cadoles.com/cadoles/bouncer:v2024.2.5-1602626
command: ["bouncer"] command: ["bouncer", "--debug", "-c", "/etc/bouncer/config.yml", "server", "admin", "run"]
args: ["--debug", "-c", "/etc/bouncer/config.yml", "server", "admin", "run"]
imagePullPolicy: Always imagePullPolicy: Always
envFrom: resources: {}
- configMapRef:
name: bouncer-admin-env
env:
- name: REDIS_SENTINEL_HOST
value: "rfs-$(REDIS_SERVICE_NAME)"
ports: ports:
- name: bouncer-admin - name: bouncer-admin
containerPort: 8081 containerPort: 8081
@ -37,4 +31,4 @@ spec:
volumes: volumes:
- name: bouncer-admin-config - name: bouncer-admin-config
configMap: configMap:
name: bouncer-admin-config name: bouncer-admin-config

View File

@ -9,6 +9,6 @@ spec:
ports: ports:
- name: bouncer-admin - name: bouncer-admin
port: 8081 port: 8081
targetPort: 8080 targetPort: bouncer-admin
selector: selector:
io.kompose.service: bouncer-admin io.kompose.service: bouncer-admin

View File

@ -14,9 +14,9 @@ layers:
redis: redis:
addresses: addresses:
- ${RFS_BOUNCER_REDIS_SERVICE_HOST}:${RFS_BOUNCER_REDIS_SERVICE_PORT} - rfs-bouncer-redis:${RFS_BOUNCER_REDIS_SERVICE_PORT}
master: "${REDIS_MASTER_NAME}" master: mymaster
logger: logger:
level: 3 level: 2
format: human format: human

View File

@ -21,6 +21,7 @@ spec:
image: reg.cadoles.com/cadoles/bouncer:v2024.2.5-1602626 image: reg.cadoles.com/cadoles/bouncer:v2024.2.5-1602626
command: ["bouncer", "-c", "/etc/bouncer/config.yml", "server", "proxy", "run"] command: ["bouncer", "-c", "/etc/bouncer/config.yml", "server", "proxy", "run"]
imagePullPolicy: Always imagePullPolicy: Always
resources: {}
ports: ports:
- name: bouncer-server - name: bouncer-server
containerPort: 8080 containerPort: 8080

View File

@ -9,6 +9,6 @@ spec:
ports: ports:
- name: bouncer-server - name: bouncer-server
port: 8080 port: 8080
targetPort: 8080 targetPort: bouncer-server
selector: selector:
io.kompose.service: bouncer-server io.kompose.service: bouncer-server

View File

@ -147,6 +147,9 @@ redis:
addresses: addresses:
- localhost:6379 - localhost:6379
master: "" master: ""
writeTimeout: 30s
readTimeout: 30s
dialTimeout: 30s
# Configuration des logs # Configuration des logs
logger: logger:

View File

@ -1,6 +1,6 @@
http://localhost:8080/blog/ ${BASE_URL}/blog/
http://localhost:8080/services/ ${BASE_URL}/services/
http://localhost:8080/ ${BASE_URL}
http://localhost:8080/recrutement/ ${BASE_URL}/recrutement/
http://localhost:8080/faq/ ${BASE_URL}/faq/
http://localhost:8080/societe/histoire/ ${BASE_URL}/societe/histoire/

View File

@ -33,8 +33,7 @@ build:
- cmd/** - cmd/**
- internal/** - internal/**
- layers/** - layers/**
- tools/** - misc/**
- data/**
docker: docker:
dockerfile: Dockerfile dockerfile: Dockerfile
@ -42,7 +41,7 @@ deploy:
statusCheckDeadlineSeconds: 600 statusCheckDeadlineSeconds: 600
portForward: portForward:
- resourceType: deployment - resourceType: service
resourceName: bouncer-admin resourceName: bouncer-admin
namespace: bouncer-dev namespace: bouncer-dev
port: 8081 port: 8081