feat(minio) — exposer l'API S3 en HTTPS public (s3.arcodange.fr) + CORS de la PWA #20
+41
-1
@@ -23,7 +23,7 @@ application vivent avec cette application.
|
||||
| Mode | **standalone** (1 réplique) — la donnée est dérivée et Longhorn réplique déjà le volume ; l'erasure coding distribué coûterait de la RAM que des Pi 5 n'ont pas à dépenser pour ça |
|
||||
| Volume | **50 Gi** sur `longhorn` ≈ **250 h de cours** au palier « travail ». ⚠ Longhorn réplique : compter **×3** sur la capacité du cluster avant d'augmenter |
|
||||
| Ressources | requests 512 Mi / 100 m · limit 2 Gi — la limite protège les voisins de `tools`, pas MinIO |
|
||||
| API S3 | `s3.arcodange.lab` (Traefik) |
|
||||
| API S3 | `s3.arcodange.lab` (interne) **et `s3.arcodange.fr`** (public, tunnel Cloudflare → entrypoint `web` + crowdsec) — voir « Pourquoi une exposition publique » |
|
||||
| Console | `minio.arcodange.lab` (Traefik) |
|
||||
| Bucket | `kadans-videos`, **privé** — l'accès passe par des URL signées (ADR-0002 du dossier produit) |
|
||||
| Identifiants | **jamais dans le dépôt** : `iac/` les génère dans Vault (`kvv2/minio/config`), le Vault Secrets Operator les matérialise en secret `minio-config`, le chart les lit via `existingSecret` |
|
||||
@@ -52,3 +52,43 @@ L'ordre compte, et il compte **deux fois** :
|
||||
> [!NOTE]
|
||||
> Sans le secret `minio-config`, le pod ne démarre pas. C'est voulu — mieux
|
||||
> vaut un pod en attente qu'un MinIO ouvert avec des identifiants par défaut.
|
||||
|
||||
|
||||
## Pourquoi une exposition publique (`s3.arcodange.fr`)
|
||||
|
||||
La PWA Kadans est servie en `https://kadans.arcodange.fr` et téléverse ses vidéos
|
||||
**directement** vers MinIO, avec des URL présignées émises par kadans-api
|
||||
(kadans-api#23) : les octets ne passent jamais par l'API.
|
||||
|
||||
Deux raisons rendent le `.lab` inutilisable pour ça, et ce sont des faits du
|
||||
navigateur, pas des préférences :
|
||||
|
||||
1. **Contenu mixte** — une page servie en `https` ne peut pas émettre une requête
|
||||
vers `http://`. L'ingress `.lab` est en entrypoint `web` sans TLS.
|
||||
2. **`.lab` n'est pas résolvable hors du LAN** — la synchronisation ne marcherait
|
||||
qu'à la maison, ce qui vide de son sens « retrouver mes vidéos sur mon autre
|
||||
appareil ».
|
||||
|
||||
**Pas de basic-auth** sur cet ingress, contrairement à `kadans-public` : une
|
||||
requête S3 porte sa propre signature (SigV4). Un défi HTTP Basic casserait le PUT
|
||||
présigné, auquel le navigateur ne peut pas répondre. L'autorisation vient de
|
||||
l'URL signée et de sa durée de vie courte (15 min pour déposer, 1 h pour lire).
|
||||
|
||||
**CORS** (`MINIO_API_CORS_ALLOW_ORIGIN`) liste les origines EXACTES de la PWA —
|
||||
jamais `*` : une URL présignée qui fuiterait serait sinon rejouable depuis
|
||||
n'importe quel site.
|
||||
|
||||
### ⚠ À vérifier avant de s'y fier : la taille maximale d'une requête
|
||||
|
||||
Le trafic public passe par un **tunnel Cloudflare**. Les offres gratuites de
|
||||
Cloudflare plafonnent la taille du corps d'une requête proxifiée (de l'ordre de
|
||||
**100 Mo**) — ce plafond n'a **pas** été mesuré ici, il doit l'être avec un vrai
|
||||
téléversement avant d'annoncer une limite aux utilisateurs.
|
||||
|
||||
Ce qu'on sait, en revanche, et qui rend le sujet peu urgent : sur le corpus réel
|
||||
du fondateur (707 vidéos, ~2 ans), **la durée moyenne est de 53 secondes** et
|
||||
**deux vidéos seulement dépassent 5 minutes**. Au palier « travail » de l'ADR-018
|
||||
(360p ≈ 3,4 Mo/min), 100 Mo représentent ~29 minutes de cours : le corpus entier
|
||||
passe très largement. Si la limite se confirme, le plafond de 200 Mio annoncé
|
||||
côté API mérite d'être ramené sous celle du tunnel — mieux vaut refuser tôt, avec
|
||||
une phrase claire, qu'échouer au milieu d'un téléversement.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Exposition PUBLIQUE s3.arcodange.fr, EN PLUS du .lab interne (qui reste
|
||||
# inchangé). Même motif que `grafana/templates/ingress-public.yaml` : entrypoint
|
||||
# `web` — le TLS est terminé en amont par le tunnel Cloudflare (wildcard
|
||||
# *.arcodange.fr → traefik.kube-system.svc:80) — et middleware crowdsec.
|
||||
#
|
||||
# POURQUOI c'est nécessaire (et pas un confort) : la PWA est servie en
|
||||
# https://kadans.arcodange.fr. Un navigateur REFUSE une requête vers http://
|
||||
# depuis une page https (contenu mixte), et `.lab` n'est de toute façon pas
|
||||
# résolvable hors du LAN. Sans cet ingress, le téléversement d'une vidéo ne peut
|
||||
# marcher NI en déplacement, NI même à la maison — c'est le maillon qui manque
|
||||
# à kadans-api#23 (URL présignées).
|
||||
#
|
||||
# ⚠ PAS de basic-auth ici, contrairement à kadans-public : une requête S3 porte
|
||||
# sa propre signature (SigV4) dans ses en-têtes ou son URL. Un défi HTTP Basic
|
||||
# casserait le PUT présigné du navigateur, qui n'a aucun moyen d'y répondre.
|
||||
# L'autorisation vient de l'URL signée, avec sa durée de vie courte.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio-public
|
||||
namespace: tools
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: kube-system-crowdsec@kubernetescrd
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: s3.arcodange.fr
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio
|
||||
port:
|
||||
number: 9000
|
||||
@@ -74,6 +74,14 @@ minio: &minio_config
|
||||
enabled: false # pas d'opérateur Prometheus ici : scrape par annotation
|
||||
environment:
|
||||
MINIO_PROMETHEUS_AUTH_TYPE: "public"
|
||||
# CORS : le navigateur téléverse DIRECTEMENT vers MinIO depuis la PWA (URL
|
||||
# présignées, kadans-api#23) — donc requête inter-origines, donc préflight
|
||||
# OPTIONS. Sans cette liste, le PUT est refusé par le navigateur avant même
|
||||
# de partir. Origines EXACTES, jamais « * » : une URL présignée qui fuite
|
||||
# serait rejouable depuis n'importe quel site.
|
||||
# .fr = la PWA publique (le cas réel, en déplacement comme à la maison)
|
||||
# .lab = la même app servie en interne, pour la mise au point
|
||||
MINIO_API_CORS_ALLOW_ORIGIN: "https://kadans.arcodange.fr,https://kadans.arcodange.lab"
|
||||
|
||||
tool:
|
||||
# kind: 'SubChart' or 'HelmChart', if subchart then uncomment Chart.yaml dependency, else comment and use tool library with helm chart template
|
||||
|
||||
Reference in New Issue
Block a user