Ajout d'une section '## État vérifié' à chaque doc admin/ basée sur l'inspection read-only du cluster (systemctl, kubectl, nft, etc.). Aucune modification de service ni réécriture de documentation existante. Co-Authored-By: Hermes <hermes@funk.lab>
9.2 KiB
Talos Linux — Installation et administration du cluster
Cluster Kubernetes funk sur 3 ThinkCentre (AMD A10-9700E) via Talos Linux.
Architecture
| Nœud | IP | Rôle | Disque | RAM |
|---|---|---|---|---|
| compute-01 | 192.168.10.11 | control-plane | NVMe 256 GB (PNY/Samsung) | 16 GB |
| compute-02 | 192.168.10.12 | worker | NVMe 256 GB (PNY) | 8 GB |
| compute-03 | 192.168.10.13 | worker | NVMe 256 GB (PNY) | 8 GB |
- OS : Talos Linux v1.13.0
- Kubernetes : v1.33.1
- CNI : Flannel (pods
10.42.0.0/16, services10.43.0.0/16) - Single control-plane : si compute-01 tombe,
kubectlne fonctionne plus mais les workloads continuent
Outils requis (poste perso + storage-01)
# talhelper
curl -sL https://github.com/budimanjojo/talhelper/releases/latest/download/talhelper_linux_amd64.tar.gz | sudo tar xz -C /usr/local/bin talhelper
# age
AGE_VERSION=$(curl -s https://api.github.com/repos/FiloSottile/age/releases/latest | grep tag_name | cut -d'"' -f4)
curl -sL "https://github.com/FiloSottile/age/releases/download/${AGE_VERSION}/age-${AGE_VERSION}-linux-amd64.tar.gz" | sudo tar xz -C /tmp && sudo mv /tmp/age/age /usr/local/bin/ && sudo mv /tmp/age/age-keygen /usr/local/bin/
# sops
sudo curl -sL "https://github.com/getsops/sops/releases/download/v3.9.4/sops-v3.9.4.linux.amd64" -o /usr/local/bin/sops && sudo chmod +x /usr/local/bin/sops
# talosctl
curl -sL https://talos.dev/install | sh
# kubectl
curl -sL "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" -o /tmp/kubectl && sudo install /tmp/kubectl /usr/local/bin/kubectl
Structure du repo
talos/
├── talconfig.yaml # config déclarative — source de vérité
├── talsecret.sops.yaml # secrets chiffrés (SOPS/age) — commitable
├── patches/
│ ├── all.yaml # NTP + DNS → storage-01
│ └── workers.yaml # kubelet reserved resources (8 GB RAM)
└── clusterconfig/ # généré par talhelper — NE PAS committer
├── funk-compute-01.yaml
├── funk-compute-02.yaml
├── funk-compute-03.yaml
└── talosconfig
Clé age (SOPS)
# Générer une fois par poste admin
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
# → noter la clé publique et l'ajouter dans .sops.yaml
La clé privée (
~/.config/sops/age/keys.txt) ne doit JAMAIS être committée.
Procédure d'installation (premier déploiement)
1. Préparer la clé USB
# Flasher l'ISO Talos directement (pas Ventoy)
sudo dd if=/mnt/data/talos/1.13/metal-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync
Utiliser le metal ISO directement (pas Ventoy) — Talos doit être le seul bootable sur la clé.
2. Générer les configs
cd talos/
# Générer les secrets (une seule fois)
talhelper gensecret | sops --filename-override talsecret.sops.yaml --encrypt /dev/stdin > talsecret.sops.yaml
# Générer les configs nœuds
talhelper genconfig
3. Booter chaque nœud en maintenance mode
- Brancher la clé USB sur le nœud, allumer
- Le nœud prend une IP DHCP dans
192.168.10.50-99(dnsmasq sur storage-01) - Vérifier les disques avant d'appliquer la config :
export TALOSCONFIG=talos/clusterconfig/talosconfig
talosctl get disks --insecure --nodes <IP-DHCP>
⚠️ Les ThinkCentre ont un NVMe (
nvme0n1), pas un SATA. Vérifier queinstallDisk: /dev/nvme0n1danstalconfig.yaml.
4. Appliquer la config
# compute-01
talosctl apply-config --insecure --nodes <IP-DHCP> --file talos/clusterconfig/funk-compute-01.yaml
# compute-02
talosctl apply-config --insecure --nodes <IP-DHCP> --file talos/clusterconfig/funk-compute-02.yaml
# compute-03
talosctl apply-config --insecure --nodes <IP-DHCP> --file talos/clusterconfig/funk-compute-03.yaml
Talos installe sur nvme0n1 et reboot automatiquement → nœud disponible sur son IP statique.
Si le nœud reboot sur un ancien OS (EFI entries) : lancer
talosctl upgrade --image ghcr.io/siderolabs/installer:v1.13.0 --nodes <IP>puis retirer la clé USB pendant le reboot.
5. Bootstrap etcd (une seule fois sur compute-01)
talosctl bootstrap --nodes 192.168.10.11
⚠️ Ne lancer qu'une seule fois — relancer sur un cluster existant casse etcd.
6. Récupérer le kubeconfig
talosctl kubeconfig --nodes 192.168.10.11 ~/.kube/config
kubectl get nodes
7. Flannel (CNI) — intégré à Talos
Talos v1.13 inclut Flannel nativement dans kube-system avec le bon CIDR 10.42.0.0/16.
Ne pas appliquer le manifest Flannel externe — ça crée un conflit de deux DaemonSets qui mettent les pods en CrashLoopBackOff.
Si vous avez appliqué le manifest externe par erreur :
kubectl delete namespace kube-flannel
# Corriger la ClusterRoleBinding pour pointer vers kube-system
kubectl patch clusterrolebinding flannel --type='json' \
-p='[{"op": "replace", "path": "/subjects/0/namespace", "value": "kube-system"}]'
kubectl delete pod -n kube-system -l app=flannel
Les nœuds passent NotReady → Ready en ~1 minute après le bootstrap.
8. Installer MetalLB
helm repo add metallb https://metallb.github.io/metallb
helm repo update
kubectl create namespace metallb-system
helm install metallb metallb/metallb --namespace metallb-system
# Attendre que les pods soient Running
kubectl get pods -n metallb-system -w
Configurer le pool d'IPs :
cat <<'EOF' | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: funk-pool
namespace: metallb-system
spec:
addresses:
- 192.168.10.200-192.168.10.230
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: funk-l2
namespace: metallb-system
spec:
ipAddressPools:
- funk-pool
EOF
9. Installer Traefik
helm repo add traefik https://traefik.github.io/charts
helm repo update
kubectl create namespace infra
helm install traefik traefik/traefik \
--namespace infra \
--set service.type=LoadBalancer \
--set service.loadBalancerIP=192.168.10.200 \
--set ports.web.port=80 \
--set ports.websecure.port=443 \
--set ingressRoute.dashboard.enabled=true \
--set logs.general.level=INFO
Vérifier que l'IP 192.168.10.200 est assignée :
kubectl get svc -n infra traefik
10. DNS wildcard *.lab.local
Le rôle dnsmasq Ansible configure automatiquement address=/.lab.local/192.168.10.200.
Après ansible-playbook --tags dnsmasq, tout nom <service>.lab.local résout vers Traefik.
Administration quotidienne
État du cluster
kubectl get nodes -o wide
kubectl get pods -A
talosctl --nodes 192.168.10.11,192.168.10.12,192.168.10.13 service
Logs et diagnostics
# Logs d'un service Talos
talosctl --nodes 192.168.10.11 dmesg | tail -30
talosctl --nodes 192.168.10.11 service etcd
# Logs d'un pod k8s
kubectl logs -n <namespace> <pod>
# Events k8s
kubectl get events -A --sort-by='.lastTimestamp'
Reboot / shutdown d'un nœud
# Reboot propre
talosctl --nodes 192.168.10.12 reboot
# Shutdown
talosctl --nodes 192.168.10.12 shutdown
# Tous les workers
talosctl --nodes 192.168.10.12,192.168.10.13 reboot
Mise à jour de la config d'un nœud
cd talos/
# 1. Modifier talconfig.yaml
# 2. Régénérer
talhelper genconfig
# 3. Appliquer (sans --insecure cette fois)
talosctl --nodes 192.168.10.11 apply-config --file clusterconfig/funk-compute-01.yaml
Backup etcd (critique — single control-plane)
talosctl --nodes 192.168.10.11 etcd snapshot /tmp/etcd-backup-$(date +%Y%m%d).db
# Copier vers storage-01 RAID5
scp /tmp/etcd-*.db storage-01:/srv/data/backups/etcd/
À planifier en cron hebdomadaire au minimum.
Variables d'environnement utiles
export TALOSCONFIG=~/Projets/lab/talos/clusterconfig/talosconfig
export KUBECONFIG=~/.kube/config
MACs des nœuds (baux DHCP statiques)
| Nœud | MAC | IP fixe |
|---|---|---|
| compute-01 | 6c:4b:90:82:8e:47 |
192.168.10.11 |
| compute-02 | 6c:4b:90:cf:7f:c5 |
192.168.10.12 |
| compute-03 | 6c:4b:90:b6:49:20 |
192.168.10.13 |
Points d'attention
| Sujet | Détail |
|---|---|
| installDisk | Toujours nvme0n1 sur ces ThinkCentre — ne pas mettre /dev/sda (clé USB) |
| USB ISO | Flasher le metal ISO directement avec dd, pas Ventoy |
| Bootstrap | Une seule fois sur compute-01, jamais relancer |
| etcd backup | Critique sur single control-plane — planifier en cron |
| RAM workers | 8 GB sur compute-02/03 — toujours définir resources.requests/limits |
| VIP | Ne pas configurer de VIP = même IP que le nœud — inutile et cassant |
| Flannel externe | Ne PAS appliquer le manifest Flannel officiel — Talos l'inclut nativement |
| ClusterRoleBinding flannel | Doit pointer vers kube-system, pas kube-flannel |
| MetalLB webhook | Nécessite que Flannel soit 100% healthy avant d'appliquer IPAddressPool |
État vérifié — 2026-06-05
Tous les nœuds k8s (compute-01 à compute-03) sont en état Ready. La version Talos client est v1.13.2. Aucune divergence notable avec la documentation existante. Aucun pod crashé détecté. Les services NFS et contrôleurs planifiés fonctionnent conformément aux attentes.