TP: déploiement dans Kubernetes
Principe
- Prendre en main la ligne de commande Kubernetes
- Déployer une API web déjà prête sur un registry
- Déployer un BD
- Déployer une deuxième application
- Configuration
Infrastructure
Un cluster Kubernetes (nommé local
) est mis à disposition. Chaque étudiant recevra un mot de passe via tomuss (le login est le même que le compte étudiant usuel). Une interface Web de gestion (instance Rancher) est disponible à l’adresse https://rancher.fsa.os.univ-lyon1.fr. Les identifiants de connexion sont votre login étudiant (pxxxxxxx) et le mot de passe spécifié dans tomuss (mdp_k8s
). Bien que cette interface permette d’effectuer un certain nombre d’actions, il est demandé d’utiliser plutôt l’interface en ligne de commandes de Kubernetes: kubectl
. Cet utilitaire nécessite une configuration pour accéder au cluster. Celle-ci peut être récupérée en cliquant sur “Explore Cluster: local” dans le menu déroulant en haut à gauche, puis via le bouton “Download Kubeconfig” en haut à droite. Vous pouvez sauvegarder ce fichier et indiquer son emplacement à kubectl
via la variable d’environnement $KUBECONFIG
. Chaque étudiant/groupe/binôme s’est vu associé un projet au sein du cluster. Dans ce projet, un namespace de la forme prj-xx
a été créé. La commande suivante va permettre de changer la configuration par défaut de kubectl pour changer utiliser ce namespace par défaut (ne pas oublier de changer xx):
kubectl config set-context $(kubectl config current-context) --namespace=prj-xx
Il faudra bien penser à créer toutes vos ressources dans ce namespace.
Pour tester que kubectl
fonctionne, lancer la commande suivante:
kubectl get pod
Cette commande devrait répondre: “No resources found.”
Premiers déploiements
Il est conseillé de bien garder les fichiers utilisés pour cette partie: il pourront servir de point de départ pour le déploiement des applications des TPs précédents.
Dans la suite du TP, bien penser à toujours ajouter votre namespace (prj-xx
) comme champ namespace
dans la section metadata de vos fichiers de déploiements yaml.
D’une manière générale, préférez
kubectl apply
àkubectl create
, y compris pour la création de nouveaux pod/déploiements, etc.
Conteneurs stateless: nginx
Suivre ce tutoriel afin de déployer un conteneur nginx
.
Avant de détruire le déploiement à la fin du tutoriel, vérifiez que le conteneur fonctionne correctement via
kubectl port-forward
.
Conteneurs stateful: postgresql
Adapter le tutoriel sur le déploiement de MySQL pour:
- utiliser une base PostgreSQL (image)
- attention au point de montage et aux variables d’environnement
- utiliser un volume dont la taille est limitée à 1 Gi
- ne pas créer de
PersistentVolume
, mais simplement unPersistentVolumeClaim
utilisant:longhorn
commestorageClassName
- bien penser à préciser la valeur de la variable
PGDATA
comme indiqué dans la documentation de l’image docker.
Supprimer le déploiement, y compris le Service et le PersistentVolumeClaim.
Déploiement de l’application “chiffrement”
On va maintenant déployer une application “chiffrement” qui offre la possibilité de chiffrer un contenu via une API. Cette application est composée de 2 composants: api
et worker
.
api
est la partie visible de l’application. Elle offre une Web API avec 3 contrôleurs:/user
(pour la gestion des utilisateurs),/key
(pour la gestion des clés de chiffrement) et/crypt
(pour le chiffrement/déchiffrement de contenus). Les échanges de données avec la route/crypt
doivent être encodée enbase64
.worker
est le composant qui effectue concrètement le chiffrement. L’implémentation fournie utilise un algorithme naïf basé sur un décalage du nom de la clé. Afin de simuler une opération de chiffrement plus complexe, un temps de latence est ajouté lors du (dé)chiffrement d’un contenu.
Le code source de ces deux composants est fourni ici: https://forge.univ-lyon1.fr/tiw-fsa/fsa-apps-ha.
Le diagramme suivant résume les liens entre les composants de cette application:
graph LR
client --> api
subgraph Kubernetes
api("fa:fa-coffee api") --> worker("fa:fa-coffee worker ")
api --> db[("fa:fa-database postgres ")]
end
Le composant api
peut être déployé grâce à l’image harbor.fsa.os.univ-lyon1.fr/fsa/api:latest
et le composant worker
via l’image harbor.fsa.os.univ-lyon1.fr/fsa/worker:latest
.
Déploiement de Worker
Le worker ne dépend d’aucun autre composant pour fonctionner, c’est celui-ci que l’on va déployer en premier.
Créer un déploiement pour le composant
worker
. Créer également un service pour accéder au worker. Prévoir 2 instances de worker. Prévoir également un service pour accéder aux workers.
Worker et API sont des applications spring-boot. Leur valeurs de configuration (définies dans application.properties
) sont modifiable via des variables d’environnement (voir la doc). Par exemple, il est possible de changer le temps de calcul simulé d’un worker via la propriété tiw.fsa.worker.latence
et donc via la variable d’environnement TIW_FSA_WORKER_LATENCE
.
Modifier le déploiement précédent en changeant cette valeur pour la mettre à 10000 (au lieu de 1000 par défaut). Tester que le worker mets maintenant 10s à répondre en lui envoyant une requête en passant par un
kubectl port-forward
.
Détruire un ou deux pods worker et observer le comportement de kubernetes. Comment faire si l’on veut réduire le nombre de workers ? Quel est l’intérêt sur Service ?
Déploiement de la base de données
On veut maintenant déployer une base PostgreSQL sur laquelle s’appuiera API.
Créer un ConfigMap pour contenir les variables d’environnement contenant le nom de la base de données, l’utilisateur et le mot de passe de la base postgres (doc de l’image postgres, doc sur l’utilisation des configmaps), puis utiliser ce ConfigMap pour créer un déploiement de PostgreSQL avec les valeurs ainsi spécifiées. Ne pas oublier de configurer un Service pour accéder à la base de données.
Déploiement de l’API
Le composant API requiert plus de configuration. Il s’appuie sur la base PostgreSQL et sur les workers. Si vous avez correctement fait lesd éploiements précédentsCes deux composants sont accessibles via des services et pas directement via les adresses des pods.
Configurer et deployer l’API en utilisant les techniques utilisées précédement pour les workers et la base de données. Vérifier le bon fonctionnement de l’API en consultant ses logs (via
kubectl logs
) et en la requêtant. On pourra par exemple se connecter commeadmin
, créer une clé puis demander le chiffrement d’une donnée via cette clé.
Registre privé
Configuration de votre machine
En complément du cluster kubernetes, un registre docker a été créé: harbor.fsa.os.univ-lyon1.fr
. Ce registre dispose d’une interface Web (https://harbor.fsa.os.univ-lyon1.fr) qui vous permttra de consulter son contenu. Le login est votre login étudiant et votre mot de passe est indiqué sur tomuss (mdp_k8s
, le même que pour Rancher). Sur ce registre, vous avez la possibiliter de gérer des images docker taguées par harbor.fsa.os.univ-lyon1.fr/prj-xx/yyyy:zz
oprj-xx
est le même que votre projet/namespace Rancher.
Vérifiez que vous pouvez vous connecter au registre via docker login harbor.fsa.os.univ-lyon1.fr
en utilisant les mêmes logins et mots de passe que pour l’interface Web de Harbor. Une fois le login effectué, vous devez pouvoir pousser une image, pour tester (penser à remplacer prj-xx
):
docker pull hello-world
docker tag hello-world:latest harbor.fsa.os.univ-lyon1.fr/prj-xx/montest:latest
docker push harbor.fsa.os.univ-lyon1.fr/prj-xx/montest:latest
Utilisation dans kubernetes
Pour que Kubernetes puisse utiliser vos images, il lui faut pouvoir se connecter au registre privé. Pour cela on va suivre la documentation (lien) et créer un secret kubernetes (nommé harborcred
) et contenant les informations de connexion (bien penser à remplacer les valeurs):
kubectl create secret docker-registry harborcred --docker-server=harbor.fsa.os.univ-lyon1.fr --docker-username=pxxxxxxxx --docker-password=XXXXXXXXXX --docker-email=yyyyyyyyyyyy@etu.univ-lyon1.fr
On va ensuite utiliser ce secret pour lancer un job de test utilisant l’image que l’on a poussé ci-dessus (bien remplacer les valeurs):
apiVersion: batch/v1
kind: Job
metadata:
name: test-harbor-pull
spec:
template:
spec:
containers:
- name: test-harbor-pull
image: harbor.fsa.os.univ-lyon1.fr/prj-xx/montest:latest
restartPolicy: Never
imagePullSecrets:
- name: harborcred
backoffLimit: 4
Vérifier ensuite dans rancher que le job a fonctionné (en sélectionant le projet prj-xx
du cluster local
du menu à côté de la vache, dans l’onglet Workload
)
En cas de problème, des infos sont disponibles en suivant les liens du job, puis du pod et en affichant les événements du pod.
Préparation du TP suivant
Le TP suivant consistera à mettre en place la surveillance de cette application. Il est conseillé de bien regarder le fonctionnement des deux services Java en amont de la séance. Ne pas hésiter à réaliser un fork du dépôt du code des applications.
Les script build-push.sh
permettent de construire les images docker et de les pousser vers Harbor. Il faudra changer le tag pour indiquer votre projet au lieu de fsa
. Essayez d’avoir un cycle modification -> build -> déploiement fluide. Pour mettre au point ce cycle, vous pouvez ajouter/changer des lignes de log dans chacune des applications. Vous pouvez également ajouter une fonctionnalité, comme par exemple exposer l’interface OpenAPI via springdoc.
Un miroir maven local au campus est disponible ici: https://nexus.ecoquery.os.univ-lyon1.fr/repository/maven-central/ Il est possible d’utiliser ce lien comme valeur pour l’argument de build MVN_MIRROR
des Dockerfile
pour accélérer la construction des images. Son utilisation est intégrée aux scripts build-push.sh
.