From 7e33d65bf602a1902f19e15084784b9dd13f38dd Mon Sep 17 00:00:00 2001 From: Gitea Actions Date: Thu, 17 Jul 2025 12:06:40 +0000 Subject: [PATCH] Auto-update blog content from Obsidian: 2025-07-17 12:06:40 --- ...te-manual-kubernetes-cluster-kubeadm.fr.md | 187 ++++++++++++++++-- ...reate-manual-kubernetes-cluster-kubeadm.md | 139 +++++++++++-- content/post/random-post.md | 2 +- 3 files changed, 296 insertions(+), 32 deletions(-) diff --git a/content/post/8-create-manual-kubernetes-cluster-kubeadm.fr.md b/content/post/8-create-manual-kubernetes-cluster-kubeadm.fr.md index ac46666..6ff496a 100644 --- a/content/post/8-create-manual-kubernetes-cluster-kubeadm.fr.md +++ b/content/post/8-create-manual-kubernetes-cluster-kubeadm.fr.md @@ -14,37 +14,200 @@ Dans cet [article précédent]({{< ref "post/7-terraform-create-proxmox-module" Maintenant que l'infrastructure est prête, passons à l'étape suivante : **créer manuellement un cluster Kubernetes** avec `kubeadm`. -Dans cet article, je vais détailler chaque étape de l'installation d’un cluster Kubernetes simple, depuis la préparation des nœuds jusqu'au déploiement d'une application simple. +Dans cet article, je vais détailler chaque étape de l'installation d’un cluster Kubernetes simple, depuis la préparation des nœuds jusqu'au déploiement d'une application basique. -Je n'utiliserai pas d'outil d'automatisation pour configurer les nœuds pour le moment, afin de mieux comprendre les étapes impliquées dans le bootstrap d’un cluster Kubernetes. +Je n'utiliserai pas d'outil d'automatisation pour configurer les nœuds pour le moment, afin de mieux comprendre les étapes impliquées dans le bootstrap d’un cluster Kubernetes. L'automatisation sera couverte dans de futurs articles. --- ## Qu'est ce que Kubernetes -Kubernetes est une plateforme open-source qui orchestre des conteneurs sur un ensemble de machines. Elle gère le déploiement, la montée en charge et la santé des applications conteneurisées, ce qui vous permet de vous concentrer sur vos services plutôt que sur l’infrastructure sous-jacente. +Kubernetes est une plateforme open-source qui orchestre des containers sur un ensemble de machines. Elle gère le déploiement, la montée en charge et la santé des applications conteneurisées, ce qui vous permet de vous concentrer sur vos services plutôt que sur l’infrastructure sous-jacente. -Un cluster Kubernetes est composé de deux types de nœuds : les nœuds control plane (masters) et les workers. Le control plane assure la gestion globale du cluster, il prend les décisions de planification, surveille l’état du système et réagit aux événements. Les workers, eux, exécutent réellement vos applications, dans des conteneurs gérés par Kubernetes. +Un cluster Kubernetes est composé de deux types de nœuds : les nœuds control plane (masters) et les workers. Le control plane assure la gestion globale du cluster, il prend les décisions de planification, surveille l’état du système et réagit aux événements. Les workers, eux, exécutent réellement vos applications, dans des containers gérés par Kubernetes. Dans cet article, nous allons mettre en place manuellement un cluster Kubernetes avec 3 nœuds control plane et 3 workers. Cette architecture reflète un environnement hautement disponible et proche de la production, même si l’objectif ici est avant tout pédagogique. La documentation officielle se trouve [ici](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/), je vais utiliser la version **v1.32**. --- -## Prepare the Nodes +## Préparer les Nœuds - OS-level updates and basic tools +Je vais exécuter les étapes suivantes sur les **6 VMs** (masters et workers). - Disabling swap and firewall adjustments +### Hostname - Installing container runtime (e.g., containerd) +Chaque VM possède un **nom d’hôte unique** et tous les nœuds doivent pouvoir **se résoudre entre eux**. - Installing kubeadm and kubelet +Le nom d’hôte est défini à la création de la VM via cloud-init. Mais pour la démonstration, je vais le définir manuellement : +```bash +sudo hostnamectl set-hostname +``` - Installing kubeadm on bastion +Dans mon infrastructure, les nœuds se résolvent via mon serveur DNS sur le domaine `lab.vezpi.me`. Si vous n’avez pas de DNS, vous pouvez inscrire manuellement les IPs des nœuds dans le fichier `/etc/hosts` : +```bash +192.168.66.168 apex-worker +192.168.66.167 apex-master +192.168.66.166 zenith-master +192.168.66.170 vertex-worker +192.168.66.169 vertex-master +192.168.66.172 zenith-worker +``` - Enabling required kernel modules and sysctl settings +### Mises à jour Système -## Initialize the Cluster +Mes VMs tournent sous **Ubuntu 24.04.2 LTS**. Cloud-init s’occupe des mises à jour après le provisionnement, mais on s’assure quand même que tout est bien à jour et on installe les paquets nécessaires pour ajouter le dépôt Kubernetes : +```bash +sudo apt update && sudo apt upgrade -y +sudo apt install -y apt-transport-https ca-certificates curl gpg +``` + +### Swap + +Par défaut, `kubelet` ne démarre pas si une **mémoire swap** est détectée sur un nœud. Il faut donc la désactiver ou la rendre tolérable par `kubelet`. + +Mes VMs ne disposent pas de swap, mais voici comment le désactiver si besoin : +```bash +sudo swapoff -a +sudo sed -i '/ swap / s/^/#/' /etc/fstab +``` + +### Pare-feu + +Dans ce lab, je désactive simplement le pare-feu local (à ne pas faire en production) : +```bash +sudo systemctl disable --now ufw +``` + +En production, vous devez autoriser la communication entre les nœuds sur les ports suivants : +#### Control Plane + +| Protocole | Direction | Ports | Usage | Utilisé par | +| --------- | --------- | --------- | ----------------------- | -------------------- | +| TCP | Entrant | 6443 | API server Kubernetes | Tous | +| TCP | Entrant | 2379-2380 | API client etcd | kube-apiserver, etcd | +| TCP | Entrant | 10250 | API Kubelet | Plan de contrôle | +| TCP | Entrant | 10259 | kube-scheduler | Lui-même | +| TCP | Entrant | 10257 | kube-controller-manager | Lui-même | +#### Worker + +| Protocole | Direction | Ports | Usage | Utilisé par | +| --------- | --------- | ----------- | ----------------- | -------------- | +| TCP | Entrant | 10250 | API Kubelet | Control plane | +| TCP | Entrant | 10256 | kube-proxy | Load balancers | +| TCP | Entrant | 30000-32767 | Services NodePort | Tous | +### Modules noyau et paramètres sysctl + +Kubernetes requiert l’activation de deux modules noyau : +- **overlay** : pour permettre l’empilement de systèmes de fichiers. +- **br_netfilter** : pour activer le filtrage des paquets sur les interfaces bridge. + +Activation des modules : +```bash +cat < /dev/null +``` + +Utiliser `systemd` comme pilote de _cgroup_ : +```bash +sudo sed -i 's/^\(\s*SystemdCgroup\s*=\s*\)false/\1true/' /etc/containerd/config.toml +``` + +Redémarrer et activer le service `containerd` : +```bash +sudo systemctl restart containerd +sudo systemctl enable containerd +``` + +### Paquets Kubernetes + +Dernière étape : installer les paquets Kubernetes. On commence par ajouter le dépôt officiel et sa clé de signature. + +Ajouter la clé : +```bash +curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg +``` + +Ajouter le dépôt : +```bash +echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list +``` + +Installer ensuite les paquets nécessaires : +- `kubeadm` : l’outil pour initier un cluster Kubernetes. +- `kubelet` : l’agent qui s’exécute sur tous les nœuds et qui gère les pods/containers. +- `kubectl` : l’outil en ligne de commande pour interagir avec le cluster. + +Sur les nœuds, on installe `kubelet` et `kubeadm`, puis on les fige : +```bash +sudo apt-get update +sudo apt-get install -y kubelet kubeadm +sudo apt-mark hold kubelet kubeadm +``` + +ℹ️ Je ne gérerai pas le cluster depuis les nœuds eux-mêmes, j’installe `kubectl` sur mon contrôleur LXC à la place : +```bash +sudo apt-get update +sudo apt-get install -y kubectl +sudo apt-mark hold kubectl +``` + +--- +## Initialiser le Cluster + +Une fois tous les nœuds préparés, on peut initialiser le **plan de contrôle** Kubernetes sur le **premier nœud master**. + +### Initialisation + +Exécutez la commande suivante pour lancer la création du cluster: +```bash +sudo kubeadm init \ + --control-plane-endpoint "apex-master.lab.vezpi.me:6443" \ + --upload-certs \ + --pod-network-cidr=10.10.0.0/16 +``` + +**Explications** : +- `--control-plane-endpoint` : un nom DNS pour votre plan de contrôle. +- `--upload-certs` : permet d’ajouter d’autres nœuds maîtres ensuite. +- `--pod-network-cidr` : le sous-réseau à utiliser pour le réseau des Pods (compatible avec Cilium). + +Cette étape va : +- Initialiser etcd et les composants du plan de contrôle. +- Configurer RBAC et les tokens d’amorçage. +- Afficher deux commandes `kubeadm join` importantes : une pour les **workers**, l’autre pour les **maîtres supplémentaires**. + +Vous verrez aussi un message indiquant comment configurer l’accès `kubectl`. + +## Create the Cluster Running kubeadm init diff --git a/content/post/8-create-manual-kubernetes-cluster-kubeadm.md b/content/post/8-create-manual-kubernetes-cluster-kubeadm.md index 0f952bb..14078b1 100644 --- a/content/post/8-create-manual-kubernetes-cluster-kubeadm.md +++ b/content/post/8-create-manual-kubernetes-cluster-kubeadm.md @@ -14,9 +14,9 @@ In this [previous article]({{< ref "post/7-terraform-create-proxmox-module" >}}) Now that the infrastructure is ready, let’s move on to the next step: **manually building a Kubernetes cluster** using `kubeadm`. -In this post, I’ll walk through each step of the installation process of a simple Kubernetes cluster, from preparing the nodes to deploying a simple application. +In this post, I’ll walk through each step of the installation process of a simple Kubernetes cluster, from preparing the nodes to deploying a basic application. -I will not rely on automation tools to configure the nodes for now, to better understand what are the steps involved in a Kubernetes cluster bootstrapping. +I will not rely on automation tools to configure the nodes for now, to better understand what are the steps involved in a Kubernetes cluster bootstrapping. Automation will be covered in future posts. --- ## What is Kubernetes @@ -53,8 +53,7 @@ On my infrastructure, the nodes resolve the hostnames each other using my DNS se 192.168.66.172 zenith-worker ``` -### -OS Updates +### OS Updates My VMs are running **Ubuntu 24.04.2 LTS**. Cloud-init handles the updates after the provision in that case, let's make sure everything is up to date and install packages needed to add Kubernetes repository: ```bash @@ -74,7 +73,7 @@ sudo sed -i '/ swap / s/^/#/' /etc/fstab ### Firewall -For testing environment, I will just disable the local firewall (don't do that in production): +For this lab, I will just disable the local firewall (don't do that in production): ```bash sudo systemctl disable --now ufw ``` @@ -90,11 +89,11 @@ For production, you want to allow the nodes to talk to each other on these ports |TCP|Inbound|10257|kube-controller-manager|Self| #### Worker -|Protocol|Direction|Port Range|Purpose|Used By| -|---|---|---|---|---| -|TCP|Inbound|10250|Kubelet API|Self, Control plane| -|TCP|Inbound|10256|kube-proxy|Self, Load balancers| -|TCP|Inbound|30000-32767|NodePort Services†|All +| Protocol | Direction | Port Range | Purpose | Used By | +| -------- | --------- | ----------- | ------------------ | -------------------- | +| TCP | Inbound | 10250 | Kubelet API | Self, Control plane | +| TCP | Inbound | 10256 | kube-proxy | Self, Load balancers | +| TCP | Inbound | 30000-32767 | NodePort Services† | All | ### Kernel Modules and Settings @@ -137,32 +136,134 @@ sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml > /dev/null ``` -Enable `systemd` cgroup driver: +Enable `systemd` *cgroup* driver: ```bash sudo sed -i 's/^\(\s*SystemdCgroup\s*=\s*\)false/\1true/' /etc/containerd/config.toml ``` -Restart `containerd` service +Restart and enable the `containerd` service ```bash sudo systemctl restart containerd +sudo systemctl enable containerd ``` +### Kubernetes Packages - - Installing kubeadm and kubelet +Last step: install the Kubernetes packages. I start with adding the repository and its signing key. - Installing kubeadm on bastion +Add the key: +```bash +curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg +``` +Add the repository: +```bash +echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list +``` - +Finally I can install the needed packages: +- `kubeadm`: the command to bootstrap the cluster. +- `kubelet`: the component that runs on all of the machines in your cluster and does things like starting pods and containers. +- `kubectl`: the command line util to talk to your cluster. + +On the nodes, update the `apt` package index, install `kubelet` and `kubeadm`, and pin their version: +```bash +sudo apt-get update +sudo apt-get install -y kubelet kubeadm +sudo apt-mark hold kubelet kubeadm +``` + +ℹ️ I will not manage the cluster from my nodes, I install `kubectl` on my LXC controller instead: +```bash +sudo apt-get update +sudo apt-get install -y kubectl +sudo apt-mark hold kubectl +``` + +--- ## Initialize the Cluster - Running kubeadm init +Once all nodes are prepared, it’s time to initialize the Kubernetes control plane on the **first master node**. - Configuring kubectl on the bastion +### Initialization +Run the following command to bootstrap the cluster: +```bash +sudo kubeadm init \ + --control-plane-endpoint "apex-master.lab.vezpi.me:6443" \ + --upload-certs \ + --pod-network-cidr=10.10.0.0/16 +``` - Installing the CNI plugin Cilium +**Explanation**: +- `--control-plane-endpoint`: a DNS name for your control plane. +- `--upload-certs`: Upload the certificates that should be shared across all the control-plane instances to the cluster. +- `--pod-network-cidr`: The subnet for your CNI. +This step will: +- Initialize the `etcd` database and control plane components. +- Set up RBAC and bootstrap tokens. +- Output two important `kubeadm join` commands: one for **workers**, and one for **additional control-plane nodes**. + +You’ll also see a message instructing you to set up your `kubectl` access. + +### Configure `kubectl` + +If you want to manage your cluster from your master node, you can simply copy paste from the output of the `kubeadm init` command: +```bash +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +If you prefer to control the cluster from elsewhere, in my case my from my LXC bastion: +```bash +mkdir -p $HOME/.kube +scp :/etc/kubernetes/admin.conf $HOME/.kube/config +chmod 600 ~/.kube/config +``` + +Verify your access: +```bash +kubectl get nodes +``` + +ℹ️ You should see only the first master listed (in "NotReady" state until the CNI is deployed). + +### Install the CNI plugin Cilium + +From the [Cilium documentation](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/), there are 2 common ways for installing the CNI: using the **Cilium CLI** or **Helm**, for that lab I will use the CLI tool. + +#### Install the Cilium CLI + +The Cilium CLI can be used to install Cilium, inspect the state of a Cilium installation, and enable/disable various features (e.g. `clustermesh`, `Hubble`): +```bash +CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt) +curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz{,.sha256sum} +sha256sum --check cilium-linux-amd64.tar.gz.sha256sum +sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin +rm cilium-linux-amd64.tar.gz{,.sha256sum} +``` + +#### Install Cilium + +Install Cilium into the Kubernetes cluster pointed to by your current kubectl context: +```bash +cilium install --version 1.17.6 +``` + +#### Validate the installation + +To validate that Cilium has been properly installed, you can run: +```bash +cilium status --wait +``` + +Run the following command to validate that your cluster has proper network connectivity: +```bash +cilium connectivity test +``` + +Once installed, the master node should transition to **Ready** status. ## Join Additional Nodes diff --git a/content/post/random-post.md b/content/post/random-post.md index 5e11b3e..5775dda 100644 --- a/content/post/random-post.md +++ b/content/post/random-post.md @@ -13,4 +13,4 @@ I'm ==testing== ## Emoji -🚀💡🔧🔁⚙️📝📌⚠️✅🍒❌ \ No newline at end of file +🚀💡🔧🔁⚙️📝📌⚠️✅🍒❌ℹ️ \ No newline at end of file