Série de webinaires: Un aperçu de Kubernetes

introduction

Kubernetes est un outil d’orchestration de conteneur open source permettant de gérer des applications conteneurisées. Dans le tutoriel previous de cette série, vous avez configuré Kubernetes sur DigitalOcean. Maintenant que le cluster est opérationnel, vous pouvez y déployer des applications conteneurisées.

Dans ce didacticiel, vous apprendrez comment ces primitives fonctionnent ensemble lors du déploiement d’un pod dans Kubernetes, de son exposition en tant que service et de sa mise à l’échelle via un contrôleur de réplication.

Conditions préalables

Pour compléter ce didacticiel, vous devez d’abord terminer le didacticiel précédent de cette série, Démarrer avec Kubernetes.

Étape 1 - Comprendre les primitives Kubernetes

Kubernetes expose une API que les clients utilisent pour créer, mettre à l’échelle et mettre fin aux applications. Chaque opération cible un ou plusieurs objets gérés par Kubernetes. Ces objets constituent les blocs de construction de base de Kubernetes. Ce sont les primitives par lesquelles vous gérez les applications conteneurisées.

Voici un résumé des principaux objets API de Kubernetes:

  • * Clusters *: pool de ressources de calcul, de stockage et de réseau.

  • * Nœuds *: ordinateurs hôtes s’exécutant dans le cluster.

  • * Namespaces *: partitions logiques d’un cluster.

  • * Pods *: Unités de déploiement.

  • * Étiquettes * et * sélecteurs *: paires clé-valeur pour l’identification et la découverte de services.

  • * Services *: Collection de pods appartenant à la même application.

  • * Jeu de répliques *: garantit la disponibilité et l’évolutivité.

  • * Déploiement *: gère le cycle de vie des applications.

Voyons cela plus en détail.

Les Nodes qui exécutent un cluster Kubernetes sont également traités comme des objets. Ils peuvent être gérés comme n’importe quel autre objet API de Kubernetes. Pour activer la séparation logique des applications, Kubernetes prend en charge la création de Namespaces. Par exemple, une organisation peut partitionner logiquement un cluster Kubernetes pour exécuter des environnements de développement, de test, de transfert et de production. Chaque environnement peut être placé dans un espace de noms dédié, géré indépendamment. Kubernetes expose son API via le Master Node.

Bien que Kubernetes exécute des conteneurs Docker, ceux-ci ne peuvent pas être déployés directement. Au lieu de cela, les applications doivent être empaquetées dans un format compris par Kubernetes. Ce format permet à Kubernetes de gérer efficacement les applications conteneurisées. Ces applications peuvent contenir un ou plusieurs conteneurs devant fonctionner ensemble.

L’unité fondamentale d’empaquetage et de déploiement dans Kubernetes est appelée un Pod. Chaque pod peut contenir un ou plusieurs conteneurs à gérer ensemble. Par exemple, un conteneur de serveur Web (Nginx) et un conteneur de cache (Redis) peuvent être regroupés en tant que pod. Kubernetes traite tous les conteneurs appartenant à un pod comme une unité logique. Chaque fois qu’un nouveau pod est créé, il en résulte la création de tous les conteneurs déclarés dans la définition du pod. Tous les conteneurs d’un pod partagent le même contexte, tel que l’adresse IP, le nom d’hôte et le stockage. Ils communiquent entre eux par le biais d’une communication interprocessus (IPC) plutôt que d’appels distants ou d’API REST.

Une fois les conteneurs empaquetés et déployés sur Kubernetes, ils doivent être exposés pour un accès interne et externe. Certains conteneurs, tels que les bases de données et les caches, n’ont pas besoin d’être exposés au monde extérieur. Etant donné que les API et les interfaces Web seront directement accessibles aux autres consommateurs et utilisateurs finaux, ils devront être exposés au public. Dans Kubernetes, les conteneurs sont exposés en interne ou en externe en fonction d’une stratégie. Ce mécanisme réduira les risques d’exposition du public à des charges de travail sensibles telles que des bases de données.

Les pods de Kubernetes sont exposés via Services. Chaque service est déclaré en tant que point de terminaison interne ou externe avec les informations de port et de protocole. Les consommateurs internes, y compris les autres pods, et les consommateurs externes, tels que les clients API, s’appuient sur les services Kubernetes pour une interaction de base. Les services prennent en charge les protocoles TCP et UDP.

Chaque objet de Kubernetes, tel qu’un pod ou un service, est associé à des métadonnées supplémentaires appelées Labels et Selectors. Les étiquettes sont des paires clé / valeur attachées à un objet Kubernetes. Ces étiquettes identifient de manière unique un ou plusieurs objets API. Les sélecteurs associent un objet Kubernetes à un autre. Par exemple, un sélecteur défini dans un service aide Kubernetes à trouver tous les pods avec une étiquette correspondant à la valeur du sélecteur. Cette association permet la découverte dynamique des objets. Les nouveaux objets créés au moment de l’exécution avec les mêmes étiquettes seront immédiatement découverts et associés aux sélecteurs correspondants. Ce mécanisme de découverte de service permet une configuration dynamique efficace, telle que des opérations d’extension et d’extinction.

L’un des avantages du passage aux conteneurs est une mise à l’échelle rapide. Les conteneurs étant légers comparés aux machines virtuelles, vous pouvez les faire évoluer en quelques secondes. Pour une configuration hautement disponible et évolutive, vous devez déployer plusieurs instances de vos applications et vous assurer qu’un nombre minimum d’instances de ces applications sont toujours en cours d’exécution. Pour traiter cette configuration d’applications conteneurisées, Kubernetes a introduit le concept de ensembles de répliques, conçus pour exécuter un ou plusieurs pods à tout moment. Lorsque plusieurs instances de pod doivent être exécutées dans un cluster, elles sont regroupées en tant que jeux de répliques. Kubernetes s’assurera que le nombre de pods définis dans le jeu de réplicas est toujours en mode de fonctionnement. Si un pod est arrêté en raison d’un problème matériel ou de configuration, le plan de contrôle de Kubernetes lancera immédiatement un autre pod.

Un objet Deployment est une combinaison de pods et de jeux de répliques. Cette primitive apporte des fonctionnalités de type PaaS aux applications Kubernetes. Il vous permet d’effectuer une mise à niveau progressive d’un déploiement existant avec un temps d’immobilisation minimal. Les déploiements permettent également des modèles tels que les déploiements canaries et les déploiements bleu / vert. Ils gèrent les éléments essentiels de la gestion du cycle de vie des applications (ALM) des applications conteneurisées.

Étape 2 - Liste des noeuds Kubernetes et des espaces de noms

En supposant que vous ayez suivi les étapes pour réglez le cluster Kubernetes dans DigitalOcean, exécutez les commandes suivantes pour répertorier tous les Nœuds et espaces de noms disponibles:

kubectl get nodes
OutputNAME                  STATUS    ROLES     AGE       VERSION
spc3c97hei-master-1   Ready     master    10m       v1.8.7
spc3c97hei-worker-1   Ready     <none>    4m        v1.8.7
spc3c97hei-worker-2   Ready     <none>    4m        v1.8.7
kubectl get namespaces
OutputNAME                STATUS    AGE
default             Active    11m
kube-public         Active    11m
kube-system         Active    11m
stackpoint-system   Active    4m

Quand aucun espace de noms n’est spécifié, + kubectl + cible l’espace de noms par défaut.

Lançons maintenant une application.

[[step-3–-creating-and-deploying-a-pod]] === Étape 3 - Création et déploiement d’un pod

Les objets Kubernetes sont déclarés dans des fichiers YAML et soumis à Kubernetes via la CLI + kubectl +. Définissons un pod et déployez-le.

Créez un nouveau fichier YAML nommé + Simple-Pod.yaml +:

nano Simple-Pod.yaml

Ajoutez le code suivant qui définit un pod avec un conteneur basé sur le serveur Web Nginx. Il est exposé sur le port + 80 + via le protocole TCP. Notez que la définition contient les étiquettes + nom + et + env +. Nous utiliserons ces étiquettes pour identifier et configurer des pods spécifiques.

Simple-Pod.yaml

apiVersion: "v1"
kind: Pod
metadata:
 name: web-pod
 labels:
   name: web
   env: dev
spec:
 containers:
   - name: myweb
     image: nginx
     ports:
       - containerPort: 80
         name: http
         protocol: TCP

Exécutez la commande suivante pour créer un pod.

kubectl create -f Simple-Pod.yaml
Outputpod "web-pod" created

Vérifions la création du pod.

kubectl get pods
OutputNAME      READY     STATUS    RESTARTS   AGE
web-pod   1/1       Running   0          2m

Dans la prochaine étape, nous allons rendre ce pod accessible au public sur Internet.

Étape 4 - Exposer les pods à travers un service

Les services exposent un ensemble de pods de manière interne ou externe. Définissons un service qui rend le module Nginx accessible au public. Nous exposerons Nginx via un NodePort, un schéma rendant le pod accessible via un port arbitraire ouvert sur chaque nœud du cluster.

Créez un nouveau fichier appelé + Simple-Service.yaml + qui contient ce code qui définit le service pour Nginx:

Simple-Service.yaml

apiVersion: v1
kind: Service
metadata:
 name: web-svc
 labels:
   name: web
   env: dev
spec:
 selector:
   name: web
 type: NodePort
 ports:
   - port: 80
     name: http
     targetPort: 80
     protocol: TCP

Le service découvre tous les pods dans le même espace de noms qui correspondent à l’étiquette avec + name: web +. La section de sélection du fichier YAML définit explicitement cette association.

Nous spécifions que le service est de type NodePort via le type: déclaration NodePort.

Puis utilisez pour le soumettre au cluster.

kubectl create -f Simple-Service.yml

Vous verrez cette sortie indiquant que le service a été créé avec succès:

Outputservice "web-svc" created

Voyons le port sur lequel le pod est disponible.

kubectl get services
OutputNAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.3.0.1     <none>        443/TCP        28m
     NodePort    10.3.0.143   <none>        80:32097/TCP   38s

À partir de cette sortie, nous voyons que le service est disponible sur le port + 32097 +. Essayons de nous connecter à l’un des nœuds de travail.

Utilisez la console DigitalOcean pour obtenir l’adresse IP de l’un des nœuds de travail.

image: https: //assets.digitalocean.com/articles/webinar_4_kubernetes_closer_look/kB9HmSK.png [Les gouttelettes de la console DigitalOcean associées à votre cluster Kubernetes.]

Utilisez la commande + curl + pour envoyer une requête HTTP à l’un des noeuds du port + 31930 +.

curl http://:32097

La réponse contenant la page d’accueil par défaut de Nginx s’affiche:

Output<!DOCTYPE html>
<html>
 <head>
   <title>Welcome to nginx!</title>
...
    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>

Vous avez défini un pod et un service. Examinons maintenant la mise à l’échelle avec les jeux de réplicas.

Étape 5 - Mise à l’échelle des pods via un jeu de répliques

Un ensemble de répliques garantit qu’au moins un nombre minimal de pods sont en cours d’exécution dans le cluster. Supprimons le pod actuel et recréons trois pods à travers le jeu de répliques.

Tout d’abord, supprimez le pod existant.

kubectl delete pod web-pod
Outputpod "web-pod" deleted

Créez maintenant une nouvelle déclaration de jeu de réplicas. La définition du jeu de répliques est identique à celle d’un pod. La principale différence réside dans le fait qu’il contient l’élément réplica qui définit le nombre de pods à exécuter. Comme un pod, il contient également des étiquettes en tant que métadonnées qui facilitent la découverte de services.

Créez le fichier + Simple-RS.yml + et ajoutez ce code au fichier:

Simple-RS.yml

apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
 name: web-rs
 labels:
   name: web
   env: dev
spec:
 replicas: 3
 selector:
   matchLabels:
     name: web
 template:
   metadata:
     labels:
       name: web
       env: dev
   spec:
     containers:
     - name: myweb
       image: nginx
         ports:
           - containerPort: 80
             name: http
             protocol: TCP

Enregistrez et fermez le fichier.

Maintenant, créez le jeu de répliques:

kubectl create -f Simple-RS.yml
Outputreplicaset "web-rs" created

Puis vérifiez le nombre de pods:

kubectl get pods
OutputNAME           READY     STATUS    RESTARTS   AGE
web-rs-htb58   1/1       Running   0          38s
web-rs-khtld   1/1       Running   0          38s
web-rs-p5lzg   1/1       Running   0          38s

Lorsque nous accédons au service via NodePort, la demande sera envoyée à l’un des pods gérés par l’ensemble de répliques.

Testons la fonctionnalité d’un jeu de répliques en supprimant l’un des pods et en observant ce qui se passe:

kubectl delete pod web-rs-p5lzg
Outputpod "web-rs-p5lzg" deleted

Regardez les gousses à nouveau:

kubectl get pods
OutputNAME           READY     STATUS              RESTARTS   AGE
web-rs-htb58   1/1       Running             0          2m
web-rs-khtld   1/1       Running             0          2m

web-rs-p5lzg   1/1       Running             0          2m
web-rs-p5lzg   0/1       Terminating         0          2m

Dès que le pod est supprimé, Kubernetes en a créé un autre pour garantir le maintien du nombre souhaité.

Voyons maintenant les déploiements.

Étape 6 - Faire face aux déploiements

Bien que vous puissiez déployer des conteneurs en tant que pods et ensembles de répliques, les déploiements facilitent la mise à niveau et la correction de votre application. Vous pouvez mettre à niveau un pod sur place à l’aide d’un déploiement, ce que vous ne pouvez pas faire avec un jeu de réplicas. Cela permet de déployer une nouvelle version d’une application avec un temps d’indisponibilité minimal. Ils apportent des fonctionnalités de type PaaS à la gestion des applications.

Supprimez le jeu de réplicas existant avant de créer un déploiement. Cela supprimera également les pods associés:

kubectl delete rs web-rs
Outputreplicaset "web-rs" deleted

Définissez maintenant un nouveau déploiement. Créez le fichier + Simple-Deployment.yaml + et ajoutez le code suivant:

Simple-Deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
 name: web-dep
 labels:
   name: web
   env: dev
spec:
 replicas: 3
 selector:
   matchLabels:
     name: web
 template:
   metadata:
     labels:
       name: web
   spec:
     containers:
     - name: myweb
       image: nginx
       ports:
       - containerPort: 80

Créez un déploiement et vérifiez la création.

kubectl create -f Simple-Deployment.yml
Outputdeployment "web-dep" created

Voir les déploiements:

kubectl get deployments
OutputNAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
web-dep   3         3         3            3           1m

Étant donné que le déploiement entraîne la création de pods, trois pods seront exécutés conformément à la déclaration des réplicas dans le fichier YAML.

kubectl get pods
OutputNAME                       READY     STATUS    RESTARTS   AGE
web-dep-8594f5c765-5wmrb   1/1       Running   0          2m
web-dep-8594f5c765-6cbsr   1/1       Running   0          2m
web-dep-8594f5c765-sczf8   1/1       Running   0          2m

Le service que nous avons créé précédemment continuera à acheminer les demandes aux pods créés par le déploiement. C’est à cause des étiquettes qui contiennent les mêmes valeurs que la définition originale du pod.

Nettoyez les ressources en supprimant Déploiement et service.

kubectl delete deployment web-dep
Outputdeployment "web-dep" deleted
kubectl delete service web-svc
Outputservice "web-svc" deleted

Pour plus de détails sur les déploiements, reportez-vous à la Kubernetes documentation.

Conclusion

Dans ce didacticiel, vous avez exploré les éléments de base de Kubernetes lors du déploiement d’un serveur Web Nginx à l’aide d’un pod, d’un service, d’un jeu de répliques et d’un déploiement.

Dans la prochaine partie de cette série, vous apprendrez à conditionner, déployer, mettre à l’échelle et gérer une application multi-conteneur.