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 |
|
| 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 |
|
| 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 |
|
| 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) |
|
| Console | `minio.arcodange.lab` (Traefik) |
|
||||||
| Bucket | `kadans-videos`, **privé** — l'accès passe par des URL signées (ADR-0002 du dossier produit) |
|
| 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` |
|
| 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]
|
> [!NOTE]
|
||||||
> Sans le secret `minio-config`, le pod ne démarre pas. C'est voulu — mieux
|
> 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.
|
> 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
|
enabled: false # pas d'opérateur Prometheus ici : scrape par annotation
|
||||||
environment:
|
environment:
|
||||||
MINIO_PROMETHEUS_AUTH_TYPE: "public"
|
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:
|
tool:
|
||||||
# kind: 'SubChart' or 'HelmChart', if subchart then uncomment Chart.yaml dependency, else comment and use tool library with helm chart template
|
# 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