Aller au contenu

Infrastructure

Ce que le POC cree reellement chez Scaleway, ressource par ressource, et les limites qu'il faut connaitre avant de s'appuyer dessus.

Tout est dans tofu/infra, en OpenTofu. Aucun appel kubectl ni talosctl en shell, hors les trois operations qui n'ont pas d'equivalent declaratif (voir plus bas). Les valeurs citees ici sont celles des variables par defaut de tofu/infra/variables.tf ; les chiffres de prix sont ceux releves le 17/10/2026 et vieillissent, contrairement au reste.

Inventaire

Zone fr-par-1, region fr-par, projet Scaleway unique.

Control plane (3 instances) : cp_count = 3, cp_instance_type = PLAY2-NANO, soit l'equivalent de 20,10 € par mois et par instance. Trois, parce qu'etcd a besoin d'un quorum impair et que deux pannes doivent rester survivables.

  • une IPv4 reservee par instance, creee avant les serveurs. Ce n'est pas un detail de style : le security group a besoin de connaitre les IP des noeuds pour ecrire ses regles, et les serveurs ont besoin du security group. Sans reservation prealable, la boucle est ferme.
  • une instance sans image du catalogue (image = "none"), dont le disque racine est un volume cree depuis notre snapshot Talos.
  • un volume bloc de 20 GiB a 5 000 IOPS par instance (cp_volume_size_gb, cp_volume_iops), cree depuis le snapshot.
  • un security group commun aux trois.

Worker (1 Elastic Metal) : baremetal_offer = EM-A116X-SSD, 27,99 € par mois en facturation horaire, baremetal_hostname = edge-01. C'est le seul noeud qui porte des charges de travail : le control plane a allowSchedulingOnControlPlanes: false.

  • aucun OS du catalogue (install_config_afterward = true). L'API Scaleway n'accepte pour un Elastic Metal qu'un os-id du catalogue, aucun ISO ni image personnalisee. Le seul chemin vers Talos est donc de booter en rescue et d'ecrire l'image disque a la main.
  • pas de security group. La ressource scaleway_baremetal_server du provider scaleway 2.87.0 n'expose aucun attribut de ce type : les security groups n'existent que pour les Instances. Consequence assumee : sur le worker, le filtrage vient du host firewall Cilium et de l'anti-DDoS Scaleway en amont.
  • pas d'option 1 Gbps (baremetal_bandwidth_1gbps = false), qui est facturee en plus et sans interet pour un POC.

Objet et image (2 ressources + 1 snapshot) : un bucket Object Storage (object_bucket_name, obligatoire) et un objet (image_key = talos/metal-amd64.qcow2), puis un snapshot bloc importe depuis cet objet.

DNS (optionnel) : dns_zone = "" par defaut, donc aucun enregistrement cree. Tu geres le DNS ou tu le fais ailleurs. Avec une zone renseignee, le module cree les noms d'API (api_hostname = k8s-poc, une entree A par control plane) et de bord (edge_hostname = edge, vers l'IP du worker).

SSH : ssh_public_key_path est enregistree cote Scaleway (scaleway_iam_ssh_key) et sert a ouvrir la session rescue du worker.

Chaine de l'image Talos

Scaleway ne sait pas creer une instance depuis une image locale : l'API exige un snapshot, et l'import d'un snapshot exige un QCOW2 present dans Object Storage. C'est le detour impose, et il est entierement declaratif.

Image Factory (platform=scaleway, qcow2)
   -> telechargement local, dans tofu/infra/.cache, idempotent
   -> Object Storage (un objet)
   -> snapshot bloc
   -> un volume racine par control plane

Image Factory (platform=metal, raw.zst)
   -> http direct depuis le rescue, ecrit en dd sur le worker

Deux plateformes pour deux modes de demarrage, volontairement. Details :

  • schematic : construit par talos_image_factory_schematic, vide par defaut (talos_extensions = []), donc Talos vanilla sans identifiant en dur. Le meme schematic sert aux deux plateformes.
  • version : talos_version = v1.13.11, pinnée. Voir la section suivante.
  • image d'installation : machine.install.image pointe sur le meme schematic que l'image bootee. Sans cela, un upgrade remplace le systeme par une image sans les extensions.
  • certSANs : le nom DNS de l'API est extrait de cluster_endpoint et injecte dans les certSANs du kube-apiserver, pour que kubectl fonctionne par ce nom.

Pourquoi la version de Talos est bloquee

Le provider siderolabs/talos 0.12.0, la derniere version publiee, materialise encore les cles de configuration v1alpha1 en parallele des documents multiples introduits par Talos 1.14 (KubeNetworkConfig, KubeFlannelCNIConfig, KubeProxyConfig). Les deux ensemble ne passent pas la validation :

talosctl validate --config controlplane.yaml --mode metal
  * either install disk or diskSelector should be defined
  * UnattendedInstallConfig config is incompatible with v1alpha1 config
  * cluster network config in v1alpha1 config can't be used with
    KubeFlannelCNIConfig document

Une machine qui recoit cette configuration refuse de s'installer. Le depot reste donc sur Talos 1.13.11, dont le modele de configuration est exactement ce que le provider produit. A reprendre quand le provider saura emettre les documents.

Deux choses ne doivent pas figurer dans les patchs communs, verifiees avec talosctl 1.13.11 :

  • machine.features.stableHostname : le document HostnameConfig genere le porte deja, la doubler fait echouer la validation.
  • cluster.etcd : interdit sur un noeud worker, donc reserve au patch du control plane.

Reseau et ports

Pas de reseau prive Scaleway. Ce choix est assume : le trafic inter-noeuds passe par l'interface par defaut, protege par le security group, le host firewall Cilium et l'encryption WireGuard. Un reseau prive aurait impose une seconde interface a configurer dans Cilium pour un gain nul sur un cluster d'une zone.

Le control plane est filtre par le security group, en drop par defaut, avec enable_default_security = false et des regles par IP de noeud :

  • administration, depuis admin_cidrs : TCP 6443 (API Kubernetes) et TCP 50000 (API Talos).
  • entre noeuds, depuis chaque IP du cluster : TCP 2379 (etcd client), TCP 2380 (etcd peer), TCP 10250 (kubelet), UDP 51871 (tunnel WireGuard Cilium). UDP 8472 (VXLAN) est commente : il ne sert qu'en routingMode: tunnel.
  • ICMP depuis l'administration et entre noeuds, pour le diagnostic et la decouverte de MTU.
  • 80 et 443 depuis partout, uniquement si expose_edge_on_control_plane = true. Par defaut, non : le bord est sur le worker.

Attention a admin_cidrs. Sa valeur par defaut est ["0.0.0.0/0"], ce qui ouvre l'API Kubernetes et l'API Talos a l'Internet entier. C'est un defaut de POC pour ne pas bloquer au premier essai ; a restreindre avant tout autre usage. Le mot de passe d'API Talos ne protege que ce qu'il peut.

Les trois operations hors state

Tout le reste est declaratif et suivi. Trois operations n'ont pas d'equivalent :

  1. Telechargement de l'image qcow2 (null_resource.image_download) : les ressources local_file du provider recopient un fichier, elles ne le telechargent pas. Idempotent, et make clean-image force le renouvellement.
  2. Ecriture de l'image sur le worker (null_resource.baremetal_talos_install) : Scaleway n'accepte qu'un os-id du catalogue. Il faut booter en rescue, attendre SSH, dd l'image decompressee, puis redemarrer en mode normal.
  3. Premiere configuration Talos (tofu/infra/bootstrap.tf, en --insecure) : talos_machine_configuration_apply n'expose pas l'option insecure, or la machine sort du rescue en mode maintenance sans certificat de confiance.

Ces trois ressources sont gardees par un triggers hache : elles ne se rejouent que si l'URL de l'image, le disque ou l'identifiant du serveur changent.

Ce que le POC ne couvre pas

A connaitre avant de promettre quoi que ce soit a un client :

  • un seul worker, donc un seul point de panne pour les charges de travail. Le control plane survit a une panne, le service non.
  • aucun load balancer. La passerelle est exposee en NodePort sur le worker, et cette plage est restreinte a 80 et 443 (voir docs/architecture.md).
  • aucun BGP, aucun anycast. Pas de LIR, pas de /24, pas d'ASN : le trafic arrive sur une IP unique dans une zone unique.
  • anti-DDoS sans SLA revendable sur l'Elastic Metal. C'est un filet amont, pas une protection contractuelle a mettre sur une facture.
  • le state contient les secrets du cluster : CA, cles etcd, tokens. Un state local est acceptable pour un POC et inacceptable en production. Backend distant chiffre obligatoire des la premiere vraie machine.
  • pas de sauvegarde d'etcd, pas de politique de retention, pas de supervision des certifcats au dela de ce que cert-manager renouvelle lui-meme.

Cout

Prix releves le 17/10/2026, hors taxes, facturation horaire :

  • worker EM-A116X-SSD : 27,99 € par mois, soit 0,077 € par heure.
  • 3 x PLAY2-NANO : 20,10 € par mois chacune, soit environ 60 € par mois.
  • volumes bloc 20 GiB a 5 000 IOPS, Object Storage et snapshot : quelques euros par mois au total.
  • cluster entier allume : de l'ordre de 4 € par jour. C'est le chiffre a retenir : un POC laisse tourner un mois coute plus cher qu'un mois de cluster de production, parce que rien n'est mutualise.

tofu destroy ne laisse rien derriere, mais l'ordre compte : voir docs/operations.md.