Déploiement en environnement isolé (Air Gap)
Déployez Scrydon dans des environnements déconnectés à l'aide de Zarf
Utilisez ce guide si votre cluster Kubernetes n'a pas accès à Internet en sortie — par exemple, des réseaux gouvernementaux classifiés, des environnements industriels isolés ou des environnements soumis à des exigences de conformité strictes. Si votre cluster peut accéder à Internet, consultez Helm à la place.
Qu'est-ce que Zarf ?
Zarf est un outil open source (Apache 2.0) conçu pour livrer des applications Kubernetes dans des environnements déconnectés. Scrydon livre toutes les images de conteneurs, le chart Helm et ses valeurs dans une seule archive .tar.zst autonome, que vous pouvez transférer physiquement (USB, DVD, passerelle inter-domaines) ou via une diode de données unidirectionnelle.
| Capacité | Prise en charge par Zarf |
|---|---|
| Chargement des images | Pousse chaque image du paquet dans un registre interne au cluster |
| Réécriture des références d'images | Un webhook de mutation réécrit les références — aucune surcharge de imageRegistry n'est nécessaire |
| Gestion du registre | Zarf déploie et gère le registre interne au cluster |
| SBOM | Intégré (Syft, avec visualiseur) |
Vous n'avez besoin ni de Harbor, ni d'Artifactory, ni d'aucun registre externe. Le paquet contient toute la pile, y compris les six images Dapr (cinq composants du plan de contrôle et le sidecar daprd injecté) et l'image Valkey du backbone d'événements.
Prérequis
- Un cluster Kubernetes 1.28+ sans accès sortant.
- Une implémentation de la Gateway API. La périphérie du chart est une
Gatewayavec desHTTPRoute, et un cluster standard n'a ni les CRDgateway.networking.k8s.ioni de contrôleur. Installez-en un depuis votre propre miroir avant le déploiement, ou activez le Traefik intégré au chart (traefik.enabled: true) en important ses images avec le paquet. - Un moyen d'émettre le certificat d'entrée. Let's Encrypt ne peut pas joindre un réseau isolé. Faites pointer la variable
TLS_ISSUERvers unClusterIssuercert-manager adossé à votre autorité de certification interne, ou créez vous-même le Secrettls-frontdoor— voir Certificats. - La CLI
zarf— un binaire statique unique disponible sur zarf.dev, que vous transférez avec le paquet. - Votre fichier de licence (
{ "jwt": "…", "publicKey": "…" }), reçu par un canal sécurisé. Voir Licences.
L'isolation d'exécution est livrée, pas activée. Le paquet contient le Runtime Plane et ses images de charge de travail, mais la surcouche air gap garde runtimePlane.enabled: false tant que votre cible n'a pas prouvé une RuntimeClass Kata/KVM planifiable, l'accès au registre et au DNS internes, l'admission des charges de travail, une egress gouvernée et un nettoyage avec la release importée. Des images livrées ne prouvent pas à elles seules une microVM.
Étape 1 : récupérer et vérifier, sur une machine connectée
La vérification de signature a besoin du journal de transparence public de Sigstore : faites-la avant que le paquet ne franchisse l'isolement.
# Le paquet lui-même
zarf package pull oci://ghcr.io/scrydon/scrydon:<version>
# → zarf-package-scrydon-amd64-<version>.tar.zstDepuis les fichiers de la release (ou auprès de votre contact commercial), récupérez le fichier de signature du paquet — le même nom suivi de .bundle — ainsi que SHA256SUMS, et SHA256SUMS.asc lorsqu'il est publié. La release signe le paquet avec le mode sans clé de Cosign ; vérifiez-le contre l'identité du workflow de release :
PKG=zarf-package-scrydon-amd64-<version>.tar.zst
cosign verify-blob "${PKG}" \
--bundle "${PKG}.bundle" \
--certificate-identity-regexp '^https://github.com/scrydon/main/\.github/workflows/release-platform\.yml@' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com'
# Verified OKUn échec signifie ne pas déployer — voir Vérification de la chaîne d'approvisionnement.
Transférez le paquet, SHA256SUMS et le binaire zarf de l'autre côté. L'archive est un fichier tar standard, accepté par la plupart des passerelles inter-domaines.
Étape 2 : contrôler la somme de contrôle, à l'intérieur
sha256sum -c SHA256SUMS --ignore-missing
# zarf-package-scrydon-amd64-<version>.tar.zst: OKCela prouve que le fichier est bien celui que vous avez vérifié côté connecté. Pour lister chaque composant et sa licence, extrayez le SBOM ; il contient un visualiseur HTML :
zarf package inspect sbom zarf-package-scrydon-amd64-<version>.tar.zst --output ./sbomÉtape 3 : déployer
zarf package deploy zarf-package-scrydon-amd64-<version>.tar.zst --confirm \
--set-variables DOMAIN=app.example.gov \
--set-variables TLS_ISSUER=internal-caLe paquet déclare trois variables de déploiement. Ce sont les seules valeurs modifiables au déploiement ; tout le reste provient de la surcouche air gap du chart.
| Variable | Valeur du chart | Défaut | À régler sur |
|---|---|---|---|
DOMAIN | routing.host | app.scrydon.com | Le nom d'hôte ouvert par les utilisateurs. Toujours à définir. |
TLS_ISSUER | gateway.tls.clusterIssuer | letsencrypt-prod | Votre ClusterIssuer d'autorité interne. |
LICENSE_MODE | license.mode | offline | Laissez-la. online exige une route vers license.scrydon.com. |
Zarf ensuite :
- Crée un registre OCI interne au cluster, s'il n'en existe pas encore.
- Y pousse chaque image de l'archive.
- Installe un webhook de mutation qui redirige les références d'images vers ce registre.
- Exécute
helm installavec le chart et les valeurs du paquet. - Attend le déploiement d'
api-platform.
Le chart exécute au passage ses Jobs d'amorçage des bases — auth-bootstrap et events-bootstrap — et api-platform attend leur schéma avant de passer Ready. Le mot de passe Valkey géré est généré à la première installation et réutilisé depuis son Secret lors des mises à niveau.
L'installateur guidé exécute ce même déploiement pour vous : bash setup.sh --location airgap --package <fichier> --host app.example.gov --tls-issuer internal-ca. Il vérifie votre licence hors ligne contre la clé de signature épinglée dans l'installateur, exécute le contrôle préalable du cluster et transmet DOMAIN et TLS_ISSUER à Zarf. Avant le déploiement, il compare le paquet au fichier SHA256SUMS du même répertoire et refuse un fichier qui ne correspond pas. Sans SHA256SUMS, il affiche un avertissement et continue : transportez-le avec le paquet. La somme de contrôle prouve seulement que le fichier n'a pas changé depuis le côté connecté : la vérification de signature de l'étape 1 doit toujours s'y faire, car elle a besoin du journal de transparence public.
Étape 4 : saisir la licence
La licence ne fait pas partie du paquet. Ouvrez https://<DOMAIN>/platform/setup et collez ou déposez votre fichier de licence à l'étape 1 de l'assistant. L'assistant affiche les claims et, à l'étape 2, le serveur vérifie le JWT à l'aide des clés de signature Scrydon intégrées à la version avant de l'enregistrer dans la base de données de la plateforme. Le champ publicKey du fichier n'est pas enregistré et ne décide jamais de la confiance. Il n'y a aucun Secret Kubernetes à gérer ; les renouvellements passent ensuite par Paramètres → Organisation → Licence.
Étape 5 : vérifier le déploiement
La disposition par défaut place tous les services dans scrydon-platform.
kubectl get pods -n scrydon-platform # Running, 2/2 avec le sidecar Dapr
kubectl get gatewayclass # ACCEPTED=True pour gateway.className
kubectl get gateway -n scrydon-platform # PROGRAMMED=True
kubectl get httproute -A # une par application activée
kubectl get certificate -n scrydon-platform # READY=True| Symptôme | À examiner |
|---|---|
Les pods restent en 1/1 | L'injection Dapr a échoué : kubectl get pod -A -l app=dapr-sidecar-injector. |
Un pod reste bloqué en Init:0/1 | wait-for-db n'est pas terminé : kubectl get pod -n scrydon-platform -l app=db. |
api-platform attend dans wait-for-events-schema | kubectl get job -A -l app=events-bootstrap, et la base events si vous apportez votre propre PostgreSQL. |
| Le certificat ne passe jamais Ready | TLS_ISSUER désigne un émetteur inexistant, ou pointe encore vers Let's Encrypt. |
Un listener indique Accepted=False reason=PortUnavailable | gateway.listenerPorts.* ne correspond à aucun port écouté par votre contrôleur. Traefik écoute :8000/:8443 dans le conteneur, ce qui est la valeur par défaut du chart. |
Alternative : votre propre registre privé, sans Zarf
Si vous exploitez déjà un registre interne (Harbor, Artifactory, un ACR client), passez Zarf et installez directement le chart. Importez chaque image tirée par le chart, puis définissez les deux valeurs de registre :
helm install scrydon ./helm/scrydon \
-f helm/scrydon/values.yaml \
-f helm/scrydon/values.airgapped.yaml \
--set global.imageRegistry=harbor.internal \
--set dapr.global.registry=harbor.internal/daprglobal.imageRegistry couvre chaque image gérée par le chart. dapr.global.registry couvre les cinq images du plan de contrôle Dapr et le sidecar daprd injecté, qui proviennent du sous-chart Dapr et ne voient pas le global du parent. Oublier la seconde n'est pas un échec partiel : l'injecteur ne passe jamais Ready, ou les pods applicatifs ne peuvent pas démarrer leur sidecar. helm install avertit lorsqu'une seule est définie.
Ce chemin permet aussi de régler n'importe quelle valeur du chart — routage, base de données BYO, StarRocks, planification, allègements pour petites ressources — et de pré-remplir la licence avec auth.secrets.LICENSE (le champ jwt du fichier ; il n'y a pas de valeur de clé publique). Voir la référence Helm.
Pour lister les images exactes de la version déployée :
helm template scrydon ./helm/scrydon \
-f helm/scrydon/values.yaml -f helm/scrydon/values.airgapped.yaml \
| grep -oE 'image: .*' | sed 's/image: //' | tr -d '"' | sort -uUne image tierce peut provenir d'un autre chemin grâce à sa clé registry propre (infra.starrocks.image.registry, opa.image.registry, …).
GitOps et rendu hors ligne des manifestes
Tout ce qui rend le chart avec helm template au lieu de l'installer en direct — le moteur de rendu par défaut d'ArgoCD, l'inflateur Helm de Kustomize, un pipeline helm template | kubectl apply à travers l'isolement — doit définir global.requireExplicitSecrets: true et fournir le jeu de secrets de values.gitops.example.yaml.
Sans connexion à l'API, le lookup de Helm ne renvoie rien : chaque secret géré par le chart est régénéré à chaque rendu — y compris la clé maîtresse crypto de Dapr, ce qui rend indéchiffrable chaque secret stocké. Avec l'option activée, une valeur manquante fait échouer le rendu en nommant son chemin. Détails : Rendu sans cluster actif.
zarf package deploy, un helm install direct et le HelmRelease de Flux exécutent tous un vrai helm upgrade --install et n'ont besoin de rien de tout cela.
Considérations de sécurité
- Aucune information d'identification ni rappel en périphérie. Un filtre
RequestHeaderModifierstandard retire les en-têtes d'identité Dapr et on-behalf-of de chaque requête externe, et la redirection HTTP→HTTPS est un filtreRequestRedirectstandard. Les deux s'appliquent à chaque route, sans annotation propre à un contrôleur qui pourrait échouer silencieusement. - Licence hors ligne. La validation de licence n'effectue aucun appel sortant ; le JWT est vérifié localement à l'aide des clés de signature Scrydon intégrées à la version.
- Aucune télémétrie ne quitte le cluster.
- Intégrité des images. Vérifiez la signature du paquet et
SHA256SUMS, consignez les empreintes des images importées et utilisez exactement ces artefacts pour l'accréditation du Runtime Plane. La réécriture de Zarf ne remplace pas la conservation des preuves d'empreinte. - Secrets. La licence est stockée dans la base de données de la plateforme après sa première utilisation ; les identifiants de déploiement résident dans les magasins de secrets internes au cluster. Zarf n'envoie rien hors de l'environnement déconnecté.
Suite : Licences couvre la validation hors ligne, l'expiration et le renouvellement.