#+TITLE: Cours de virtualisation avancée: /Kubernetes/, introduction
#+OPTIONS: toc:nil date:nil author:nil reveal_single_file:t timestamp:nil
#+LATEX_CLASS: article
#+LATEX_CLASS_OPTIONS: [12pt,a4paper]
#+LATEX_HEADER: \usepackage[a4paper,margin=0.5in]{geometry}
#+LATEX_HEADER: \usepackage[utf8]{inputenc}
#+LATEX_HEADER: \usepackage[inkscapelatex=false]{svg}
#+LATEX_HEADER: \usepackage[sfdefault]{AlegreyaSans}
#+LATEX_HEADER: \usepackage{multicol}
#+LATEX_HEADER: \usepackage{minted}
#+LATEX_HEADER: \usepackage{float}
#+LATEX_HEADER: \usepackage{tikz}
#+LATEX_HEADER: \usetikzlibrary{positioning}
#+LATEX_HEADER: \renewcommand\listingscaption{Exemple de code}

#+REVEAL_THEME: white
#+REVEAL_INIT_OPTIONS: slideNumber:true
#+REVEAL_EXTRA_CSS: ../common/reveal_custom.css

* Introduction, les /clusters/
- Grappe de serveur
- Groupe de machines fonctionnant ensemble

* /Kubernetes/
[[file:./images/kube_logo.png]]

** C'est quoi ?
- Ancien mot grec signifiant "timonier" (marin qui tient la barre)
- Souvent abrégé /"K8S"/
- Système /open-source/ pour le *déploiement*, la *mise à l’échelle* et *gestion* de conteneurs
- Configuration via des fichiers /YAML/

** Origine
- Lancé par /Google/ en 2014
- /Google/ s'associe à la /Linux Foundation/ pour créer la /CNCF/ en utilisant /K8S/ comme projet de départ

/CNCF/: /Cloud Native Computer Foundation/

** Quelques statistiques
- 66% : c'est le nombre d'entreprises qui utilisent /K8S/ en prod en 2023 [[[source:cncf_survey]]]
- Entre 2018 et 2020 : /K8S/ top 10 projets les plus actifs /Github/
- Le nombre de conteneurs en prod dans le monde est inestimable mais /Google/ estime en lancer *2 milliards par semaine*

* Le monde des conteneurs
[[file:./images/containers.webp]]

** Des applications souvent présentes
[[file:./images/top_container_images.png]]

#+REVEAL: split

#+BEGIN_smallfont
| *Redis*         | BDD clef-valeur               |
| *ElasticSearch* | NOSQL / moteur de recherche   |
| *Postgresql*    | base de données SQL           |
| *RabbitMQ*      | agent de message              |
| *Kafka*         | agent de message / événements |
| *Vault*         | BDD sécurisés                 |
| *Mongo*         | BDD NOSQL                     |
| *Nginx*         | serveur web                   |
| *Consul*        | gestion de réseau             |
| *MySql*         | BDD SQL                       |
#+END_smallfont

** Plusieurs orchestrateurs
*** */Kubernetes/*
#+BEGIN_imagecol
#+ATTR_LATEX: :width 2cm
[[file:./images/k8s_logo.png]]
#+END_imagecol

#+BEGIN_textcol
Le plus connu et utilisé, objet de ce cours
#+END_textcol

*** /*Nomad*/
#+BEGIN_imagecol
#+ATTR_LATEX: :width 2cm
[[file:./images/nomad_logo.png]]
#+END_imagecol

#+BEGIN_textcol
Proposé par /Hashicorp/, solution d'orchestration hybride entre conteneurs, machines virtuelles et machines physiques.
#+END_textcol

*** /*Docker Swarm*/
#+BEGIN_imagecol
#+ATTR_LATEX: :width 2cm
[[file:./images/swarm_logo.png]]
#+END_imagecol

#+BEGIN_textcol
Proposé par /Docker/, solution plus simple mais qui ne permet pas une utilisation aussi avancée.
#+END_textcol

*** /*Rancher*/
#+BEGIN_imagecol
#+ATTR_LATEX: :width 2cm
[[file:./images/rancher_logo.png]]
#+END_imagecol

#+BEGIN_textcol
Une surcouche à /Kubernetes/ qui permet de simplifier son utilisation à grande échelle.
#+END_textcol

** Solutions à louer
#+ATTR_LATEX: :width 2cm
[[file:./images/eks_logo.png]]
#+ATTR_LATEX: :width 2cm
[[file:./images/aks_logo.png]]
#+ATTR_LATEX: :width 2cm
[[file:./images/gke_logo.png]]

* Pourquoi un orchestrateur
[[file:./images/why.gif]]

#+REVEAL: split

- Déploiement et mise à l'échelle automatique
- Haute disponibilité / réplication
- Optimisation des ressources
- Supervision et journalisation

** Déploiement et mise à l'échelle automatique
- Déploiement via de la /CI/
- Mises à jours automatiques des conteneurs
- Allocation automatique des ressources
  
** Haute disponibilité
- Réplication des applications
  - Pour les performances
  - Pour la sécurité
- Tolérance aux pannes de machines

** Optimisation des ressources
- Utilisation de conteneurs
- Choix des cibles de déploiement en fonction de leur usage et occupation
- Dé-allocation des ressources en cas de baisse de charge
  
** Supervision et journalisation
- Gestion unifiée des journaux
- Outils automatisés

* /Kubernetes/
** Terminologie et concepts
- /Namespace/ ::
  - Un "espace de noms"
  - Permet de regrouper les ressources pour s'y retrouver et simplifier la gestion
  
  #+REVEAL: split
  
- /Pod/ ::
  [[https://kubernetes.io/fr/docs/concepts/workloads/pods/pod-overview/][doc]]
  - La plus petite unité d'exécution
  - C'est dans ces éléments que sont présents les conteneurs
  - Réseau local entre les conteneurs d'un même /pod/

#+REVEAL: split    
    
- /Service/ ::
  [[https://kubernetes.io/fr/docs/concepts/services-networking/service/][doc]]
  - Une manière d'exposer une application s'exécutant sur un ensemble de /pods/ en tant que service réseau
  - Possède une adresse /IP/ et un nom /DNS/
  - Permet l'équilibration de la charge

#+REVEAL: split    

- /Volume/ ::
  [[https://kubernetes.io/fr/docs/concepts/storage/volumes/][doc]]
  - Permet le stockage des fichiers d'un /pod/ (sinon fichiers perdu lors de la destruction du /pod/)
  - Permet de partager des fichiers entre des conteneurs au sein d'un /pod/

#+REVEAL: split

Il reste encore une multitudes de concepts et de termes propres à /Kubernetes/.
Je vous invite donc à consulter cette page: [[https://kubernetes.io/fr/docs/concepts/][https://kubernetes.io/fr/docs/concepts/]].

** Architecture
[[file:./images/k8s_cluster.png]]

#+REVEAL: split

- Composé de plusieurs nœuds
- Au moins 1 nœud de gestion et 1 nœud de travail

*** Nœud de gestion
- Aussi appelé /"control plane"/ dans la terminologie /K8S/
- Composant principal
- Gestion de la charge de travail
- Services qui contrôlent le /cluster/

#+REVEAL: split

- /etcd/ :: stocke les éléments de configuration
- /API server/ :: reçoit et traite les requêtes de gestion. Vérifie en permanence que l'état du /cluster/ correspond aux configurations stockées dans =etcd=
- /Scheduler/ :: se charge de la répartition de la charge
- /Controller manager/ :: applique les actions requises à la gestion du /cluster/

*** Nœud de travail
- C'est sur ces nœuds que les conteneurs sont déployés
- Cela peut être des machines physiques ou virtuelles

#+REVEAL: split

- /kubelet/ ou /node manager/ ::
  - Se charge de la gestion des /pods/ sur le nœud
  - Reçoit ses ordres du /control plane/
  - Informe le /control plane/ de l'état du nœud

- /kube-proxy/ ::
  - Se charge de la gestion du réseau

- /container runtime/ ::
  L'environnement d’exécution des conteneurs, souvent /Docker/

* Prise en main
- Les interactions avec /K8S/ se font via la commande =kubectl=.
- Quelques interactions sont aussi possible via le /dashboard/ mais ce dernier est limité et ne sera pas abordé pendant ce cours.

  
** Appliquer une configuration
Cela se fait avec la commande
#+BEGIN_SRC bash
kubectl apply -f <fichier.yaml>
#+END_SRC

** Lister des ressources
#+BEGIN_NOTE
Syntaxe:

=kubectl get <ressource>=
#+END_NOTE

#+BEGIN_SRC bash
❯ kubectl get pods
NAME           READY   STATUS    RESTARTS   AGE
profiles-app   3/3     Running   0          22s
#+END_SRC

#+BEGIN_SRC bash
❯ kubectl get services
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
profiles-app-svc   LoadBalancer   10.97.188.25   <pending>     8000:30487/TCP,8001:32451/TCP   5s
#+END_SRC

** Lire les journaux d'un /pod/

#+BEGIN_NOTE
Syntaxe:

=kubectl logs <nom ressource>=
#+END_NOTE

#+BEGIN_SRC bash
❯ kubectl logs profiles-app
...
#+END_SRC

** Supprimer une ressource
#+BEGIN_NOTE
Syntaxe:

=kubectl delete <type ressource> <nom ressource>=

ou

=kubectl delete -f <fichier.yaml>=
#+END_NOTE

#+BEGIN_SRC bash
❯ kubectl delete pods profiles-app
pod "profiles-app" deleted
#+END_SRC

** Décrire une ressource
#+BEGIN_NOTE
Syntaxe:

=kubectl describe <type ressource> <nom ressource>=
#+END_NOTE

#+BEGIN_SRC bash
❯ kubectl -n profiles-app describe pod profiles-app
Name:             profiles-app
Namespace:        profiles-app
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Thu, 09 May 2024 17:35:54 +0200
Labels:           run=profiles-app
Annotations:      <none>
Status:           Running
IP:               10.244.0.7
...
#+END_SRC

** Créer des ressources
*** Le /YAML/
#+BEGIN_smallfont
Dans /K8S/ les ressources se créent depuis des fichiers /YAML/ décrivant la ressource en question et ses paramètres.

Le language /YAML/ est un language de sérialisation semblale à /JSON/.

L'extension de fichier est =.yaml= ou =.yml=.

Exemple de fichier /YAML/:
#+END_smallfont

#+BEGIN_SRC yaml
---
clef: valeur
liste_de_nombres:
  - 1
  - 2
  - 3
liste_de_clefs_valeurs:
- titre: blade_runner
  note: 10
#+END_SRC

** Types de ressources et exemples
*** /Namespace/
[[https://kubernetes.io/docs/tasks/administer-cluster/namespaces/#creating-a-new-namespace][doc]]
#+BEGIN_SRC yaml
---
apiVersion: v1          # nécessaire pour que K8S comprenne
kind: Namespace         # le type de ressource
metadata:               # les informations de la ressource
  name: profiles-app    # ici, son nom
#+END_SRC

*** /Pod/
[[https://kubernetes.io/fr/docs/concepts/workloads/pods/pod-overview/][doc]]
#+BEGIN_SRC yaml
---
apiVersion: v1
kind: Pod                     # ici le type est "pod"
metadata:
  namespace: profiles-app-ns  # on choisi le namespace
  name: profiles-app          # le nom du pod
spec:                         # puis ses spécifications
  containers:                 # il contient des conteneurs
  - name: database            # nom du conteneur
    image: image:latest       # l'image à utiliser
    env:                      # variables d'environnement
    - name: COULEUR           # avec un nom
      value: "rouge"          # et une valeur
#+END_SRC


*** /Deployment/
[[https://kubernetes.io/fr/docs/concepts/workloads/controllers/deployment/][doc]]
#+BEGIN_SRC yaml
apiVersion: apps/v1
kind: Deployment         # un nouveau type, "Deployment"
metadata:
  name: nginx-deployment # on lui met un nom
  labels:                # et des labels
    app: nginx
spec:
  replicas: 3            # le nombre de réplications voulues
  selector:
    matchLabels:
      app: nginx
  template:              # champs qui seront appliqués aux pods
    metadata:
      labels:
        app: nginx
    spec:
      containers:        # on spécifie les conteneurs
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
#+END_SRC


*** /Service/
[[https://kubernetes.io/fr/docs/concepts/services-networking/service/][doc]]
#+BEGIN_SRC yaml
---
apiVersion: v1
kind: Service                # ici le type est "service"
metadata:
  namespace: profiles-app-ns # on choisi le namespace
  name: my-service           # on choisi un nom pour le service
spec:
  selector:                  # règles pour sélectionner le pod
    app.kubernetes.io/name: profiles-app # selection par nom
  ports:                     # on choisi les ports à exposer
    - protocol: TCP          # le protocole
      port: 80               # le port *CIBLE*
      targetPort: 9376       # le port *DU POD*
#+END_SRC




* Aller plus loin
- [1] <<source:cncf_survey>> [[https://www.cncf.io/reports/cncf-annual-survey-2023/][https://www.cncf.io/reports/cncf-annual-survey-2023/]]
- /Services/: https://kubernetes.io/fr/docs/concepts/services-networking/service/
- /Pods/: https://kubernetes.io/docs/concepts/workloads/pods/
- /Deployments/: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
