Déploiement d'applications avec Kubernetes
Contexte
1. Objectifs généraux
a. Exploiter la plateforme Kubernetes mise en place
Les précédents chapitres se sont attachés à montrer les différentes manières de monter un cluster Kubernetes, ainsi qu’à expliquer dans les détails les opérations de maintenance et d’exploitation de ce cluster une fois mis en place. Jusqu’à maintenant, donc, les opérations montrées relevaient plutôt de profils système ou opérationnels, dont le rôle est d’assurer la disponibilité de l’infrastructure.
Dans le présent chapitre, nous allons basculer dans un autre rôle, qui correspond à un profil d’exploitant du logiciel supporté par la plateforme, et donc plutôt consommateur de celle-ci. En résumé, après être rentré dans le détail de comment Kubernetes fonctionne, nous allons nous pencher sur ce que nous pouvons en faire. L’usage principal de ce type de plateforme étant de déployer des applications pouvant passer à l’échelle, nous utiliserons une application exemple que nous installerons sur un cluster Kubernetes et que nous manipulerons comme le ferait l’exploitant d’une structure similaire en production.
b. Remarque sur l’approche DevOps
Dans son expression-même, "DevOps" peut faire penser que le principe associé est qu’une même personne possède les deux rôles de développeur et d’opérationnel, ou à l’inverse qu’il convient de bien séparer ces deux rôles. En fait, le principe du DevOps est de faire en sorte d’éviter les barrières entre les personnes en charge de l’infrastructure et celles en charge des logiciels portés par cette dernière.
Traditionnellement, les approches sont en effet opposées car les enjeux sont très différents : pour l’opérationnel en charge de la plateforme, l’enjeu principal est que celle-ci fonctionne en continu, ce qui a pour conséquence naturelle une certaine aversion au changement. Après tout, un des commandements principaux dans l’informatique est de ne pas toucher à un système qui fonctionne. Tout changement est potentiellement vecteur d’un nouveau bug, d’un problème dans la procédure de mise à jour et n’importe quel administrateur système a donc comme réflexe de réduire au maximum ces interventions.
À l’inverse, les développeurs et les profils qui commanditent ces changements, que ce soient des Product Owners sur un produit ou le client/utilisateur en direct sur un projet, ont plutôt intérêt à ce que les fonctionnalités sortent le plus vite possible, pour apporter le maximum de valeur métier au logiciel. À l’inverse de l’administrateur du système, ils souhaitent donc généralement accélérer le rythme du changement. Cette différence dans les enjeux a longtemps été traitée par un rapport de force et une opposition entre les deux approches, les seconds obtenant bon gré mal gré des premiers des mises en production tandis que ceux-ci invoquaient toutes les raisons, bonnes ou mauvaises, pour ne pas les réaliser.
Comme le périmètre de recoupement entre les deux responsabilités est traditionnellement assez large, les difficultés étaient plus étendues. Par exemple, un développeur pouvait avoir besoin d’un OS particulier pour son application, alors que l’administrateur souhaitait ne plus le supporter. Dans certains cas, un administrateur pouvait décider de blocages de sécurité trop contraignants pour un applicatif. Bref, le champ d’interaction était très large entre les deux rôles, car il couvrait toutes les technologies de support de déploiement, de la machine physique jusqu’au choix de librairies partagées.
Une approche plus évoluée est de s’attaquer au problème lié à l’incertitude sur le changement elle-même....
Premier déploiement par ligne de commande
1. Contexte
Pour la première utilisation du cluster Kubernetes, un premier exemple extrêmement simple avec un seul pod, dans le namespace par défaut et avec une exposition restreinte, suffira amplement. Ce n’est que dans la seconde partie du présent chapitre que nous passerons à un mode un peu plus industriel.
Pour ce premier exemple, une interface Linux en ligne de commande sera utilisée, avec kubectl installé et le contexte actif pour pointer sur le cluster d’exercice, comme cela a été montré plus haut sur une machine virtuelle CoreOS.
Afin de respecter la promesse d’un premier exemple le plus simple possible, nous allons utiliser une image Docker existante et très simple, à savoir celle exposant un serveur nginx.
2. Création du déploiement
Contrairement au fonctionnement depuis le client Docker, les conteneurs ne sont pas créés directement dans la plateforme Kubernetes. Un objet de type Deployment permet de recenser tous les paramètres de démarrage des conteneurs (quelle image, combien d’instances, etc.). C’est lui qui va se charger de créer des pods, qui eux-mêmes contiennent les conteneurs Docker.
Pour être encore plus précis, l’objet de type Deployment est géré par le Deployment Controller, ce dernier étant lui-même pris en charge par le Controller-Manager, comme expliqué au chapitre précédent.
La commande ci-dessous permet de créer un déploiement simple, nommé siteweb et basé sur l’image Docker officielle nginx dans sa version par défaut :
kubectl create deployment siteweb --image=nginx
3. Vérification du déploiement
Après cela, une commande comme la suivante permet de vérifier que le déploiement a bien été créé (à noter que deploy peut être utilisé à la place de deployment comme au-dessus) :
core@CoreOS1 ~ $ kubectl describe deploy siteweb
Name: siteweb
Namespace: default
CreationTimestamp: Mon, 05 Aug 2019 14:21:07 +0000
Labels: app=siteweb
Annotations: deployment.kubernetes.io/revision=1
Selector: app=siteweb
Replicas: 1 desired | 1 updated | 1 total | 1 available
| 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=siteweb
Containers:
nginx:
Image: nginx
Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: siteweb-5778d9dcc7 (1/1 replicas created)
Events: ...
Second déploiement à l’aide d’un fichier de configuration
1. Objectifs
Après une première section consacrée à déployer manuellement un site web sur une infrastructure Kubernetes, la présente section s’attache à montrer une méthode plus industrielle proche de l’esprit Infrastructure As Code. Le but restant de bien développer la compréhension des mécanismes derrière Kubernetes, nous n’irons pas jusqu’au bout de l’automatisation du système, mais il sera simple, en fin d’exercice, de reprendre toutes les commandes entrées et de les regrouper dans un script ou dans toute autre méthode de lancement automatique associable à Kubernetes.
Pour essayer d’être le plus complet possible sur les fonctionnalités qui peuvent servir dans un véritable déploiement, l’ensemble d’exercices ci-dessous se base sur un exemple qui est le plus proche possible d’une application de production, avec une dizaine de services en interaction, une gestion de base de données, une exposition d’API sur l’extérieur, mais aussi des appels internes, etc.
Contrairement au premier exercice qui avait pour but de bien expliquer les notions de déploiement, de service et de pod avec un exemple simple et accompagné de bout en bout, le second exercice ci-dessous cherche à couvrir le maximum des fonctionnalités offertes par Kubernetes pour le gestionnaire d’applications, sans toutefois s’aventurer dans celles qui ne servent que dans des cas très particuliers. Une fois ce second exercice compris, le lecteur devrait être à l’aise avec 99 % des cas de déploiements applicatifs sur un cluster Kubernetes, et en mesure de lister les contenus, savoir où trouver les informations pour comprendre le déploiement ou le refaire fonctionner, etc.
2. Application exemple
a. Présentation de l’application
L’application utilisée dans les exemples de manipulation ci-dessous s’appelle Middle Office. Il s’agit, comme son nom l’indique, d’une application s’interfaçant entre un Front Office (qui permet de déposer des demandes, typiquement sur un site web) et un Back Office (l’application côté entreprise qui va permettre de traiter ces demandes). Le Middle Office est en général géré par des gestionnaires qui vont qualifier les demandes et accepter qu’elles entrent dans le périmètre du traitement par l’entreprise sur le Back Office.
Il y a une part de tampon de sécurité dans le rôle du Middle Office, car il sert de sas à faire entrer des informations dans une zone moins fortement sécurisée du périmètre étendu de l’entreprise. Ainsi, c’est typiquement sur un Middle Office qu’on opérera les contrôles antivirus, pour ne pas faire perdre de temps à un usager ou un client lors de son dépôt, mais pour ne pas non plus accepter de faire entrer un document dangereux dans le périmètre interne de l’entreprise.
Le Middle Office est également un moyen de filtrer les demandes d’un point de vue fonctionnel, en faisant en sorte que les gestionnaires du Back Office ne soient pas gênés par des demandes incomplètes, farfelues ou invalides. Le gestionnaire Middle Office sert donc de validateur de premier niveau sur des demandes, en les autorisant à passer ou pas, ou en leur donnant une qualification qui va les orienter vers tel ou tel processus sur le reste du Système d’Information.
Notre application exemple de Middle Office permettra ainsi à un type d’utilisateur de déposer des demandes, à un autre de faire porter des décisions sur ces demandes et à un troisième de paramétrer les types de demandes ainsi que les décisions possibles sur chaque. Cette application est souhaitée comme la plus générique possible, dans le sens où elle permet de gérer n’importe quel type de demande, avec toutes les données qui y sont associées...