Aller au contenu principal

Réseau

Disponible

Fonctionnalité déployée et prise en charge. Les champs et commandes décrits ici sont stables au sein de la version v1alpha1.

Le réseau d'une App est fermé par défaut : un service n'accepte que les connexions sur ses ports déclarés, venant des autres services de la même App (et d'Internet s'il est exposé), et ne sort nulle part sauf vers les services de votre tenant. Deux champs ouvrent des portes : allowFrom (une autre App de votre tenant entre) et egress: [internet] (le service sort).

Prérequis​

Étapes​

1. Ouvrir ce qui doit l'être​

shop.yml
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: shop
spec:
services:
api:
image: registry.gitlab.com/acme/shop-api:1.4.2
ports: ["8080"]
ingress: { port: 8080 }
egress: [internet] # appelle un prestataire de paiement
dependsOn: [db]
db:
image: postgres:17
user: "999"
ports: ["5432"]
allowFrom: [reporting] # l'App « reporting » du tenant peut lire la base
volumes:
- { path: /var/lib/postgresql/data, size: 10Gi }

En ligne de commande : sng app create … --egress-internet --allow-from reporting, sng app patch shop --service api --egress-internet=false.

2. Appliquer et tester​

sng apply shop.yml
sng app logs shop --service api --since 5m

Depuis api, db:5432 répond ; https://api.paiement.example aussi. Depuis db, une requête vers Internet est bloquée.

Vérification​

Un petit job de sonde dit ce qui passe :

netcheck.yml
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: netcheck
spec:
services:
closed:
kind: job
image: curlimages/curl:8.11.1
user: "100"
size: xxxs
command: ["sh", "-c", "for u in https://example.com http://169.254.169.254/; do if curl -s -m 5 -o /dev/null $u; then echo \"OK $u\"; else echo \"BLOCKED $u\"; fi; done"]
open:
kind: job
image: curlimages/curl:8.11.1
user: "100"
size: xxxs
egress: [internet]
command: ["sh", "-c", "for u in https://example.com http://169.254.169.254/; do if curl -s -m 5 -o /dev/null $u; then echo \"OK $u\"; else echo \"BLOCKED $u\"; fi; done"]
sng apply netcheck.yml
sng app logs netcheck
[netcheck-closed-3f9a1c2e-x7k2q] BLOCKED https://example.com
[netcheck-closed-3f9a1c2e-x7k2q] BLOCKED http://169.254.169.254/
[netcheck-open-8b1d7e40-p9s4m] OK https://example.com
[netcheck-open-8b1d7e40-p9s4m] BLOCKED http://169.254.169.254/

Qui peut joindre quoi​

Entrée vers un service​

DepuisVersAutorisé ?
un autre service de la même Appun port déclaré dans portsoui
un autre service de la même Appun port non déclarénon
une autre App de votre tenantun port déclaréoui si l'App est dans allowFrom
Internet (en HTTPS)le port de ingress seulementoui si ingress
un autre tenantquoi que ce soitjamais
n'importe quiun service sans portsnon : il n'accepte rien

Les règles sont en place avant que le service ne démarre : il n'y a pas de fenêtre où un service serait ouvert.

Sortie d'un service​

VersAutorisé ?
les services de votre tenant (toutes Apps)oui, mais le service cible doit accepter (voir ci-dessus)
le DNS de la plateformeoui
Internetseulement avec egress: [internet]
les adresses privées (autres tenants, réseaux privés, 169.254.169.254)jamais, même avec egress: [internet]

egress n'accepte que la valeur internet ; il n'y a pas d'ouverture par adresse ou par port.

Nommer les services entre eux​

Un service db de l'App shop qui déclare ports: ["5432"] est joignable par les autres services de l'App en db:5432, exactement comme en compose. Avec la forme "5433:5432", c'est db:5433 qui est exposé, vers le port 5432 du conteneur.

Depuis une autre App du tenant (autorisée par allowFrom), utilisez le même nom : db:5432. Évitez de donner le même nom de service à deux Apps d'un tenant : le second est refusé (NameConflict), car un nom de service est unique dans tout le tenant.

allowFrom​

  • Liste de noms d'Apps de votre tenant (10 au plus), pas de services.
  • Ouvre tous les ports du service aux services de ces Apps. Pas de granularité par port.
  • Exige au moins un port déclaré, sinon le manifeste est invalide (allowFrom : le service n'a aucun port à ouvrir).
  • sng app patch shop --service db --allow-from '' retire toutes les autorisations.

dependsOn et réseau​

dependsOn ordonne la création des services ; il n'ouvre aucune porte. Un service peut dépendre d'un autre sans pouvoir le joindre (si celui-ci n'a pas de ports), et réciproquement. Pour qu'api attende db et lui parle : dependsOn: [db] sur api, ports: ["5432"] sur db.

Si ça ne marche pas​

Ce que vous voyezCauseCorrection
connection refused ou délai dépassé vers db:5432Le port n'est pas dans les ports de db, ou l'appelant est dans une autre App absente de allowFromDéclarer le port, ou ajouter l'App à allowFrom
Un appel vers une API externe expireLe service n'a pas egress: [internet]L'ajouter, puis sng apply
NameConflict sur un serviceUne autre App du tenant a un service du même nomRenommer l'un des deux services
Manifeste refusé : allowFrom : le service n'a aucun port à ouvrirallowFrom sur un service sans portsDéclarer au moins un port

Pour aller plus loin​

  • Ces règles s'appliquent à chaque service et ne peuvent pas être désactivées.
  • Vos conteneurs ne reçoivent aucune variable décrivant les autres services : passez les adresses par env (DB_HOST: db).
  • La résolution des noms publics est toujours permise : aucune ouverture supplémentaire n'est nécessaire pour résoudre un nom avant de le joindre avec egress: [internet].

Voir aussi​