🛞 DĂ©ploiement avec Kubernetes

Cette partie prĂ©sente des tenants et aboutissants du dĂ©ploiement applicatif, avec une application a l’hĂ©bergement cloud via kubernetes.

Les exemples sont basĂ©s sur l’application hĂ©bergĂ©e ici : https://frontend-conception-logicielle.kub.sspcloud.fr/

Api hébergée ici : https://backend-conception-logicielle.kub.sspcloud.fr

Le code source de l’application est disponible directement dans le projet d’architecture exemple : https://github.com/conception-logicielle-ensai/archi-exemple

PrĂ©ambule : HĂ©bergement traditionnel d’une application

Avant de s’intĂ©resser a ce que nous permet Kubernetes, on prĂ©cise ce qui permet hĂ©berger une application ou un site web.

Environnement d’execution

Il vous faut un environnement d’execution de votre application. C’est a dire un support sur lequel on peut lancer votre application.

Cela inclut l’installation des dĂ©pendances, la configuration des services et la gestion des fichiers applicatifs.

Cela peut ĂȘtre par exemple :

  • Un ordinateur avec python d’installĂ©.
  • Une machine virtuelle (machine installĂ©e sur un ordinateur, on peut en installer plusieurs)
  • Un serveur (qui est un ordinateur), sur lequel est installĂ© un engine docker, ce qui permet de lancer des applications sous forme de conteneur.

Routage et exposition de votre application

Une fois que votre application tourne sur un environement d’execution, il faut la rendre accessible a l’extĂ©rieur.

Il faut pour cela comprendre comment fonctionne l’accĂšs a une machine depuis une url.

Il existe un ensemble de serveurs DNS qui permettent d’apparier les urls avec des adresses IP, en effet on ne pourrait pas facilement retenir des adresses IP.

Les adresses IP correspondent a ce qu’on appelle des Load balancer ou des serveurs. En simplifiant un peu, cela correspond a une IP publique d’accĂšs a votre service (machine, cluster, vm ou autre..)

Il faut finalement que votre serveur / machine / cluster accepte l’accĂšs sur le port, tous les ports sont fermĂ©s par dĂ©faut.

En bref:

Une fois l’application installĂ©e, elle doit ĂȘtre accessible aux utilisateurs via le rĂ©seau.

Cela implique la configuration d’un serveur (uvicorn ou serveur web statique (pour simplifier on utilise vite ici)).

L’attribution d’une adresse IP et l’ouverture des ports nĂ©cessaires pour permettre la communication avec les clients se configure au niveau de l’environnement d’execution, on parle parfois de parefeu applicatif.

Il existe d’autres notions : scalabilitĂ©, routage, …

PrĂ©ambule : diffĂ©rentes formes d’hĂ©bergements

Historiquement on distingue diffĂ©rentes formes d’hĂ©bergement applicatifs:

  • Bare Metal : ExĂ©cution directe sur un serveur physique sans couche de virtualisation. Performant mais complexe Ă  gĂ©rer.

  • Virtual Machine (VM) : Utilisation d’un hyperviseur (ex: VMware, KVM) pour exĂ©cuter plusieurs systĂšmes isolĂ©s sur une mĂȘme machine physique.

  • Conteneur : ExĂ©cution lĂ©gĂšre et isolĂ©e d’applications via Docker ou Kubernetes, partageant le mĂȘme noyau du systĂšme hĂŽte.

Idée

L’idĂ©e a Ă©tĂ© dans le temps de limiter le nombre de machines et d’optimiser l’usage en ressources, en effectuant un roulement sur une mĂȘme machine de diffĂ©rents traitements, en s’appuyant sur de l’isolation des processus.

Remarque

Tous ces modes ont leur lĂ©gitimitĂ© en fonction de cas d’usages prĂ©cis.

Architecture de Kubernetes : un standard d’architecture d’hĂ©bergement cloud

Kubernetes propose une solution d’architecture pour administrer des serveurs qui hĂ©bergent des applications sous forme de conteneurs.

Kubernetes permet (entre autres):

  • D’executer des conteneurs sur des serveurs a la demande
  • D’associer ces traitements avec de la persistence
  • Une couche rĂ©seau interne au cluster de machines (connexion entre conteneurs isolĂ©s)
  • Proposer une typologie d’ordonnancement, de redĂ©marrage et de mise a jour : Rollout..

L’idĂ©e ?

  1. On part du simple concept de pouvoir lancer des processus isolés sur une machine.
  2. On administre nos différents serveurs avec une architecture Master / slave
  3. On gÚre les demandes cÎté master et on ordonnance les traitements cÎté slave
  4. On suit l’Ă©tat du cluster entre la partie demande et la partie executante.

Utilisation d’un cluster kubernetes

configmap

L’utilisation d’un cluster Kubernetes repose sur la communication avec un API server. Il s’agit d’une API qui attend des objets dans un format bien prĂ©cis pour ensuite ĂȘtre intĂ©grĂ©s.

L’API server fonctionne avec un superset de JSON, le Yaml.

On prĂ©conisera, dans le cadre du cours, d’utiliser l’utilitaire en ligne de commande kubectl qui permet de simplifier l’utilisation de l’API kubernetes.

Remarque les CLI sont des outils trĂšs importants qui peuvent grandement simplifier votre travail en fonction des technologies: maintenance base de donnĂ©es, apis Ă©prouvĂ©es…

Exemple de contrat d’un Pod:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world-pod
spec:
  containers:
  - name: hello-world-container
    image: ragatzino/backend-demo-conception-logicielle:latest
    ports:
    - containerPort: 8000

Ce yaml dĂ©crit le contrat d’un Pod. Nous verrons cela dans quelques instants.

L’application de cette demande au cluster nous permet de lancer un processus sur un des serveurs du cluster.

Kubernetes permet d’installer des applications a la demande, via l’utilisation d’une API pour dĂ©ployer des ressources sur un cluster.

Ces ressources correspondent a des applicatifs deploiement, des expositions réseau ingress/service ou des éléments de configuration configmap par exemple.

Comme toute API bien constituĂ©e, elle nĂ©cessite une authentification et n’est pas forcĂ©ment accessible partout.

Exemples d’implĂ©mentations

Kubernetes est une technologie opensource, on peut donc en voir plusieurs installations dans différents systÚmes :

Implémentations privées

  • GCP : Google Cloud Platform, l’inscription est gratuite et vous donne 100 euros de crĂ©dit temporairement pour hĂ©berger vos traitements
  • EKS : Amazon Ela plateforme d’amazon
  • AKS : Azure Kubernetes Service plateforme microsoft

Implémentations du service statistique publique

SSPCloud: Cloud administrĂ© par la division innovation Ă  l’INSEE Nubo : Cloud de la dgfip, technologies diverses

Kubectl : Utilitaire CLI pour dialoguer avec l’API server d’un cluster Kubernetes

kubectl est l’outil CLI permettant d’interagir avec un cluster Kubernetes via l’API Server. Il permet de gĂ©rer les ressources Kubernetes (Pods, Services, Deployments, etc.), dĂ©ployer des applications et diagnostiquer des problĂšmes.

Il s’installe directement ici : https://kubernetes.io/docs/reference/kubectl/

NB si vous avez passĂ© le script d’install ou que vous utilisez un environnement SSP cloud tout est dĂ©jĂ  configurĂ©.

Commandes essentielles: Récupérer des ressources (pod,deployment,service,configmap): get

  • kubectl get pods

Liste des pods, pour récupérer des infos, leur nom pour les supprimer ou autre

  • kubectl get services

Liste des services, cela vaut aussi pour deployment ou configmap ou tout autre Supprimer des ressources : delete

  • kubectl delete ingress mon-ingress

Mon ingress c’est le nom de la ressource de type ingress sur le cluster

  • kubectl delete service mon-service Avoir des infos sur le comportement d’une ressource describe
  • kubectl describe typeressource nomressource
  • kubectl describe pod monpod

Ce qu’on fera le plus souvent :

  • describe/ logs / get pour voir l’Ă©tat
  • application de ressource et suppression de ressources sous forme de fichier

Appliquer de la configuration sous forme de fichier

  • kubectl apply -f deployment.yaml

Exemple :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: backend
          image: ragatzino/backend-demo-conception-logicielle:latest
          resources:
            limits:
              memory: "200Mi"
              cpu: "300m"
          envFrom:
            - configMapRef:
                name: configuration-backend
          ports:
            - containerPort: 8000

deployment.yaml

Vous pouvez également supprimer une ressource par fichier

kubectl delete -f deployment.yaml

Ressources d’un cluster

ressources d’un cluster

Dans cette partie on va prĂ©senter quelques ressources que vous pourrez utiliser sur le cluster, bien d’autres existent rĂ©pondant chacunes a des besoins spĂ©cifiques :

  • Gestion de la resilience et de l’ordonnancement: deployment, statefulSet, cronjob
  • Configuration applicatives : configmap secret
  • Routage rĂ©seau: ingress, service Plus loin :
  • Droits d’accĂšs Ă  vos ressources : role, rolebinding, serviceaccount
  • Persistence des donnĂ©es: persistentvolume, persistentvolumeclaim

Remarque, il en existe une myriade d’autres

Quel est notre objectif?

DĂ©ployer une application sur le cloud, accessible via une url fixe, et avec une configuration via variable d’environnement

Comment y arriver? Nous allons nous limiter pour les usages du cours a 4 ressources:

  • Deployment : Lancer des processus conteneurisĂ©s pod, les rĂ©pliquer, dĂ©finir une stratĂ©gie de mise a jour
  • Service : Permettre l’accĂšs a des processus a l’intĂ©rieur du cluster, ou leur donner une adresse IP
  • Ingress : Mettre en place une entrĂ©e DNS, et un routage vers un service en HTTP depuis l’extĂ©rieur du cluster.
  • Configmap: Permettre la crĂ©ation de fichiers de configuration et l’injection de variables d’environnements a l’intĂ©rieur de nos conteneurs.

On va détailler cela dans cette partie.

Pod : la brique unitaire contenant un/des conteneur(s)

pod

Un pod est le plus petit concept Kubernetes et correspond (en gros) à un ensemble de conteneurs (souvent un seul) qui fonctionnent ensemble et se partagent les ressources notamment le réseau. Pour en savoir plus sur les concepts kubernetes, ça commence ici : https://kubernetes.io/docs/concepts/.

Dans notre cas on lancera un seul conteneur par “Pod”, donc cela sera Ă©quivalent a une instance de votre application <=> un docker run.

ProblĂšme: si il plante, le processus n’est pas relancĂ© donc en gĂ©nĂ©ral on utilise pas la ressource Pod telle qu’elle.

Solution: Il faut orchester ces traitements, et en fonction de leur enjeu, leur appliquer une rĂšgle

Exemples

  • Un traitement qui s’execute de maniĂšre asynchrone et one shot (on appelle ça un batch), doit fonctionner mais ne doit pas ĂȘtre executĂ© en boucle
  • Un traitement qui offre un service a des utilisateurs en exposant des ressources (API, UI), doit a priori ĂȘtre toujours en ligne, et donc on doit veiller a ce qu’ils soient relancĂ©s si ils plantent.

Deployment : Orchestration des pods - redémarrer, mettre a jour..

Un Deployment est un objet Kubernetes permettant de gérer et mettre à jour un ensemble de Pods de maniÚre déclarative (contrat de la ressource).

Objectifs

  • Il assure la haute disponibilitĂ© et l’auto-rĂ©paration des pods.
  • Il permet le scaling et les rollbacks.

Configmap: externaliser la configuration, introduire des variables d’environnement dans les conteneurs

Un ConfigMap stocke des données de configuration sous forme de clés-valeurs et permet aux pods de les utiliser.

apiVersion: v1
kind: ConfigMap
metadata:
  name: configuration-application
data:
  VARIABLE_ENVIRONNEMENT1: variable_environnement
  DATABASE_URL: "postgres://user:password@db:5432/mydb"

Il sont ensuite importable en tant que variables d’environnement dans les conteneur ainsi :

containers:
  - name: mon-container
    image: mon-image:v1
    envFrom:
      - configMapRef:
          name: mon-configmap

Service : Exposition intra cluster et load balancing

service

Un Service expose un ensemble de Pods et assure la communication entre eux ou avec l’extĂ©rieur.

apiVersion: v1
kind: Service
metadata:
  name: application
spec:
  selector:
    app: application # doit correspondre a une valeur définie dans le deployment.yaml
    #     metadata:
    #        labels:
    #          app: application
  ports:
    # PORT QUE VOUS VOULEZ, 80 correspond au port standard http, doit correspondre cÎté ingress.
    - port: 80
      # PORT DU CONTENEUR, ET DONC DE VOTRE SERVEUR
      targetPort: 5173

Ingress : exposition HTTP et ingress

ingress

Un Ingress permet d’exposer des Services HTTP/S en dĂ©finissant des rĂšgles de routage.

Exemple :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: application
  labels:
    name: application
spec:
  rules:
    - host: hello.kube.sspcloud.fr
    # CETTE URL est unique, donc si quelqu'un l'a déjà prise vous ne pourrez pas la prendre
    # Changer le host vers une url qui fonctionne, une url du type *.kub.sspcloud.fr exemple mon-application.kub.sspcloud.fr
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: application
                port:
                  number: 80

Remarque : L’Ingress nĂ©cessite un Ingress Controller (ex: Nginx Ingress Controller) pour fonctionner. C’est le cas sur le sspcloud.

TP : Mise en place de vos applications sur les plateformes kuberentes du SSPCloud

Ce TP nĂ©cessite la mise en place d’un livrable au format docker et le dĂ©ploiement sur un registre publique (type dockerhub) pour l’hĂ©berger par la suite.

Le sspcloud propose un api server ouvert au sein du cluster kubernetes SSPCloud Ă  ces utilisateurs. Ce service est un service a faible support, seulement pour des usages de poc, pas de donnĂ©es sensibles, pas de garantie de service, toutefois cela convient tout a fait pour les expĂ©rimentations et l’hĂ©bergement de projets informatiques ENSAI.

Pour la mise en place, il nous faut un service qui peut accĂ©der au cluster et donc qui est hĂ©bergĂ© sur le cluster (puisque l’api n’est accessible que depuis le cluster).

Le SSPCloud met a disposition des services qui vous permettent d’instancier des applications sur le cluster, notamment des services de type “plateforme de dĂ©veloppement” :

  • VScode
  • RStudio

1 - Mise en place d’un service dans le cluster

Rendez vous sur le SSPCloud pour dĂ©ployer un service VSCode en choisissant admin dans l’onglet Kubernetes.

Ce choix admin donne Ă  votre service VSCode les permissions nĂ©cessaires au dĂ©ploiement d’une application dans le cluster kubernetes du sspcloud.

2 - Interaction avec le cluster kubernetes

Une fois le VSCode lancĂ©, ouvrez le et ouvrez y un terminal. On utilise l’utilitaire kubectl.

Lancez la commande suivante:

kubectl get pods

Vous constatez, de maniĂšre mĂ©ta que vous disposez d’une ressource de type pod, qui est le vscode dans lequel vous vous situez.

3 - Récupération de contrats de base

On a prémaché le travail pour vous, on a mis des contrats approchant ce que vous pouvez vouloir mettre en place sur le dépÎt suivant https://github.com/conception-logicielle-ensai/exemples-cours.git :

  • Faites ce que vous faites le mieux depuis le vscode : git clone https://github.com/conception-logicielle-ensai/exemples-cours.git

Dans la partie : https://github.com/conception-logicielle-ensai/exemples-cours/tree/main/cours-6/kubernetes/app

Observez le contenu du sous dossier exemples-cours/cours-6/kubernetes/app : il y a diffĂ©rents fichiers ̀yaml de configuration de ressources pour kubernetes.

Mettez en place la configuration en amont du déploiement (le déploiement le référence) :

kubectl apply -f exemples-cours/cours-6/kubernetes/app/configmap.yaml

Appliquez le deployment:

kubectl apply -f exemples-cours/cours-6/kubernetes/app/deployment.yaml

et vérifiez vos Pod

kubectl get pods

4 - Exposition sur internet

Modifiez le contrat, ingress pour mettre une url qui vous est propre, puis appliquez les différents fichiers

Service

kubectl apply -f exemples-cours/cours-6/kubernetes/app/service.yaml
kubectl apply -f exemples-cours/cours-6/kubernetes/app/ingress.yaml

5 - Application d’une configuration et redĂ©marrage

On souhaite maintenant changer la configuration pour afficher une autre information sur la page d’accueil du swagger:

Si l’on regarde le configmap, on peut y configurer des variables d’environnement pour notre application :

Notre application reçoit la variable d’environnement : APP_TITLE pour changer a l’affichage du swagger le titre de l’application au niveau de sa documentation. RĂ©alisez une modification de ce champ dans le fichier configmap et relancez votre application.

pour appliquer le changement:

kubectl apply -f exemples-cours/cours-6/kubernetes/app/configmap.yaml

Mais il vous faut relancer, car les variables d’environnement ne se chargent qu’au dĂ©marrage des applicatifs.

pour relancer

Soit vous supprimez tout refaites tout :

  • kubectl delete -f exemples-cours/cours-6/kubernetes/app/
  • puis kubectl apply -f exemples-cours/cours-6/kubernetes/app/ Soit vous supprimez le pod :
  • kubectl get pods
  • puis en notant lepodtrouvĂ©svpchangezmoi le nom du pod kubectl delete pod lepodtrouvĂ©svpchangezmoi

6 - Passage a votre appli

Modifier l’image, et Ă©ventuellement les ports d’Ă©coute du dĂ©ployment et du service pour changer d’application et dĂ©ployer l’application que vous avez packagĂ© prĂ©cĂ©demment dans ce TP.