Aller au contenu

Ressources de base de Kubernetes

Mise à jour :

logo kubernetes

Dans Kubernetes, tout tourne autour des ressources. Ces objets représentent les éléments clés de votre infrastructure : vos applications, leur configuration, leur exposition au réseau et bien plus encore. Pour bien démarrer avec Kubernetes, il est indispensable de comprendre ces ressources fondamentales et leur rôle dans l’écosystème.

Dans cette partie de la formation, nous allons explorer les NameSpaces, Pods, Services, Deployments, ainsi que les ConfigMaps et Secrets. Ces ressources constituent les briques de base sur lesquelles tout est construit. En maîtrisant leur fonctionnement, vous serez capable de :

  • Déployer vos applications de manière cohérente.
  • Exposer vos services aux utilisateurs internes ou externes.
  • Gérer les configurations et les données sensibles efficacement.

Prérequis

Avant de plonger dans ce guide, il est important de s’assurer que vous avez les bases nécessaires pour tirer le meilleur parti des concepts abordés. Voici ce qu’il faut maîtriser :

  1. Connaissances en ligne de commande Linux

    • Être à l’aise avec les commandes de base dans un terminal.
    • Savoir naviguer dans un système de fichiers et exécuter des commandes simples.
  2. Connaissances de base sur Kubernetes

    • Comprendre l’architecture globale (plan de contrôle, nœuds de travail).
    • Savoir ce qu’est un cluster Kubernetes et comment il fonctionne.
  3. Un environnement Kubernetes opérationnel

    • Avoir installé un “Mini Kubernetes”, comme Minikube, K3s, ou Kind.
    • Vérifier que kubectl est configuré et fonctionne avec votre cluster.
  4. Connaissance de la CLI Kubernetes : kubectl

Si ces prérequis sont en place, vous êtes prêt à démarrer ce guide et à explorer en profondeur les ressources essentielles de Kubernetes.

Les Pods

Les services : Exposer et connecter vos pods

Les services sont une ressource essentielle de Kubernetes qui permet de connecter vos pods entre eux ou de les rendre accessibles à l’extérieur du cluster. Alors que les pods sont éphémères et peuvent être recréés à tout moment, les services offrent un point d’accès stable et persistent, facilitant la communication dans vos applications.

Qu’est-ce qu’un service

Un service agit comme une couche d’abstraction réseau pour un ensemble de pods. Il fournit :

  • Une adresse IP et un port fixe pour accéder aux pods correspondants.
  • Une méthode pour répartir le trafic (load balancing) entre plusieurs pods.

Un service sélectionne les pods à gérer à l’aide de labels et de selectors, ce qui permet de définir dynamiquement quels pods font partie du service.

Types de services

  1. ClusterIP

    • Par défaut, le service est uniquement accessible depuis l’intérieur du cluster.
    • Idéal pour connecter des composants internes, comme un backend qui communique avec une base de données.
  2. NodePort

    • Permet d’exposer un service à l’extérieur du cluster via un port spécifique sur chaque nœud.
    • Utile pour des tests ou des déploiements simples sans gestion avancée du trafic.
  3. LoadBalancer

    • Utilisé principalement dans les environnements cloud.
    • Configure automatiquement un équilibrage de charge pour rendre un service accessible depuis Internet.
  4. ExternalName

    • Redirige les requêtes vers un nom DNS externe.
    • Utile pour connecter des applications à des services externes.

Cas d’utilisation des services

  1. Communication interne entre pods

    • Exemple : Un frontend communique avec un backend via un service ClusterIP.
  2. Accès aux applications depuis l’extérieur

    • Exemple : Une API exposée à des clients via un service LoadBalancer.
  3. Gestion de la persistance

    • Un service garantit que même si un pod est recréé ou déplacé, l’adresse d’accès reste stable.

Fonctionnement des services

  1. Découverte de service Kubernetes intègre un DNS interne qui permet aux pods de résoudre automatiquement les noms des services en adresses IP. Par exemple, un pod peut accéder à un service appelé backend via backend.default.svc.cluster.local.

  2. Sélection dynamique de pods Les services utilisent des labels pour déterminer quels pods sont connectés. Si un pod avec les labels correspondants est ajouté ou supprimé, le service s’adapte automatiquement.

  3. Répartition du trafic Les services répartissent les requêtes entrantes entre tous les pods correspondants, assurant un équilibre de charge simple.

Commandes de base kubectl

  • Lister les services dans le cluster :

    Terminal window
    kubectl get services -A
    NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m42s
    kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 9m41s
  • Obtenir les détails d’un service :

    Terminal window
    kubectl describe service kube-dns -n kube-system
    Name: kube-dns
    Namespace: kube-system
    Labels: k8s-app=kube-dns
    kubernetes.io/cluster-service=true
    kubernetes.io/name=CoreDNS
    Annotations: prometheus.io/port: 9153
    prometheus.io/scrape: true
    Selector: k8s-app=kube-dns
    Type: ClusterIP
    IP Family Policy: SingleStack
    IP Families: IPv4
    IP: 10.96.0.10
    IPs: 10.96.0.10
    Port: dns 53/UDP
    TargetPort: 53/UDP
    Endpoints: 10.244.0.4:53,10.244.0.5:53
    Port: dns-tcp 53/TCP
    TargetPort: 53/TCP
    Endpoints: 10.244.0.4:53,10.244.0.5:53
    Port: metrics 9153/TCP
    TargetPort: 9153/TCP
    Endpoints: 10.244.0.4:9153,10.244.0.5:9153
    Session Affinity: None
    Events: <none>

Voici une explication détaillée des informations importantes fournies par cette commande concernant le service Kubernetes kube-dns.

  • Type: ClusterIP Ce service est de type ClusterIP, ce qui signifie qu’il est accessible uniquement à l’intérieur du cluster via une adresse IP interne.

  • Ports et targetPorts:

    • dns 53/UDP Le service est accessible sur le port 53 en UDP, qui est le port standard pour les requêtes DNS.
      • TargetPort: 53/UDP Le port sur lequel les pods cibles (CoreDNS) écoutent réellement pour le trafic DNS UDP.
    • dns-tcp 53/TCP Même fonction que ci-dessus, mais pour les requêtes DNS utilisant TCP.
      • TargetPort: 53/TCP Le port TCP correspondant sur les pods cibles.
    • metrics 9153/TCP Ce port est utilisé pour exposer des métriques liées au DNS, accessibles sur le port 9153 via TCP.
      • TargetPort: 9153/TCP Le port sur lequel les pods cibles exposent les métriques.
  • Endpoints:

    • 10.244.0.4:53,10.244.0.5:53 Les adresses IP des pods cibles (CoreDNS) et les ports sur lesquels ils écoutent. Ces endpoints représentent les instances effectives du service.
    • Les mêmes endpoints sont exposés pour le DNS (ports 53 UDP/TCP) et pour les métriques (port 9153 TCP).

Les deployments : Gérer vos applications à grande échelle

Les deployments sont une abstraction essentielle de Kubernetes, conçue pour déployer et gérer vos pods de manière déclarative et automatisée. Ils offrent des fonctionnalités avancées comme le scaling, les mises à jour progressives et la tolérance aux pannes, simplifiant la gestion de vos applications.

Qu’est-ce qu’un deployment

Un deployment gère les pods et les ReplicaSets pour garantir que vos applications s’exécutent dans l’état souhaité. Contrairement aux pods créés directement, les pods gérés par un deployment sont automatiquement recréés ou redéployés si nécessaire.

Pourquoi utiliser un deployment

  1. Automatisation des tâches complexes

    • Les deployments gèrent automatiquement la création, la mise à jour et la suppression des pods.
    • Ils garantissent un nombre constant de réplicas.
  2. Mises à jour sans interruption

    • Les rolling updates permettent de déployer une nouvelle version de votre application sans interrompre le service.
  3. Revenir facilement en arrière

    • Les rollbacks permettent de revenir rapidement à une version précédente en cas de problème.

Commandes de base avec kubectl

  • Créer un deployment :

    Terminal window
    kubectl create deployment nom-deployment --image=image-name
  • Mettre à jour un deployment :

    Terminal window
    kubectl set image deployment/nom-deployment container-name=new-image
  • Lister les deployments :

    Terminal window
    kubectl get deployments
  • Supprimer un deployment :

    Terminal window
    kubectl delete deployment nom-deployment

ConfigMaps et Secrets : Gérer les configurations et les données sensibles

Dans Kubernetes, la gestion des configurations et des données sensibles est une nécessité pour séparer le code de son environnement d’exécution. C’est ici qu’interviennent les ConfigMaps et les Secrets, deux ressources essentielles pour injecter des paramètres et des informations confidentielles dans vos pods.

Qu’est-ce qu’un ConfigMap

Un ConfigMap est une ressource qui permet de stocker des données non sensibles sous forme de paires clé-valeur. Il est utilisé pour externaliser des configurations de votre application, comme des URL d’API, des paramètres, ou des fichiers de configuration.

Qu’est-ce qu’un Secret

Un Secret est similaire à un ConfigMap, mais il est conçu pour stocker des données sensibles, comme des mots de passe, des clés API, ou des certificats. Les données dans un Secret sont encodées en Base64 et peuvent être configurées pour être mieux sécurisées.

Pourquoi utiliser ConfigMaps et Secrets

  1. Séparation des préoccupations

    • Le code de l’application reste identique, tandis que les paramètres et configurations spécifiques à l’environnement sont gérés séparément.
  2. Flexibilité

    • Les configurations peuvent être modifiées sans avoir à redéployer l’application.
  3. Sécurité

    • Les Secrets permettent de gérer des informations sensibles de manière plus sûre, en évitant leur inclusion dans le code ou les fichiers manifest.

Fonctionnement

  1. Création

    • Les ConfigMaps et Secrets sont créés comme des objets Kubernetes indépendants.
  2. Injection dans les pods

    • Ils peuvent être montés comme volumes, injectés comme variables d’environnement, ou utilisés directement dans des fichiers de configuration.
  3. Mise à jour dynamique

    • Les pods peuvent utiliser les nouvelles valeurs des ConfigMaps sans redémarrage, selon leur configuration.

Commandes de base avec kubectl

  • Créer un ConfigMap :

    Terminal window
    kubectl create configmap nom-configmap --from-literal=cle=valeur
  • Créer un Secret :

    Terminal window
    kubectl create secret generic nom-secret --from-literal=cle=valeur
  • Voir un ConfigMap ou un Secret :

    Terminal window
    kubectl get configmap
    kubectl get secret
  • Supprimer un ConfigMap ou un Secret :

    Terminal window
    kubectl delete configmap nom-configmap
    kubectl delete secret nom-secret

Les Namespaces : Organiser et Isoler vos Ressources dans Kubernetes

Dans un cluster Kubernetes, les namespaces permettent de segmenter, organiser et isoler les ressources. Ils sont particulièrement utiles lorsque vous gérez plusieurs projets, environnements ou équipes dans un même cluster. Grâce aux namespaces, il devient plus facile de structurer et de sécuriser vos ressources.

Qu’est-ce qu’un namespace ?

Un namespace est une division logique au sein d’un cluster Kubernetes. Pensez-y comme un espace virtuel dans lequel vous pouvez créer et gérer des ressources (pods, services, configmaps, etc.). Chaque namespace est indépendant des autres, bien qu’il partage les mêmes ressources physiques (CPU, mémoire, stockage) du cluster.

Pourquoi utiliser des namespaces ?

  1. Organisation Les namespaces permettent de regrouper les ressources par projet, application ou environnement (par exemple : développement, test, production).

  2. Isolation Chaque namespace est isolé des autres. Les ressources d’un namespace ne peuvent pas accéder directement à celles d’un autre sans configuration explicite.

  3. Gestion des quotas Kubernetes permet de définir des quotas de ressources (CPU, mémoire, etc.) au niveau des namespaces pour éviter qu’un projet ne monopolise les ressources du cluster.

  4. Facilité d’administration En segmentant les ressources, il devient plus facile de gérer les permissions avec Role-Based Access Control (RBAC).

Namespaces par défaut dans Kubernetes

Lorsque vous créez un cluster Kubernetes, plusieurs namespaces sont déjà disponibles :

  • default : Utilisé si aucun namespace spécifique n’est mentionné.
  • kube-system : Contient les composants internes du cluster (API Server, Scheduler, etc.).

Commandes de base avec kubectl

  • Lister tous les namespaces :

    Terminal window
    kubectl get namespaces
  • Créer un namespace :

    Terminal window
    kubectl create namespace mon-namespace
    namespace/mon-namespace created
  • Travailler dans un namespace spécifique :

    Terminal window
    kubectl get pods -n mon-namespace
    No resources found in mon-namespace namespace.
  • Changer temporairement de namespace par défaut :

    Terminal window
    kubectl config set-context --current --namespace=mon-namespace
    Context "kind-kind" modified.

Mise en œuvre des ressources Kubernetes

Dans ce chapitre, nous allons explorer comment créer et gérer des ressources Kubernetes comme les pods, services, configmaps et secrets en utilisant le mode impératif. Cette approche permet de rapidement tester ou déployer des ressources sans écrire de fichiers YAML, ce qui peut être utile pour des tests ou des environnements temporaires.

Créer un pod

Lancer un pod contenant un conteneur nginx avec une commande impérative :

Terminal window
kubectl run nginx-pod --image=nginx --restart=Never

Vérifier que le pod a été créé :

Terminal window
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 0/1 ContainerCreating 0 4s

Afficher les logs du pod pour vérifier qu’il fonctionne :

Terminal window
kubectl logs nginx-pod
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/12/09 10:56:43 [notice] 1#1: using the "epoll" event method
2024/12/09 10:56:43 [notice] 1#1: nginx/1.27.3
2024/12/09 10:56:43 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/12/09 10:56:43 [notice] 1#1: OS: Linux 6.8.0-48-generic
2024/12/09 10:56:43 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/12/09 10:56:43 [notice] 1#1: start worker processes
2024/12/09 10:56:43 [notice] 1#1: start worker process 54

Créer un service pour exposer le pod

Exposer le pod nginx-pod via un service de type NodePort pour le rendre accessible localement :

Terminal window
kubectl expose pod nginx-pod --type=NodePort --port=80
service/nginx-pod exposed

Lister les services pour obtenir le port d’accès :

Terminal window
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-pod NodePort 10.96.191.168 <none> 80:30276/TCP 16s

On recherche l’IP du node :

Terminal window
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kind-control-plane Ready control-plane 3h39m v1.31.2 172.18.0.2 <none> Debian GNU/Linux 12 (bookworm) 6.8.0-48-generic containerd://1.7.18

Tester l’accès local :

Terminal window
curl http://172.18.0.2:30276
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Créer un ConfigMap

Créer un ConfigMap contenant une configuration simple :

Terminal window
kubectl create configmap app-config --from-literal=ENV=production --from-literal=VERSION=1.0
configmap/app-config created

Lister les ConfigMaps pour vérifier la création :

Terminal window
kubectl get configmap
NAME DATA AGE
app-config 2 19s
kube-root-ca.crt 1 10m

Voir le contenu du ConfigMap :

Terminal window
kubectl describe configmap app-config
Name: app-config
Namespace: mon-namespace
Labels: <none>
Annotations: <none>
Data
====
ENV:
----
production
VERSION:
----
1.0
BinaryData
====
Events: <none>

Créer un Secret

Créer un Secret pour stocker une clé API :

Terminal window
kubectl create secret generic api-secret --from-literal=API_KEY=mysecretkey123
secret/api-secret created

Vérifier la création :

Terminal window
kubectl get secret
NAME TYPE DATA AGE
api-secret Opaque 1 5s

Afficher les détails encodés :

Terminal window
kubectl describe secret api-secret
Name: api-secret
Namespace: mon-namespace
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
API_KEY: 14 bytes

Décoder la clé pour la lire :

Terminal window
kubectl get secret api-secret -o jsonpath="{.data.API_KEY}" | base64 --decode
mysecretkey123

Limites du mode impératif

Bien que rapide et pratique pour des tests locaux, le mode impératif présente des limites importantes :

  • Pas de traçabilité : Les configurations créées directement dans le terminal ne sont pas versionnées ni documentées.
  • Difficulté de réplication : Reproduire une infrastructure exacte devient difficile sans un fichier YAML décrivant les ressources.
  • Manque de standardisation : Il est plus difficile de collaborer ou d’automatiser les déploiements avec cette approche.

Nettoyer les ressources créées

Pour supprimer les ressources créées lors des tests en mode impératif, voici les commandes nécessaires :

Supprimer le pod nginx-pod :

Terminal window
kubectl delete pod nginx-pod

Supprimer le service exposant le pod :

Terminal window
kubectl delete service nginx-pod

Supprimer le ConfigMap app-config :

Terminal window
kubectl delete configmap app-config

Supprimer le Secret api-secret :

Terminal window
kubectl delete secret api-secret

Pour s’assurer que toutes les ressources ont bien été supprimées, vous pouvez lister les ressources restantes :

Terminal window
kubectl get all
kubectl get configmap
kubectl get secret

Conclusion

Félicitations, vous avez maintenant une bonne compréhension des ressources de base dans Kubernetes : pods, services, configmaps et secrets. Ces briques essentielles forment le socle sur lequel vous pouvez construire et gérer vos applications conteneurisées.

En expérimentant avec le mode impératif, vous avez appris à rapidement déployer et manipuler ces ressources. Toutefois, nous avons également vu les limites de cette approche pour des environnements complexes ou collaboratifs. La prochaine étape naturelle est de passer au mode déclaratif en écrivant vos premiers manifests YAML.

Avec cette méthode, vous pourrez :

  • Versionner vos configurations pour une meilleure traçabilité.
  • Répliquer vos déploiements sur différents environnements.
  • Automatiser vos workflows avec des pipelines CI/CD robustes.

Dans le prochain guide, nous aborderons l’écriture et la gestion de votre premier manifest Kubernetes, pour exploiter tout le potentiel de Kubernetes. Préparez votre éditeur de code et votre curiosité, car nous allons franchir une grosse étape vers la maîtrise de Kubernetes. 🚀