From 15daddbe130cce4c72321b1c5a9b758473ab7c83 Mon Sep 17 00:00:00 2001 From: William Petit Date: Sat, 1 Jul 2023 11:38:16 -0600 Subject: [PATCH] feat: add multi-nodes docker-compose deployment example --- Dockerfile | 21 ++++++++-- Makefile | 2 + doc/README.md | 3 ++ misc/docker-compose/README.md | 37 +++++++++++++++++ misc/docker-compose/bouncer/admin-key.json | 1 + misc/docker-compose/bouncer/config.yml | 47 ++++++++++++++++++++++ misc/docker-compose/docker-compose.yml | 42 +++++++++++++++++++ misc/docker-compose/haproxy/haproxy.cfg | 21 ++++++++++ 8 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 misc/docker-compose/README.md create mode 100644 misc/docker-compose/bouncer/admin-key.json create mode 100644 misc/docker-compose/bouncer/config.yml create mode 100644 misc/docker-compose/docker-compose.yml create mode 100644 misc/docker-compose/haproxy/haproxy.cfg diff --git a/Dockerfile b/Dockerfile index dc57cb5..3970c7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,16 +3,30 @@ FROM golang:1.20 AS BUILD RUN apt-get update \ && apt-get install -y make +ARG YQ_VERSION=4.34.1 + +RUN mkdir -p /usr/local/bin \ + && wget -O /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_amd64 \ + && chmod +x /usr/local/bin/yq + COPY . /src WORKDIR /src RUN make GORELEASER_ARGS='build --rm-dist --single-target --snapshot' goreleaser -FROM busybox:latest AS RUNTIME +# Patch config +RUN /src/dist/bouncer_linux_amd64_v1/bouncer -c '' config dump > /src/dist/bouncer_linux_amd64_v1/config.yml \ + && yq -i '.layers.queue.templateDir = "/usr/share/bouncer/layers/queue/templates"' /src/dist/bouncer_linux_amd64_v1/config.yml \ + && yq -i '.admin.auth.privateKey = "/etc/bouncer/admin-key.json"' /src/dist/bouncer_linux_amd64_v1/config.yml \ + && yq -i '.redis.adresses = ["redis:6379"]' /src/dist/bouncer_linux_amd64_v1/config.yml + +FROM alpine:3.18 AS RUNTIME ARG DUMB_INIT_VERSION=1.2.5 +RUN apk add --no-cache ca-certificates + RUN mkdir -p /usr/local/bin \ && wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_x86_64 \ && chmod +x /usr/local/bin/dumb-init @@ -23,14 +37,13 @@ RUN mkdir -p /usr/local/bin /usr/share/bouncer/bin /etc/bouncer COPY --from=BUILD /src/dist/bouncer_linux_amd64_v1/bouncer /usr/share/bouncer/bin/bouncer COPY --from=BUILD /src/layers /usr/share/bouncer/ +COPY --from=BUILD /src/dist/bouncer_linux_amd64_v1/config.yml /etc/bouncer/config.yml -RUN ln -s /usr/share/bouncer/bin/bouncer /usr/local/bin/bouncer \ - && /usr/share/bouncer/bin/bouncer -c '' config dump > /etc/bouncer/config.yml +RUN ln -s /usr/share/bouncer/bin/bouncer /usr/local/bin/bouncer EXPOSE 8080 EXPOSE 8081 -ENV BOUNCER_WORKDIR=/usr/share/bouncer ENV BOUNCER_CONFIG=/etc/bouncer/config.yml CMD ["bouncer"] \ No newline at end of file diff --git a/Makefile b/Makefile index c34d87e..e704412 100644 --- a/Makefile +++ b/Makefile @@ -75,9 +75,11 @@ finish-release: docker-build: docker build -t $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) . + docker tag $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) $(DOCKER_IMAGE_NAME):latest docker-release: docker push $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) + docker push $(DOCKER_IMAGE_NAME):latest gitea-release: tools/gitea-release/bin/gitea-release.sh goreleaser mkdir -p .gitea-release diff --git a/doc/README.md b/doc/README.md index 38d68d7..a3a9ab8 100644 --- a/doc/README.md +++ b/doc/README.md @@ -3,6 +3,9 @@ - [(FR) - Premiers pas](./fr/getting-started.md) - [(FR) - Architecture générale](./fr/general-architecture.md) +## Exemples + +- [(FR) - Exemple de déploiement multi-noeuds](../misc/docker-compose/README.md) ## Référence - [(FR) - Layers](./fr/references/layers/README.md) diff --git a/misc/docker-compose/README.md b/misc/docker-compose/README.md new file mode 100644 index 0000000..548ec95 --- /dev/null +++ b/misc/docker-compose/README.md @@ -0,0 +1,37 @@ +# Exemple de déploiement multi-noeuds avec Docker-Compose + +Le répertoire `misc/docker-compose` contient un exemple de déploiement de Bouncer multi-noeuds avec: + +- 3 instances du service `bouncer-proxy`; +- 1 instance du service `haproxy` en frontal en charge du load-balancing; +- 1 instance du service `bouncer-admin`; +- 1 serveur Redis. + +## Prérequis + +- [Docker Compose](https://docs.docker.com/compose/) + +## Étapes + +1. Se positionner dans le répertoire puis lancer l'environnement avec la commande `docker-compose`: + + ```bash + cd misc/docker-compose + docker-compose up + ``` + +2. Entrer dans le conteneur `bouncer-admin` puis créer un jeton d'accès: + + ```bash + docker-compose exec bouncer-admin /bin/sh + bouncer auth create-token --role writer > .bouncer-token + ``` + +3. Créer un proxy via le CLI: + + ```bash + bouncer admin proxy create --proxy-name myproxy --proxy-to "https://www.cadoles.com/" + bouncer admin proxy update --proxy-name myproxy --proxy-enabled=true + ``` + +4. Via votre navigateur, accéder à l'URL http://127.0.0.1:8080. La page du site Cadoles devrait s'afficher. Dans le log de la commande `docker-compose up` vous devriez voir que les requêtes sont routées à tour de rôle sur les 3 instances de Bouncer en exécution. \ No newline at end of file diff --git a/misc/docker-compose/bouncer/admin-key.json b/misc/docker-compose/bouncer/admin-key.json new file mode 100644 index 0000000..59025df --- /dev/null +++ b/misc/docker-compose/bouncer/admin-key.json @@ -0,0 +1 @@ +{"d":"JuBw5OsGv3rPgVczxUgtJ6iUQ41LQu4Xpu-t8IKI_z8r-BZBlbndxidPmRlGZASLGL3rhY4qw6_ScFxakrMpCreO1RMU0kqtz--N48BXFnW5tEgr1voyyKP__bPssQNn6PgkoyAd11es7MEKlBff_DtGrcSkVRgU0zDZB-vIU0aNEIZPNw0icbYqc1u_QQNPpBU9cw6P33WHhzvfCVAkZKRszwznhiPM08n1vjpiA7e1kQ8a6OC4IFZBvohkmpmyOq1g1OLRABQ83YPCjGjCAejO-jEWkbLksp6rAl_YYpCvfBAjFV76JuZq4eh5IU82LsSfi3PGYBkhxWuLY779XQ","dp":"gljHOQowGK7fVn2DJizWtgRIDJuKpKnoX2PWNJUbm2WZwcEPZalAkxn7Y-w_reLVJZuRpfKEUMS-Tn3-CwI1ZjCHPqMPTXcoG0Pe2E-Z88jOs9lW4XSOASiiM980VIvkV1xCxDJkN3NsDFQ9j9kRGnKuMnsucCW3AKaU917hXNU","dq":"mqY19JcEBDnzS70_XkAsOKqPzemOScax66b-4N6zrsgeLVlRjHffY9uCAgBWzlxOidRdQN8q23ZJB4fqsKB2w00Iw7Jxx94IoAKGjKDT5iB48Y_kdKLAwSHRTXsqA9GG3po_H_JpP_EqX4TDBYtqQZuBD_tACP9HbLYMi_V2YU8","e":"AQAB","kty":"RSA","n":"sam0X0BGcuFwX8z3Wde8cv2o_zl6A9ghpkT0tCjw8qH3GNWrbAqzncSWdHBzoChBgAbuTOVs-ixYC0KeUhwFdc8Ul-jmKJWFaS8kIr3y4EH62-vLgMuIKfaxbsyUG6KMkJfnftge1jPO4ccddNej9msxcqTxu37dcgstutwtd6QkS9p5RrNbDBc8-Z7SQ4TuxJfP8msXRnCPJ-I44yszGdQF1Np2DXakJHVn8PBrDh3iSFwORw8jxNS4oS0OlBl5aSc0t5XkkaNcSU2a50SKts290w54fl6MPJ1sLnnznLy4uu37-nrfEUvqRLDZL9B1F82RM1dtLIIiN4gnSrMlpQ","p":"wOmFPhAT_wXWzMuwtEdYIer3-CiOWxFKpFL09eEJkJ29MIUchEaoiJaUAghqPxM48llfOVaUaLbFVxmo5U3fyjNMaP-nHMUBwojutykMK-gC2R3J4bQgFWfKbGSL7M7UsextAvpq9iiOuR0LNE-xTfCgPIxHVdPZskO3yx0DkjM","q":"68OGRb0tLRjb_PpkGctcSjEz_vvcyjzxGL-fn4_h4GCw98Xrj6Y4rZ4lfWWRSeDohSvdd-ICSlxvxkQOIOcA0H7jyJcBC0KDs4hX5BRGJNDri3QX0ry4_F1ptAdbfiFgQGqCfMRCr7L60Tfd_6tLczvny7eEBKQNGdj6dLfhgMc","qi":"DFwixyxUDf0REPLLa8hOKieRL95_AH9rbYWzStBOdSjKWra5l0reD6a4bbvAYvl0e8qCcRI6S8Nzpz0BYm4sJL7poVOnjxqvBY3Q9Ppf4Mq8lW39pOCJcqOHIvvYHsMjTC5uwp7Yg2p0GvxuUibbyNL1PXf6WZ_szVP_oSMrCXA"} \ No newline at end of file diff --git a/misc/docker-compose/bouncer/config.yml b/misc/docker-compose/bouncer/config.yml new file mode 100644 index 0000000..0c6e787 --- /dev/null +++ b/misc/docker-compose/bouncer/config.yml @@ -0,0 +1,47 @@ +admin: + http: + host: 127.0.0.1 + port: 8081 + cors: + allowedOrigins: + - http://localhost:3001 + allowCredentials: true + allowMethods: + - POST + - GET + - PUT + - DELETE + allowedHeaders: + - Origin + - Accept + - Content-Type + - Authorization + - Sentry-Trace + debug: false + auth: + issuer: http://127.0.0.1:8081 + privateKey: /etc/bouncer/admin-key.json + metrics: + enabled: true + endpoint: /.bouncer/metrics + basicAuth: null +proxy: + http: + host: 0.0.0.0 + port: 8080 + metrics: + enabled: true + endpoint: /.bouncer/metrics + basicAuth: null + +redis: + addresses: + - redis:6379 + master: "" +logger: + level: 1 + format: human +layers: + queue: + templateDir: /usr/share/bouncer/layers/queue/templates + defaultKeepAlive: 1m0s diff --git a/misc/docker-compose/docker-compose.yml b/misc/docker-compose/docker-compose.yml new file mode 100644 index 0000000..235c941 --- /dev/null +++ b/misc/docker-compose/docker-compose.yml @@ -0,0 +1,42 @@ +version: "2" +services: + haproxy: + image: reg.cadoles.com/proxy_cache/library/haproxy:2.7-alpine + ports: + - 8080:8080 + links: + - bouncer-proxy-1 + - bouncer-proxy-2 + - bouncer-proxy-3 + volumes: + - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg + + bouncer-admin: + image: reg.cadoles.com/cadoles/bouncer:latest + command: bouncer -c /etc/bouncer/config.yml server admin run + links: + - redis + volumes: + - ./bouncer/config.yml:/etc/bouncer/config.yml + - ./bouncer/admin-key.json:/etc/bouncer/admin-key.json + + bouncer-proxy-1: &bouncer-proxy + image: reg.cadoles.com/cadoles/bouncer:latest + command: bouncer -c /etc/bouncer/config.yml server proxy run + links: + - redis + volumes: + - ./bouncer/config.yml:/etc/bouncer/config.yml + - ./bouncer/admin-key.json:/etc/bouncer/admin-key.json + + bouncer-proxy-2: *bouncer-proxy + bouncer-proxy-3: *bouncer-proxy + + redis: + image: reg.cadoles.com/proxy_cache/library/redis:7-alpine + command: redis-server --save 60 1 --loglevel verbose + volumes: + - redis-data:/data + +volumes: + redis-data: \ No newline at end of file diff --git a/misc/docker-compose/haproxy/haproxy.cfg b/misc/docker-compose/haproxy/haproxy.cfg new file mode 100644 index 0000000..9da199f --- /dev/null +++ b/misc/docker-compose/haproxy/haproxy.cfg @@ -0,0 +1,21 @@ +global + maxconn 100 + log stdout format raw local0 info + +defaults + mode http + timeout client 30s + timeout server 30s + timeout connect 30s + log global + option httplog + +frontend proxy + bind *:8080 + default_backend bouncer-proxy + +backend bouncer-proxy + mode http + server bouncer-proxy-1 bouncer-proxy-1:8080 check + server bouncer-proxy-2 bouncer-proxy-2:8080 check + server bouncer-proxy-3 bouncer-proxy-3:8080 check