Installation
Dans cette documentation, nous allons détailler l’installation de Talos Linux et la création d’un cluster Kubernetes en mode « bare-metal » ou « vm ».
Autre point important, cette documentation traite de l’installation et de la création d’un cluster utilisant la CNI Cilium.
Talos Linux est déployé nativement avec la CNI Flannel, personnellement, je la trouve un peu limitée dans ses capacités, c’est pour celà
que j’opte pour le choix de Cilium.
Cilium sera déployé avec les features suivantes :
- Remplacement de
kube-proxy - Gestion des Gateway API Kubernetes
- Déploiement de l’Ingress Controller embarqué (Envoy)
L’installation sur un Cloud Provider doit être faite d’une façon légèrement différente pour démarrer les machines.
Pour ce cas d’usage, je vous invite à vous rapprocher de la documentation de Talos.
Prérequis
Section titled “Prérequis”- Disposer sur votre machine ou sur une machine dédiée le binaire
talosctldans la dernière version stable disponible en téléchargement sur le dépot GitHub. - Déterminer la version du Kubernetes à installer à l’aide de la matrice de compatibilité si vous souhaitez déployer une version particulière de Kubernetes.
- Disposer de l’iso de Talos Linux disponible également sur le dépot GitHub.
- Disposer d’une adresse IP pour chacun des nœuds du cluster Talos qui va être constitué.
- Disposer d’une adresse IP virtuelle (VIP) pour les Control Planes.
- Disposer sur votre machine ou sur une machine dédiée de Helm
Préparation des hôtes
Section titled “Préparation des hôtes”En tout premier lieu, préparez les machines qui vont être les nœuds de votre cluster.
Il suffit de démarrer les machines sur l’iso de Talos que vous avez récupéré en pré-requis.
Si vous avez du DHCP sur votre réseau, les machines vont automatiquement prendre une adresse dans celui-ci,
sinon, il faudra configurer manuellement les adresse IP depuis la console.
Dans le cadre de cette documentation, nous considèrerons que les adresse IP seront les suivantes :
| hostname | IP |
|---|---|
| talos-cp1 | 192.168.0.101 |
| talos-cp2 | 192.168.0.102 |
| talos-cp3 | 192.168.0.103 |
| talos-worker1 | 192.168.0.201 |
| talos-worker2 | 192.168.0.202 |
| talos-worker3 | 192.168.0.203 |
Autre information réseau :
| role | IP |
|---|---|
| NTP | 192.168.0.8 |
| NTP | 192.168.0.9 |
| DNS | 192.168.0.10 |
| DNS | 192.168.0.11 |
Préparation de la configuration
Section titled “Préparation de la configuration”La toute première étape à effectuer est de générer et préparer les manifestes de configuration de Talos que vous allez injecter à vos machines.
Génération des secrets
Section titled “Génération des secrets”Talos utilise pour sécuriser l’ensemble des communications de ses composants des jeux de certificats (serveurs et client).
Afin de s’assurer que ces certificats sont uniques, il est préférable de générer un fichier contenant ces secrets.
Le binaire talosctl permet de générer un fichier contenant l’ensemble des secrets :
talosctl gen secrets -o secrets.yamlVous obtiendrez donc le fichier suivant :
cluster: id: <id du cluster> secret: <secret interne du cluster>secrets: bootstraptoken: <token de jonction au cluster Kubernetes> secretboxencryptionsecret: <clef de chiffrement des secrets Kubernetes>trustdinfo: token: <token de jonction au cluster Talos>certs: etcd: crt: <certificat pour les communications ETCD> key: <clef privée pour les communications ETCD> k8s: crt: <certificat pour les communications Kubernetes> key: <clef privée pour les communications Kubernetes> k8saggregator: crt: <certificat pour les communications de Kubernetes aggregator> key: <clef privée pour les communications de Kubernetes aggregator> k8sserviceaccount: key: <clef privée pour le compte de service Kubernetes administrateur> os: crt: <certificat pour la communication avec les API Talos> key: <clef pivée pour la communication avec les API Talos>Génération des configurations initiales
Section titled “Génération des configurations initiales”Maintenant que vous avez le fichier contenant vos secrets, vous pouvez générer les fichiers de configuration de référence.
Ces fichiers serviront de socle général pour la configuration de vos nœuds :
controlplane.yaml: Le fichier de configuration de référence pour les Control Planeworker.yaml: Le fichier de configuration de référence pour les workers.
Fichiers de références standard
Section titled “Fichiers de références standard”Pour générer les fichiers :
talosctl gen config \ --with-secrets secrets.yaml \ <cluster_name> \ <cluster_endpoint>Dans le cas de la commande ci-dessus, vous générez les configurations « standard » de Talos sans spécificitées.
Vous devrez spécifier deux paramètres :
<cluster_name>: Le nom de votre cluster Kubernetes<cluster_endpoint>: L’URL d’accès aux API Kubernetes de votre cluster en utilisant la VIP. (Le format complet étant :https://<VIP>:6443)
Spécification de la version de Kubernetes
Section titled “Spécification de la version de Kubernetes”Pour spécifier la version de Kubernetes à déployer, ajouter une option à la commande ci-dessus :
talosctl gen config \ --with-secrets secrets.yaml \ --kubernetes-version <kube_version> \ <cluster_name> \ <cluster_endpoint>La version de Kubernetes doit être spécifié en intégralité. Par example : 1.29.3.
Ajouter la feature Kubespan
Section titled “Ajouter la feature Kubespan”De mon côté, j’apprécie la feature Kubespan présente dans Talos.
Celà permet facilement d’hybrider un cluster Talos entre des nœuds sur site, et chez un cloud provider par exemple.
L’idée derrière cette feature est d’instancier un réseau Mesh Wireguard entre tous les nœuds du cluster pour permettre
de chiffrer les communications entre les nœuds et de ne pas avoir à se soucier particulièrement de la sécurité réseau
des communications vu que ces dernières sont encapsulée dans une solution de « VPN ».
Dans un réseau local dans l’absolu, elle n’est pas nécessaire, mais j’ai une préférence pour l’activer « by design ».
Pour ce faire, il faut ajouter une option à la commande permettant de générer les configurations :
talosctl gen config \ --with-secrets secrets.yaml \ --kubernetes-version <kube_version> \ --with-kubespan \ <cluster_name> \ <cluster_endpoint>Autres options
Section titled “Autres options”Lors de la génération des configurations, il est possible de passer d’autres options intéressantes :
--dns-domain: Domaine DNS utilisé au sein du cluster (par défautcluster.local)--install-disk: Le chemin absolu du disque sur lequel installer Talos (par défault/dev/sda)--install-image: Le nom complet de l’image de Talos à installer. Si vous utilisez un registry local (cache ou avec des images en propre) par exemple plutôt que de tirer les images depuis le registry GitHub. (par défault :ghcr.io/siderolabs/installer:<talos_version>)--talos-version: La version spécifique de Talos à installer, par exemplev1.6.8. Par défaut cette valeur correspond à la version du binairetalosctlque vous avez installé.
Création des configurations
Section titled “Création des configurations”Référence
Section titled “Référence”Afin de générer la bonne configuration à appliquer à vos machines, vous pouvez modifier les configurations initiales que vous venez de générer.
Par défaut, je vous invite à le faire pour tout ce qui sera commun entre vos Control Plane et vos Workers. Par exemple :
- La configuration des serveurs DNS.
- La configuration des CNI.
- L’injection de fichiers de CA si vous disposez d’une PKI propre.
- …
Dans notre cas, nous allons configurer dans les fichiers controlplane.yaml et worker.yaml les paramètres suivants :
- Serveurs DNS
- Serveurs NTP
- Activation de la rotation automatique des certificats (
rotate-server-certificates) - Désactivation de la CNI
- Exposition des métriques
- Proxy
- ETCD
- Déploiement de
kubelet-serving-cert-approverpour la rotation automatique des certificats. - Déploiement de
metric-serverpour activer les capacités de HPA et de VPA de Kubernetes.
---...machine: ... kubelet: ... network: ... nameservers: - 192.168.0.10 - 192.168.0.11 ... rotate-server-certificates: true ... ... time: disabled: false servers: - 192.168.0.8 - 192.168.0.9 ...cluster: ... network: ... cni: ... name: none ...Dans le fichier controlplane.yaml uniquement, il faudra également désactiver la partie kube-proxy :
---...cluster: ... proxy: ... disabled: true etcd: ... extraArgs: listen-metrics-urls: http://0.0.0.0:2381 ... extraManifests: ... - https://raw.githubusercontent.com/alex1989hu/kubelet-serving-cert-approver/main/deploy/standalone-install.yaml - https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml ...Une fois vos configurations de références mise en place, vous pouvez créer vos fichiers de « patch » qui seront les configurations propres à chacun des nœuds de votre cluster Talos.
Il est donc nécessaire de disposer d’un fichier de patch par machine du cluster.
Control Plane
Section titled “Control Plane”Pour la partie Control Plane, le fichier de patch « classique » sera le suivant :
machine: certSANs: - <adresse_VIP> - <adresse_node> - <fqdn_VIP> - <fqdn_node>
network: hostname: <hostname> interfaces: - interface: deviceSelector: hardwareAddr : '<node_mac_address(xx:xx:xx:xx:xx:xx)>' addresses: - <adresse_node> routes: - network: 0.0.0.0/0 gateway: <adresse_de_gateway_du_réseau> metric: 1024 mtu: 1500 vip: ip: <adresse_VIP>Dans la partie certSANs, il est recommandé d’expliciter l’ensemble des adresses ainsi que les noms du nœud.
Vous noterez dans ce cas la présence de l’adresse de VIP vu qu’elle peut être déclaré sur chaque Control-Plane.
Dans la partie réseau, on retrouve les champs à modifier :
<hostname>: Le nom d’hôte du nœud.<node_mac_address>: L’adresse MAC du nœud. Cette configuration permet de définir sur quelle interface du nœud l’adresse IP que l’on est en train de configurer doit être appliquée. Il y a plusieurs façons de faire, celle-ci étant ma préférée.<adresse_node>: L’adresse IP à attribuer au nœud.<adresse_de_gateway_du_réseau>: L’adresse da la passerelle réseau pour ce nœud.<adresse_VIP>: L’adresse VIP que vous avez définie en prérequis (dans notre cas192.168.0.100).
Worker
Section titled “Worker”Pour la partie Worker, c’est sensiblement similaire.
Au détail près qu’il ne faut pas intégrer les données propres à la VIP.
machine: certSANs: - <adresse_node> - <fqdn_node>
network: hostname: <hostname> interfaces: - interface: deviceSelector: hardwareAddr : '<node_mac_address(xx:xx:xx:xx:xx:xx)>' addresses: - <adresse_node> routes: - network: 0.0.0.0/0 gateway: <adresse_de_gateway_du_réseau> metric: 1024 mtu: 1500Génération des configurations finales
Section titled “Génération des configurations finales”Une fois vos configurations génériques et vos patchs finalisés, vous pouvez générer vos configurations finales qui seront appliqués à chacun de vos nœuds.
Pour ce faire, il faut exécuter la commande suivante (pour chacun des nœuds) :
Pour les Control Plane :
talosctl machineconfig patch controlplane.yaml --patch @<node_patch_file>.yaml --output <node>.yamlPour les Worker :
talosctl machineconfig patch worker.yaml --patch @<node_patch_file>.yaml --output <node>.yamlExemples :
talosctl machineconfig patch controlplane.yaml --patch @patch-talos-cp1.yaml --output talos-cp1.yaml # Configuration pour le nœud talos-cp1talosctl machineconfig patch controlplane.yaml --patch @patch-talos-worker1.yaml --output talos-worker1.yaml # Configuration pour le nœud talos-worker1Déploiement
Section titled “Déploiement”Le déploiement d’un cluster Talos se déroule en plusieurs étapes :
- Configuration du premier Control Plane
- Bootstrap du cluster Kubernetes
- Récupération de la configuration du cluster Kubernetes (kubeconfig)
- Déploiement du CNI
- Déploiement des autres Control Planes
- Déploiement des workers
Avant toute action, définissez la variable d’environnement TALOSCONFIG comme suivant :
export TALOSCONFIG=talosconfigConfiguration du premier Control Plane
Section titled “Configuration du premier Control Plane”Maintenant que vous avez préparé vos configurations, il faut déployer le premier Control Plane qui sera membre de votre cluster Talos.
Ce déploiement va avoir pour effet :
- D’installer Tals sur le disque de la machine
- De configurer le réseau
- De configurér le nécessaire présent dans les configurations (DNS, NTP, certificats, secrets, …)
Pour déployer votre premier Control Plane, exécutez simplement la commande suivante :
talosctl apply-config --insecure -n <adresse_IP_du_CP> -f <configuration_cp>.yamlSi on reprends la commande avec les informations données dans Préparation des hôtes ça donne ça :
talosctl apply-config --insecure -n 192.168.0.101 -f talos-cp1.yamlVous devrez patienter quelques minutes le temps que le nœud télécharge les images nécessaires.
Vous pouvez consulter la console du nœuds, vous devriez voir apparaitre le message suivant :
[talos] task startAllServices (1/1): service "etcd" to be "up"[talos] controller failed {"component": "controller-runtime", "controller": "k8s.NodeApplyController", "error": "1 error(s) occurred:\n\ttimeout"}Lorsque vous avez ce message, vous pouvez modifier la configuration talosconfig comme suivant et passer à l’étape suivante :
talosctl config endpoint <adresse_IP_du_premier_CP>Dans notre cas :
talosctl config endpoint 192.168.0.100Bootstrap Kubernetes
Section titled “Bootstrap Kubernetes”Votre premier CP est actuellement prêt à accueillir le déploiement de Kubernetes.
Il est en attente de l’instruction qui va permettre de :
- Déployer ETCD
- Déployer les composants Kubernetes initiaux (kube-scheduler, kube-controller-manager, kube-apiserver )
Pour ce faire, exécutez la commande suivante :
talosctl bootstrap -n <adresse_IP_du_premier_CP>Dans notre cas :
talosctl bootstrap -n 192.168.0.100Vous devrez attendre d’avoir sur le dashboard plusieurs informations :
- STAGE Running
- READY False
- KUBELET Healthy
- APISERVER Healthy
- CONTROLLER-MANAGER Healthy
- SCHEDULER Healthy
Une fois que toutes ces informations sont validées, vous pouvez passer à la suite.
Récupération du fichier Kubeconfig
Section titled “Récupération du fichier Kubeconfig”Vous pouvez maintenant récupérer la configuration Kubernetes vous permettant de dialoguer avec les API Kubernetes.
Pour ce faire utilisez la commande suivante :
talosctl kubeconfig -n <adresse_IP_du_premier_CP> kubeconfigCette commande va vous permettre d’extraire la configuration kubeconfig dans un fichier du même nom là où vous êtes dans le système.
Dans notre cas :
talosctl kubeconfig -n 192.168.0.100 kubeconfigUne fois fait, vous pouvez exporter la variable d’environnement KUBECONFIG pour pointer votre fichier :
export KUBECONFIG=kubeconfigSi tout va bien, vous pouvez maintenant afficher le status de votre nœud Kubernetes et dialoguer avec lui :
kubectl get nodesNAME STATUS ROLES AGE VERSIONtalos-cp1 NotReady control-plane 2m v1.28.6Si vous afficher les pods, vous verrez que tous les pods Kubernetes sont en status Ready sauf ceux de coredns :
kubectl get pods -ANAMESPACE NAME READY STATUS RESTARTS AGEkube-system coredns-c78fdf99-4kkwp 0/1 Pending 0 6m5skube-system coredns-c78fdf99-x5mcj 0/1 Pending 0 6m5skube-system kube-apiserver-talos-cp1 1/1 Running 0 4m16skube-system kube-controller-manager-talos-cp1 1/1 Running 2 (6m40s ago) 4m59skube-system kube-proxy-vbx6x 1/1 Running 0 5m55skube-system kube-scheduler-talos-cp1 1/1 Running 2 (6m38s ago) 4m53skube-system metrics-server-75bf97fcc9-ftkpp 0/1 Pending 0 4m53skubelet-serving-cert-approver kubelet-serving-cert-approver-58b48cf746-2z8p9 0/1 Pending 0 4m53sDéploiement de Cilium
Section titled “Déploiement de Cilium”Maintenant que la partie Kubernetes minimale est en place, il vous faut déployer la CNI.
Pour déployer Cilium, ma préférence va à Helm. Je trouve que c’est plus élégant et facile à utiliser pour la maintenance courante du CNI.
Ajout des CRDs GatewayAPI
Section titled “Ajout des CRDs GatewayAPI”Pour l’utilisation des GatewayAPI Kubernetes, le chart Helm de Cilium n’intégrant pas l’ajout des CRDs nécessaires, il faut les déployer manuellement en pré-requis au déploiement de Cilium.
On utilise le manifeste fourni par Kubernetes pour faire ce déploiement (pensez à vérifier la version) :
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yamlAjoutez le dépot Cilium
Section titled “Ajoutez le dépot Cilium”Pour ajouter le dépot Helm de Cilium :
helm repo add cilium https://helm.cilium.io/helm repo updateInstaller Cilium
Section titled “Installer Cilium”Pour installer Cilium, Talos nous fourni dans sa documentation les configurations nécessaires minimales.
De mon côté et comme je l’ai précisé en début de documentation, je vais ajouter quelques configurations pour notre cas d’usage.
helm install \ cilium \ cilium/cilium \ --version 1.16.1 \ --namespace kube-system \ --set ipam.mode=kubernetes \ --set kubeProxyReplacement=true \ --set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \ --set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \ --set cgroup.autoMount.enabled=false \ --set cgroup.hostRoot=/sys/fs/cgroup \ --set k8sServiceHost=localhost \ --set k8sServicePort=7445 \ --set gatewayAPI.enabled=true \ --set ingressController.enabled=true \ --set ingressController.loadbalancerMode=shared \ --set nodePort.enabled=true \ --set externalIPs.enabled=true \ --set hostPort.enabled=true \ --set l2announcements.enabled=trueLes parties que j’ai spécifiées dans cette configuration sont :
--set kubeProxyReplacement=true: Définit que Cilium remplace la partie Kube Proxy--set gatewayAPI.enabled=true: On active la feature de Gateway API--set ingressController.enabled=true: On active l’ingressController--set ingressController.loadbalancerMode=shared: On définit l’ingressController comme étant partagé (on y revient)--set nodePort.enabled=true: On autorise l’utilisation des ports--set externalIPs.enabled=true: On autorise l’exposition d’adresse IP externes--set hostPort.enabled=true: On autorise l’exposition des ports sur l’hôte--set l2announcements.enabled=true: On active l’annonce layer 2 pour les adresses IP du Load Balancer (on y revient aussi)
Deux paramètres un peu spécifiques :
ingressController.loadbalancerMode=shared : Ce que l’on vient faire à ce niveau, c’est de dire à l’ingressController déployé par Cilium (Envoy) qu’il utilisera le LoadBalancer de Kubernetes comme étant partagé entre toutes les configurations d’Ingress que l’on définira.
Concrètement, celà revient à avoir une adresse IP qui sera prise par le LoadBalancer et exposée qui traitera l’ensemble des requêtes à destination de l’ingressController.
L’ingressController fourni par Cilium est par défaut configuré en mode dedicated. C’est-à-dire qu’il utilisera une adresse IP
par Ingress déclaré.
Celà peut avoir un intérêt certain dans le cadre de gros clusters Kubernetes avec beaucoup de Workers, ou des Workers dans des réseaux
distincts.
Dans le cadre de cette installation, il n’est pas nécessaire d’avoir d’ingressController dédié vu que l’on ne tourne que sur 3 workers étant sur le même réseau.
l2announcements.enabled=true :
Cet autre paramètre permet d’activer les réponses ARP pour les adresse consommées par le LoadBalancer.
Par défaut, les réponses ARP ne sont pas actives, et de ce fait, les adresses attribuées au LoadBalancer ne seront pas accessibles
par le réseau local.
Après avoir appliqué ce déploiement, vous devriez voir vos pods coredns passer en état Running, et les pods propre à Cilium se déployer
dans le cluster :
kubectl get pods -ANAMESPACE NAME READY STATUS RESTARTS AGEkube-system cilium-envoy-htlmp 1/1 Running 0 4m48skube-system cilium-operator-857d7f4c6d-44672 0/1 Pending 0 4m48skube-system cilium-operator-857d7f4c6d-tq4xq 1/1 Running 0 4m48skube-system cilium-pvk5z 1/1 Running 0 4m48skube-system coredns-c78fdf99-4kkwp 1/1 Running 0 28mkube-system coredns-c78fdf99-x5mcj 1/1 Running 0 28mkube-system kube-apiserver-talostestcp1 1/1 Running 0 26mkube-system kube-controller-manager-talostestcp1 1/1 Running 2 (28m ago) 26mkube-system kube-proxy-vbx6x 1/1 Running 0 27mkube-system kube-scheduler-talostestcp1 1/1 Running 2 (28m ago) 26mkube-system metrics-server-75bf97fcc9-ftkpp 0/1 Pending 0 26mkubelet-serving-cert-approver kubelet-serving-cert-approver-58b48cf746-2z8p9 1/1 Running 0 26mDéploiement des autres Control Planes
Section titled “Déploiement des autres Control Planes”Maintenant que le premier Control Plane est terminé, et que vous avez un cluster Kubernetes établis et « fonctionnel », il est temps d’ajouter les autres Control Planes.
Pour ce faire, répétez la même opération que pour le premier Control Plane :
talosctl apply-config --insecure -n <adresse_IP_du_CP> -f <configuration_cp>.yamlSi on reprends la commande avec les informations données dans Préparation des hôtes ça donne ça :
talosctl apply-config --insecure -n 192.168.0.102 -f talos-cp2.yamlRépétez l’opération pour le troisième Control Plane.
Vous pouvez également passer directement à la suite pour ajouter les workers au cluster.
Toutes fois, je vous recommande d’attendre l’initialisation complète des Control Plane avant afin d’éviter une
potentielle problématique de synchronisation de base ETCD.
Déploiement des Workers
Section titled “Déploiement des Workers”Pour la partie Worker, vous pouvez lancer tous les workers à la suite, celà ne posera pas de problèmes.
Pour déployer les Worker, lancez la même commande que pour les Control Plane, mais en spécifiant les configurations des workers :
talosctl apply-config --insecure -n <adresse_IP_du_worker> -f <configuration_worker>.yamlDans notre cas ça va donner les trois commandes suivantes :
talosctl apply-config --insecure -n 192.168.0.201 -f talos-worker1.yamltalosctl apply-config --insecure -n 192.168.0.202 -f talos-worker2.yamltalosctl apply-config --insecure -n 192.168.0.203 -f talos-worker3.yamlAprès quelques minutes vous aurez vos 6 machines en status Ready lorsque vous lancez un kubectl get nodes et votre
cluster Kubernetes sera prêt à accueillir de la charge de travail.
Le après
Section titled “Le après”Une fois que votre cluster sera complètement déployé et opérationnel, il restera quand même quelques parties afin qu’il soit réellement prêt à accueillir de la production.
Je ne le ferais pas ici parce que cette documentation est déjà bien trop longue à mon goût, mais je me permets de vous lister quelques points.
À grand minima :
- Le déploiement d’un CSI pour la partie stockage
- La configuration du LoadBalancer
Pour considérer le cluster « Production Grade », je vous recommande comme pour tout déploiement de cluster Kubernetes :
- Le déploiement d’une gestion de certificats (cert-manager + trust-manager + gatekeeper (au besoin))
- Le déploiement d’une stack d’observabilité (Prometheus/Loki/Grafana)
- Une solution de sauvegarde