Cache amont : déploiements à bande passante limitée et air-gap¶
Repod peut servir de cache transparent en pull-through devant les dépôts
amont publics APT/RPM/APK (Ubuntu, Debian, AlmaLinux, EPEL, Alpine…).
Les machines clientes pointent leurs fichiers sources.list/.repo vers
Repod au lieu du vrai miroir amont ; la première requête pour un fichier
donné est récupérée puis mise en cache, chaque requête suivante est servie
localement. Ce guide couvre :
- Ce qu'est le cache amont (et ce qu'il n'est pas)
- Ajouter une cible de cache
- Sites à bande passante limitée (cache à la demande)
- Sites entièrement air-gap (amorçage via un hôte relais)
- Vérifier que le cache fonctionne réellement
- Rétention, purge et dimensionnement disque
1. Ce qu'est le cache amont (et ce qu'il n'est pas)¶
Le cache amont n'est pas la même chose que l'import de paquets dans
votre dépôt Repod (page Import / synchronisation planifiée mirror). La
différence compte :
| Cache amont | Import / miroir | |
|---|---|---|
| Ce qui est servi | Fichiers amont, à l'octet près, signature GPG de l'amont | Paquets validés par Repod, signature GPG de Repod |
| Validation | Aucune — c'est un relais, pas une porte de contrôle | Pipeline complet (ClamAV, CVE Grype, vérification des dépendances) |
| Ce que voit un client | Le vrai dépôt amont, juste plus rapide/en cache local | Une distribution Repod curatée |
| Déclencheur | Toute requête de n'importe quel client (pull-through) | Import explicite, ou synchronisation planifiée de sources sélectionnées |
| Cas d'usage | Bande passante / disponibilité / air-gap | Curation sécurité, application de la politique CVE |
Utilisez le cache amont quand vous voulez qu'un apt-get install
n-importe-quoi-venant-d-ubuntu fonctionne sans que chaque machine
n'accède à internet. Utilisez Import/miroir quand vous voulez des paquets
validés et scannés CVE avant qu'ils n'atterrissent dans votre dépôt. Les
deux sont indépendants et peuvent être utilisés ensemble.
2. Ajouter une cible de cache¶
Dans l'interface : Cache upstream (barre latérale gauche, sous « Dépôt ») → Ajouter une cible. Ou via l'API (jeton admin requis) :
curl -X POST https://repod.example.com/api/v1/upstream-cache/targets \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"id": "ubuntu-jammy",
"label": "Ubuntu 22.04 (jammy)",
"format": "apt",
"base_url": "http://archive.ubuntu.com/ubuntu",
"max_size_gb": 20,
"inactive_days": 30
}'
Ceci crée un proxy à http://repod-host:8090/upstream/apt/ubuntu-jammy/
(port 8090 par défaut — voir UPSTREAM_CACHE_PORT dans .env — dédié au
service depot-cache, distinct du dépôt APT régulier sur le port :80).
Pointez les clients vers ce proxy exactement comme ils le feraient vers le vrai miroir :
# /etc/apt/sources.list.d/repod-cache.list
deb http://repod-host:8090/upstream/apt/ubuntu-jammy jammy main restricted universe multiverse
deb http://repod-host:8090/upstream/apt/ubuntu-jammy jammy-updates main restricted universe multiverse
deb http://repod-host:8090/upstream/apt/ubuntu-jammy jammy-security main restricted universe multiverse
Pour RPM (fichier .repo) :
[repod-almalinux9-baseos]
name=AlmaLinux 9 BaseOS (cached via repod)
baseurl=http://repod-host:8090/upstream/rpm/almalinux9-baseos
gpgcheck=1
gpgkey=https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9
gpgcheck/gpgkey pointent toujours vers la clé propre de l'amont — le
cache ne re-signe rien, donc la vérification de signature des paquets côté
client fonctionne exactement comme face au vrai miroir.
3. Sites à bande passante limitée (cache à la demande)¶
Aucune étape supplémentaire nécessaire — c'est le mode par défaut. La
première machine de votre parc à faire apt-get install/dnf install
d'un paquet donné paie le coût de la récupération depuis l'amont ; chaque
autre machine (et chaque réinstallation, par ex. la ré-imagerie d'une
machine) l'obtient instantanément depuis le cache local. Seuls les paquets
réellement utilisés par votre parc sont mis en cache — pas tout le
catalogue amont — donc l'utilisation disque reste proportionnelle à
l'empreinte réelle de votre parc (voir §6).
4. Sites entièrement air-gap (amorçage via un hôte relais)¶
Si l'instance Repod n'a aucun accès internet, le cache à la demande ne
peut pas s'auto-amorcer — il n'y a pas d'amont à joindre lors d'un
échec de cache. Le flux pris en charge utilise un hôte relais :
n'importe quelle machine avec accès internet capable de faire tourner le
même conteneur depot-cache.
Étape 1 — monter le cache sur l'hôte relais¶
Sur le relais connecté à internet (pas besoin d'une installation Repod complète — juste la brique cache) :
git clone <your-repod-repo> && cd repod
docker build -f Dockerfile.cache-nginx -t repod-cache .
mkdir -p ./repos/upstream-cache/{conf/zones,conf/locations,data}
docker run -d --name depot-cache -p 8090:80 \
-v "$(pwd)/repos/upstream-cache:/repos/upstream-cache" \
-v "$(pwd)/nginx/upstream-cache.conf:/etc/nginx/conf.d/upstream-cache.conf:ro" \
repod-cache
Puis écrivez la même configuration de cible que l'API aurait générée (ou faites tourner un backend Repod jetable pointant vers la configuration de ce relais — le plus simple est de réutiliser l'API si vous disposez d'une instance Repod, même temporaire, joignable depuis le relais) :
curl -X POST http://localhost:8000/api/v1/upstream-cache/targets \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"id":"ubuntu-jammy","label":"Ubuntu 22.04","format":"apt",
"base_url":"http://archive.ubuntu.com/ubuntu","max_size_gb":20,"inactive_days":30}'
Étape 2 — chauffer le cache¶
Pointez les vrais outils clients vers le cache du relais et exécutez votre
flux normal de mise à jour/installation — c'est la vraie chaîne d'outils
(apt-get/dnf), aucun téléchargeur de liste de paquets sur mesure
n'est nécessaire :
# Sur une machine de test pointant vers le relais :
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|http://relay-host:8090/upstream/apt/ubuntu-jammy|' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y --download-only $(dpkg-query -W -f='${Package} ') # ou votre liste de paquets connue
Répétez pour chaque distribution/version/ensemble de paquets dont votre parc air-gap a réellement besoin. Le cache contient désormais chaque fichier touché par ces commandes.
Étape 3 — exporter et transférer¶
Déplacez la clé USB (ou tout support de transfert hors-ligne autorisé par votre politique de sécurité) vers le site air-gap.
Étape 4 — importer sur le site air-gap¶
L'instance Repod air-gap doit déjà avoir la même cible configurée
(même id), créée via l'API/l'interface exactement comme au
§2 (cette étape n'écrit que la
configuration, aucun appel réseau n'est effectué avant qu'un client ne
demande réellement un paquet) :
Aucun redémarrage n'est requis — les fichiers importés sont pris en compte dès la prochaine requête. Les clients du réseau air-gap obtiennent désormais des hits de cache pour tout ce qui a été chauffé sur le relais, sans aucun accès internet requis.
Maintenir le cache à jour¶
Répétez les étapes 2 à 4 périodiquement (par ex. mensuellement) sur le
relais pour récupérer les mises à jour de sécurité, puis ré-exportez/
ré-importez uniquement le delta — tar n'a naturellement besoin de
déplacer que ce qui a changé si vous gardez le répertoire de cache du
relais persistant entre les cycles de chauffe (ne relancez pas docker
run avec un volume vide à chaque fois).
5. Vérifier que le cache fonctionne réellement¶
Chaque réponse porte un en-tête X-Repod-Cache :
curl -sI http://repod-host:8090/upstream/apt/ubuntu-jammy/dists/jammy/InRelease | grep X-Repod-Cache
MISS— récupéré depuis l'amont à l'instant (première requête pour ce chemin, ou dépassement du TTL).HIT— servi depuis le cache local, aucun contact avec l'amont.STALE— l'amont était injoignable, mais une copie précédemment mise en cache a quand même été servie (c'est la garantie de résilience : un paquet en cache n'est jamais bloqué par une panne de l'amont).
Pour confirmer la résilience sans attendre une vraie panne, bloquez la
route du conteneur vers l'hôte amont (par ex. via iptables sur l'hôte
Docker, ou en éditant temporairement /etc/hosts dans le conteneur avant
redémarrage) et redemandez un chemin déjà en cache — vous devriez toujours
obtenir un 200 et X-Repod-Cache: HIT ou STALE, jamais un blocage ou
un 5xx pour un contenu déjà mis en cache.
6. Rétention, purge et dimensionnement disque¶
Chaque cible a ses propres réglages max_size_gb et inactive_days
(modifiables depuis la page Cache upstream ou PATCH
/upstream-cache/targets/{id} — note : seul enabled est actuellement
modifiable via l'API ; pour changer la taille/rétention, retirez et
rajoutez la cible). Nginx évince les entrées les moins récemment utilisées
une fois max_size_gb atteint, et abandonne tout ce qui n'a pas été
touché depuis inactive_days.
Recommandations de dimensionnement :
- Cache à la demande, une version de distribution, de quelques centaines à ~2000 machines similaires : typiquement 5 à 30 Go — proportionnel à l'empreinte réellement installée de votre parc, pas au catalogue amont complet.
- Un miroir amont complet (main+universe+multiverse, tous les pockets)
ferait des centaines de Go à quelques To — le cache amont ne fait
délibérément pas cela ; utilisez
mirror_daily(page Import → synchronisation planifiée) si vous avez spécifiquement besoin d'un miroir local complet et validé.
La purge (page Cache upstream → Purger, ou POST
/upstream-cache/targets/{id}/purge) vide le cache sur disque d'une cible
sans toucher à sa configuration — la prochaine requête pour un chemin
précédemment en cache devient un MISS frais. Utilisez cette action après
un doute d'empoisonnement du cache amont, ou simplement pour récupérer de
l'espace disque.