Aller au contenu

Exploitation

Du premier apply a la destruction, avec ce qu'il faut verifier a chaque etape et les pannes deja rencontrees.

Prerequis

Outils, verifies par make check :

  • tofu (>= 1.9), talosctl (>= 1.13, meme version mineure que le cluster), kubectl, helm, curl
  • scw (CLI Scaleway) : obligatoire, ce n'est pas un confort. La bascule du worker en rescue passe par lui, aucune API OpenTofu ne le remplace.
  • kubeconform pour make check-manifests
  • facultatifs, seulement si tu construis le filtre : cargo avec la cible wasm32-wasip1, oras, python3

Credentials Scaleway, uniquement par variables d'environnement ou par ~/.config/scw/config.yaml. Jamais dans le code, jamais dans le state :

export SCW_ACCESS_KEY="SCWXXXXXXXXXXXXXXXXX"
export SCW_SECRET_KEY="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export SCW_DEFAULT_PROJECT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Cles SSH : ssh_public_key_path (par defaut ~/.ssh/id_ed25519.pub) est enregistree cote Scaleway et sert a la session rescue. ssh_private_key_path est lue par OpenTofu pour s'y connecter et ecrire l'image.

Mise en route

cp tofu/infra/terraform.tfvars.example    tofu/infra/terraform.tfvars
cp tofu/platform/terraform.tfvars.example tofu/platform/terraform.tfvars
cp tofu/edge/terraform.tfvars.example     tofu/edge/terraform.tfvars
$EDITOR tofu/*/terraform.tfvars

make check
make apply
eval "$(make kubeconfig)"
make cluster-status

cluster_endpoint est la seule variable obligatoire cote infra : elle doit correspondre au nom DNS de l'API (api_hostname plus dns_zone) et sert aussi aux certSANs du kube-apiserver.

Ordre des couches, et pourquoi il est impose

Trois states, trois apply, dans cet ordre :

  1. tofu/infra : API Scaleway plus le cluster Talos. Ecrit talos/_out/platform-inputs.json (celui dont la couche suivante a besoin) et talos/_out/kubeconfig.
  2. tofu/platform : Cilium, les CRD de l'API Gateway, cert-manager, Istio. Ces composants ne peuvent exister qu'une fois l'API Kubernetes joignable.
  3. tofu/edge : namespace, GatewayClass, emetteur Let's Encrypt, passerelle, routes, application de demonstration, et le filtre de challenge s'il est active. Ces objets ont besoin des CRD installes par la couche precedente.

Le point technique qui impose de separer bord et plateforme : le provider hashicorp/kubernetes (kubernetes_manifest) resout le schema OpenAPI au plan, donc il echoue sur un Gateway ou un ClusterIssuer dont le CRD est cree dans le meme cycle. Le depot utilise alekc/kubectl, qui sait appliquer une ressource dont le CRD arrive dans le meme passage, et garde tout de meme chaque objet suivi dans le state.

Verifier chaque etape

Apres l'infra : talosctl doit repondre sur les trois control plane, et le worker doit etre sorti du mode maintenance.

eval "$(make kubeconfig)"
talosctl -n <ip-cp-1> health
kubectl get nodes -o wide          # 4 noeuds, un seul scheduleable

Apres la plateforme : les composants doivent etre prets avant de continuer.

kubectl -n kube-system get ds cilium
kubectl -n istio-system get pods
kubectl -n cert-manager get pods
kubectl get crd | grep -c gateway.networking.k8s.io

Apres le bord :

kubectl get gateway,httproute -A
kubectl get certificate -A
kubectl -n edge describe gateway edge-gateway
curl -vk https://<edge_hostname>.<dns_zone>/

Le certificat Let's Encrypt prend une a deux minutes. S'il reste en False/Invalid, l'ordre de verification est : le defi HTTP-01 a-t-il abouti (kubectl describe challenge), le port 80 est-il joignable depuis l'exterieur, et la plage NodePort de Cilium contient-elle bien 80.

Validation des objets sans cluster : make check-manifests rend les objets de bord depuis HCL et les passe a kubeconform contre les vrais schemas. C'est la verification a faire dans une chaine d'integration, puisqu'elle ne demande ni cluster ni credential.

Allumer et eteindre

L'instance dort quand elle ne sert pas : c'est ce qui fait tomber le cout a presque rien. Deux commandes s'en occupent.

make up     # demarre l'instance et attend que la plateforme reponde
make down   # eteint l'instance

make up ne rend pas la main des que l'API Kubernetes repond : le noeud reste NotReady le temps que Cilium remonte, et il reste cordonne tant que le kubelet n'a pas repris la main. Lancer un deploiement a ce moment-la donne des pods Pending qu'on prend pour une panne. Le script attend donc le noeud pret, leve le cordon s'il en reste un, puis attend que plus aucun pod ne soit hors Running.

Les listes se rafraichissent seules

Un CronJob lists-refresh tourne a la dix-septieme minute de chaque heure. Il regenere les listes d'ASN et la liste Tor depuis leurs sources, puis remplace les cles concernees dans la ConfigMap policy-lists. Le decideur la relit tout seul.

kubectl -n edge get cronjob lists-refresh
kubectl -n edge create job --from=cronjob/lists-refresh lists-refresh-manuel
kubectl -n edge logs job/lists-refresh-manuel

La ConfigMap reste possedee par OpenTofu, son contenu non : ignore_fields empeche un apply de ramener les listes a leur version du dernier commit. Pour repartir du contenu versionne, supprimer la ConfigMap et reappliquer.

Une source qui tombe ne fait pas echouer le reste : chaque generateur tourne dans son propre processus, et une liste absente garde son ancienne version.

Jour 2

kubectl -n kube-system exec ds/cilium -- cilium-dbg status
kubectl -n kube-system exec ds/cilium -- cilium-dbg monitor --type policy-verdict
kubectl -n kube-system port-forward svc/hubble-ui 8080:80

Cilium est livre en mode audit (policyAuditMode = true) : les verdicts sont journalises, rien n'est bloque. C'est voulu pour ne pas couper la production au premier essai. Le passage en mode bloquant se fait apres lecture des verdicts, en changeant la variable dans tofu/platform/terraform.tfvars, puis make apply-platform. Verifie le trafic legitime avant, pas apres.

L'encryption WireGuard est active (nodeEncryption = true) mais pas en mode strict : le mode strict, qui refuse le trafic pod-a-pod non chiffre, est commente dans values/cilium.yaml.tftpl. A activer une fois le cluster stable, sinon tu te coupes l'acces a tes propres services.

Pannes deja rencontrees

  • La session rescue ne repond pas. Le null_resource attend 60 fois 10 secondes. Si elle echoue, le serveur est reste sur un boot normal, ou la cle SSH n'est pas celle enregistree cote Scaleway. Reprends a la main : scw baremetal server reboot <id> boot-type=rescue ssh-key-ids.0=<key-id>.
  • Le nom du disque. baremetal_disk = /dev/sda est une hypothese. Scaleway peut presenter du NVMe. Si le dd ecrit au mauvais endroit, redemarre en rescue et lis lsblk : le nom reel se voit la, et la sortie est enregistree dans le log du provisioner.
  • Image Talos invalide pour la version. Voir docs/infrastructure.md : le provider 0.12.0 ne produit pas de configuration acceptable par Talos 1.14. Le depot est bloque en 1.13.11 et la raison est ecrite dans les patchs.
  • La passerelle ne fait rien. Verifie que la GatewayClass existe. Ni istio/base ni istiod ne la creent : elle est declaree par la couche de bord. Sans elle, un Gateway avec gatewayClassName: istio est ignore en silence par le controleur, sans erreur visible.
  • Cilium refuse une plage NodePort sous 1024. La plage est 80,443 pour que le defi HTTP-01 de cert-manager aboutisse sans load balancer. Si ta version de Cilium refuse, elargis a 30000,32767 et passe cert-manager en DNS-01.
  • Le state est un secret. Il contient le CA du cluster, les cles etcd, les tokens, et la configuration du filtre de challenge avec son secret HMAC. .gitignore exclut *.tfstate* ; ne le desactive sous aucun pretexte.

Detruire

make destroy      # ordre inverse : edge, plateforme, infra

L'ordre est inverse de l'application, pour que les objets Kubernetes disparaissent avant que le cluster qui les porte ne s'en aille. Detruire l'infra en premier laisse les states de plateforme et de bord avec des references vers un cluster mort, qu'il faut ensuite nettoyer a la main.

Ce qui disparait avec : les quatre machines, les IP reservees, les volumes, le bucket, le snapshot, le cluster, et tout ce qui tourne dedans. Aucune sauvegarde n'est prise. Ce qui reste : rien, si ce n'est ce que tu as copie ailleurs.