# 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`, services `10.43.0.0/16`) - **Single control-plane** : si compute-01 tombe, `kubectl` ne fonctionne plus mais les workloads continuent --- ## Outils requis (poste perso + storage-01) ```bash # 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) ```bash # 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 ```bash # 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 ```bash 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 1. Brancher la clé USB sur le nœud, allumer 2. Le nœud prend une IP DHCP dans `192.168.10.50-99` (dnsmasq sur storage-01) 3. Vérifier les disques **avant** d'appliquer la config : ```bash export TALOSCONFIG=talos/clusterconfig/talosconfig talosctl get disks --insecure --nodes ``` > ⚠️ Les ThinkCentre ont un NVMe (`nvme0n1`), pas un SATA. Vérifier que `installDisk: /dev/nvme0n1` dans `talconfig.yaml`. ### 4. Appliquer la config ```bash # compute-01 talosctl apply-config --insecure --nodes --file talos/clusterconfig/funk-compute-01.yaml # compute-02 talosctl apply-config --insecure --nodes --file talos/clusterconfig/funk-compute-02.yaml # compute-03 talosctl apply-config --insecure --nodes --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 ` puis retirer la clé USB pendant le reboot. ### 5. Bootstrap etcd (une seule fois sur compute-01) ```bash 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 ```bash 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 : ```bash 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 ```bash 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 : ```bash 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 ```bash 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 : ```bash 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 `.lab.local` résout vers Traefik. --- ## Administration quotidienne ### État du cluster ```bash 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 ```bash # 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 # Events k8s kubectl get events -A --sort-by='.lastTimestamp' ``` ### Reboot / shutdown d'un nœud ```bash # 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 ```bash 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) ```bash 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 ```bash 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 |