|
|
% Intended LaTeX compiler: pdflatex
|
|
|
\documentclass[12pt,a4paper]{article}
|
|
|
\usepackage[utf8]{inputenc}
|
|
|
\usepackage[T1]{fontenc}
|
|
|
\usepackage{graphicx}
|
|
|
\usepackage{longtable}
|
|
|
\usepackage{wrapfig}
|
|
|
\usepackage{rotating}
|
|
|
\usepackage[normalem]{ulem}
|
|
|
\usepackage{amsmath}
|
|
|
\usepackage{amssymb}
|
|
|
\usepackage{capt-of}
|
|
|
\usepackage{hyperref}
|
|
|
\usepackage{minted}
|
|
|
\usepackage[a4paper,margin=0.5in]{geometry}
|
|
|
\usepackage[utf8]{inputenc}
|
|
|
\usepackage[inkscapelatex=false]{svg}
|
|
|
\usepackage[sfdefault]{AlegreyaSans}
|
|
|
\usepackage{multicol}
|
|
|
\usepackage{minted}
|
|
|
\usepackage{float}
|
|
|
\usepackage{tikz}
|
|
|
\usetikzlibrary{positioning}
|
|
|
\renewcommand\listingscaption{Exemple de code}
|
|
|
\date{}
|
|
|
\title{Cours de virtualisation avancée: \emph{Kubernetes}, introduction}
|
|
|
\hypersetup{
|
|
|
pdfauthor={Evrard Van Espen},
|
|
|
pdftitle={Cours de virtualisation avancée: \emph{Kubernetes}, introduction},
|
|
|
pdfkeywords={},
|
|
|
pdfsubject={},
|
|
|
pdfcreator={Emacs 30.0.50 (Org mode 9.6.15)},
|
|
|
pdflang={English}}
|
|
|
\begin{document}
|
|
|
|
|
|
\maketitle
|
|
|
|
|
|
\section{Introduction, les \emph{clusters}}
|
|
|
\label{sec:orgc3a168b}
|
|
|
\begin{itemize}
|
|
|
\item Grappe de serveur
|
|
|
\item Groupe de machines fonctionnant ensemble
|
|
|
\end{itemize}
|
|
|
|
|
|
\section{\emph{Kubernetes}}
|
|
|
\label{sec:org2a25d0e}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=.9\linewidth]{./images/kube_logo.png}
|
|
|
\end{center}
|
|
|
|
|
|
\subsection{C'est quoi ?}
|
|
|
\label{sec:org21cf649}
|
|
|
\begin{itemize}
|
|
|
\item Ancien mot grec signifiant "timonier" (marin qui tient la barre)
|
|
|
\item Souvent abrégé \emph{"K8S"}
|
|
|
\item Système \emph{open-source} pour le \textbf{déploiement}, la \textbf{mise à l’échelle} et \textbf{gestion} de conteneurs
|
|
|
\item Configuration via des fichiers \emph{YAML}
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{Origine}
|
|
|
\label{sec:org25e70dd}
|
|
|
\begin{itemize}
|
|
|
\item Lancé par \emph{Google} en 2014
|
|
|
\item \emph{Google} s'associe à la \emph{Linux Foundation} pour créer la \emph{CNCF} en utilisant \emph{K8S} comme projet de départ
|
|
|
\end{itemize}
|
|
|
|
|
|
\emph{CNCF}: \emph{Cloud Native Computer Foundation}
|
|
|
|
|
|
\subsection{Quelques statistiques}
|
|
|
\label{sec:org84a3abf}
|
|
|
\begin{itemize}
|
|
|
\item 66\% : c'est le nombre d'entreprises qui utilisent \emph{K8S} en prod en 2023 [\ref{org0ea15b0}]
|
|
|
\item Entre 2018 et 2020 : \emph{K8S} top 10 projets les plus actifs \emph{Github}
|
|
|
\item Le nombre de conteneurs en prod dans le monde est inestimable mais \emph{Google} estime en lancer \textbf{2 milliards par semaine}
|
|
|
\end{itemize}
|
|
|
|
|
|
\section{Le monde des conteneurs}
|
|
|
\label{sec:org5ecc774}
|
|
|
\url{./images/containers.webp}
|
|
|
|
|
|
\subsection{Des applications souvent présentes}
|
|
|
\label{sec:org943bbce}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=.9\linewidth]{./images/top_container_images.png}
|
|
|
\end{center}
|
|
|
|
|
|
\begin{smallfont}
|
|
|
\begin{center}
|
|
|
\begin{tabular}{ll}
|
|
|
\textbf{Redis} & BDD clef-valeur\\[0pt]
|
|
|
\textbf{ElasticSearch} & NOSQL / moteur de recherche\\[0pt]
|
|
|
\textbf{Postgresql} & base de données SQL\\[0pt]
|
|
|
\textbf{RabbitMQ} & agent de message\\[0pt]
|
|
|
\textbf{Kafka} & agent de message / événements\\[0pt]
|
|
|
\textbf{Vault} & BDD sécurisés\\[0pt]
|
|
|
\textbf{Mongo} & BDD NOSQL\\[0pt]
|
|
|
\textbf{Nginx} & serveur web\\[0pt]
|
|
|
\textbf{Consul} & gestion de réseau\\[0pt]
|
|
|
\textbf{MySql} & BDD SQL\\[0pt]
|
|
|
\end{tabular}
|
|
|
\end{center}
|
|
|
\end{smallfont}
|
|
|
|
|
|
\subsection{Plusieurs orchestrateurs}
|
|
|
\label{sec:orgbfed1cc}
|
|
|
\subsubsection{\textbf{\emph{Kubernetes}}}
|
|
|
\label{sec:orgc08bdad}
|
|
|
\begin{imagecol}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/k8s_logo.png}
|
|
|
\end{center}
|
|
|
\end{imagecol}
|
|
|
|
|
|
\begin{textcol}
|
|
|
Le plus connu et utilisé, objet de ce cours
|
|
|
\end{textcol}
|
|
|
|
|
|
\subsubsection{\emph{\textbf{Nomad}}}
|
|
|
\label{sec:org753a09f}
|
|
|
\begin{imagecol}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/nomad_logo.png}
|
|
|
\end{center}
|
|
|
\end{imagecol}
|
|
|
|
|
|
\begin{textcol}
|
|
|
Proposé par \emph{Hashicorp}, solution d'orchestration hybride entre conteneurs, machines virtuelles et machines physiques.
|
|
|
\end{textcol}
|
|
|
|
|
|
\subsubsection{\emph{\textbf{Docker Swarm}}}
|
|
|
\label{sec:org806b74c}
|
|
|
\begin{imagecol}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/swarm_logo.png}
|
|
|
\end{center}
|
|
|
\end{imagecol}
|
|
|
|
|
|
\begin{textcol}
|
|
|
Proposé par \emph{Docker}, solution plus simple mais qui ne permet pas une utilisation aussi avancée.
|
|
|
\end{textcol}
|
|
|
|
|
|
\subsubsection{\emph{\textbf{Rancher}}}
|
|
|
\label{sec:org992d269}
|
|
|
\begin{imagecol}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/rancher_logo.png}
|
|
|
\end{center}
|
|
|
\end{imagecol}
|
|
|
|
|
|
\begin{textcol}
|
|
|
Une surcouche à \emph{Kubernetes} qui permet de simplifier son utilisation à grande échelle.
|
|
|
\end{textcol}
|
|
|
|
|
|
\subsection{Solutions à louer}
|
|
|
\label{sec:org51e50a2}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/eks_logo.png}
|
|
|
\end{center}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/aks_logo.png}
|
|
|
\end{center}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=2cm]{./images/gke_logo.png}
|
|
|
\end{center}
|
|
|
|
|
|
\section{Pourquoi un orchestrateur}
|
|
|
\label{sec:org43da0e2}
|
|
|
\url{./images/why.gif}
|
|
|
|
|
|
\begin{itemize}
|
|
|
\item Déploiement et mise à l'échelle automatique
|
|
|
\item Haute disponibilité / réplication
|
|
|
\item Optimisation des ressources
|
|
|
\item Supervision et journalisation
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{Déploiement et mise à l'échelle automatique}
|
|
|
\label{sec:orgc07e292}
|
|
|
\begin{itemize}
|
|
|
\item Déploiement via de la \emph{CI}
|
|
|
\item Mises à jours automatiques des conteneurs
|
|
|
\item Allocation automatique des ressources
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{Haute disponibilité}
|
|
|
\label{sec:orga8c0f71}
|
|
|
\begin{itemize}
|
|
|
\item Réplication des applications
|
|
|
\begin{itemize}
|
|
|
\item Pour les performances
|
|
|
\item Pour la sécurité
|
|
|
\end{itemize}
|
|
|
\item Tolérance aux pannes de machines
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{Optimisation des ressources}
|
|
|
\label{sec:org8d7c148}
|
|
|
\begin{itemize}
|
|
|
\item Utilisation de conteneurs
|
|
|
\item Choix des cibles de déploiement en fonction de leur usage et occupation
|
|
|
\item Dé-allocation des ressources en cas de baisse de charge
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{Supervision et journalisation}
|
|
|
\label{sec:orgaa33e66}
|
|
|
\begin{itemize}
|
|
|
\item Gestion unifiée des journaux
|
|
|
\item Outils automatisés
|
|
|
\end{itemize}
|
|
|
|
|
|
\section{\emph{Kubernetes}}
|
|
|
\label{sec:orgc3a6b2f}
|
|
|
\subsection{Terminologie et concepts}
|
|
|
\label{sec:org98aabf4}
|
|
|
\begin{description}
|
|
|
\item[{\emph{Namespace}}] \begin{itemize}
|
|
|
\item Un "espace de noms"
|
|
|
\item Permet de regrouper les ressources pour s'y retrouver et simplifier la gestion
|
|
|
\end{itemize}
|
|
|
|
|
|
\item[{\emph{Pod}}] \href{https://kubernetes.io/fr/docs/concepts/workloads/pods/pod-overview/}{doc}
|
|
|
\begin{itemize}
|
|
|
\item La plus petite unité d'exécution
|
|
|
\item C'est dans ces éléments que sont présents les conteneurs
|
|
|
\item Réseau local entre les conteneurs d'un même \emph{pod}
|
|
|
\end{itemize}
|
|
|
\end{description}
|
|
|
|
|
|
\begin{description}
|
|
|
\item[{\emph{Service}}] \href{https://kubernetes.io/fr/docs/concepts/services-networking/service/}{doc}
|
|
|
\begin{itemize}
|
|
|
\item Une manière d'exposer une application s'exécutant sur un ensemble de \emph{pods} en tant que service réseau
|
|
|
\item Possède une adresse \emph{IP} et un nom \emph{DNS}
|
|
|
\item Permet l'équilibration de la charge
|
|
|
\end{itemize}
|
|
|
\end{description}
|
|
|
|
|
|
\begin{description}
|
|
|
\item[{\emph{Volume}}] \href{https://kubernetes.io/fr/docs/concepts/storage/volumes/}{doc}
|
|
|
\begin{itemize}
|
|
|
\item Permet le stockage des fichiers d'un \emph{pod} (sinon fichiers perdu lors de la destruction du \emph{pod})
|
|
|
\item Permet de partager des fichiers entre des conteneurs au sein d'un \emph{pod}
|
|
|
\end{itemize}
|
|
|
\end{description}
|
|
|
|
|
|
Il reste encore une multitudes de concepts et de termes propres à \emph{Kubernetes}.
|
|
|
Je vous invite donc à consulter cette page: \href{https://kubernetes.io/fr/docs/concepts/}{https://kubernetes.io/fr/docs/concepts/}.
|
|
|
|
|
|
\subsection{Architecture}
|
|
|
\label{sec:org679afa4}
|
|
|
\begin{center}
|
|
|
\includegraphics[width=.9\linewidth]{./images/k8s_cluster.png}
|
|
|
\end{center}
|
|
|
|
|
|
\begin{itemize}
|
|
|
\item Composé de plusieurs nœuds
|
|
|
\item Au moins 1 nœud de gestion et 1 nœud de travail
|
|
|
\end{itemize}
|
|
|
|
|
|
\subsubsection{Nœud de gestion}
|
|
|
\label{sec:orgcd1d45e}
|
|
|
\begin{itemize}
|
|
|
\item Aussi appelé \emph{"control plane"} dans la terminologie \emph{K8S}
|
|
|
\item Composant principal
|
|
|
\item Gestion de la charge de travail
|
|
|
\item Services qui contrôlent le \emph{cluster}
|
|
|
\end{itemize}
|
|
|
|
|
|
\begin{description}
|
|
|
\item[{\emph{etcd}}] stocke les éléments de configuration
|
|
|
\item[{\emph{API server}}] reçoit et traite les requêtes de gestion. Vérifie en permanence que l'état du \emph{cluster} correspond aux configurations stockées dans \texttt{etcd}
|
|
|
\item[{\emph{Scheduler}}] se charge de la répartition de la charge
|
|
|
\item[{\emph{Controller manager}}] applique les actions requises à la gestion du \emph{cluster}
|
|
|
\end{description}
|
|
|
|
|
|
\subsubsection{Nœud de travail}
|
|
|
\label{sec:org7ef6e06}
|
|
|
\begin{itemize}
|
|
|
\item C'est sur ces nœuds que les conteneurs sont déployés
|
|
|
\item Cela peut être des machines physiques ou virtuelles
|
|
|
\end{itemize}
|
|
|
|
|
|
\begin{description}
|
|
|
\item[{\emph{kubelet} ou \emph{node manager}}] \begin{itemize}
|
|
|
\item Se charge de la gestion des \emph{pods} sur le nœud
|
|
|
\item Reçoit ses ordres du \emph{control plane}
|
|
|
\item Informe le \emph{control plane} de l'état du nœud
|
|
|
\end{itemize}
|
|
|
|
|
|
\item[{\emph{kube-proxy}}] \begin{itemize}
|
|
|
\item Se charge de la gestion du réseau
|
|
|
\end{itemize}
|
|
|
|
|
|
\item[{\emph{container runtime}}] L'environnement d’exécution des conteneurs, souvent \emph{Docker}
|
|
|
\end{description}
|
|
|
|
|
|
\section{Prise en main}
|
|
|
\label{sec:org41ca293}
|
|
|
\begin{itemize}
|
|
|
\item Les interactions avec \emph{K8S} se font via la commande \texttt{kubectl}.
|
|
|
\item Quelques interactions sont aussi possible via le \emph{dashboard} mais ce dernier est limité et ne sera pas abordé pendant ce cours.
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
|
\subsection{Appliquer une configuration}
|
|
|
\label{sec:org1cffc4a}
|
|
|
Cela se fait avec la commande
|
|
|
\begin{minted}[]{bash}
|
|
|
kubectl apply -f <fichier.yaml>
|
|
|
\end{minted}
|
|
|
|
|
|
\subsection{Lister des ressources}
|
|
|
\label{sec:orgb66e506}
|
|
|
\begin{NOTE}
|
|
|
Syntaxe:
|
|
|
|
|
|
\texttt{kubectl get <ressource>}
|
|
|
\end{NOTE}
|
|
|
|
|
|
\begin{minted}[]{bash}
|
|
|
❯ kubectl get pods
|
|
|
NAME READY STATUS RESTARTS AGE
|
|
|
profiles-app 3/3 Running 0 22s
|
|
|
\end{minted}
|
|
|
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
\subsection{Lire les journaux d'un \emph{pod}}
|
|
|
\label{sec:org366f208}
|
|
|
|
|
|
\begin{NOTE}
|
|
|
Syntaxe:
|
|
|
|
|
|
\texttt{kubectl logs <nom ressource>}
|
|
|
\end{NOTE}
|
|
|
|
|
|
\begin{minted}[]{bash}
|
|
|
❯ kubectl logs profiles-app
|
|
|
...
|
|
|
\end{minted}
|
|
|
|
|
|
\subsection{Supprimer une ressource}
|
|
|
\label{sec:orgf9e8dd4}
|
|
|
\begin{NOTE}
|
|
|
Syntaxe:
|
|
|
|
|
|
\texttt{kubectl delete <type ressource> <nom ressource>}
|
|
|
|
|
|
ou
|
|
|
|
|
|
\texttt{kubectl delete -f <fichier.yaml>}
|
|
|
\end{NOTE}
|
|
|
|
|
|
\begin{minted}[]{bash}
|
|
|
❯ kubectl delete pods profiles-app
|
|
|
pod "profiles-app" deleted
|
|
|
\end{minted}
|
|
|
|
|
|
\subsection{Décrire une ressource}
|
|
|
\label{sec:org0573c54}
|
|
|
\begin{NOTE}
|
|
|
Syntaxe:
|
|
|
|
|
|
\texttt{kubectl describe <type ressource> <nom ressource>}
|
|
|
\end{NOTE}
|
|
|
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
\subsection{Créer des ressources}
|
|
|
\label{sec:orgb64ac81}
|
|
|
\subsubsection{Le \emph{YAML}}
|
|
|
\label{sec:org9988630}
|
|
|
\begin{smallfont}
|
|
|
Dans \emph{K8S} les ressources se créent depuis des fichiers \emph{YAML} décrivant la ressource en question et ses paramètres.
|
|
|
|
|
|
Le language \emph{YAML} est un language de sérialisation semblale à \emph{JSON}.
|
|
|
|
|
|
L'extension de fichier est \texttt{.yaml} ou \texttt{.yml}.
|
|
|
|
|
|
Exemple de fichier \emph{YAML}:
|
|
|
\end{smallfont}
|
|
|
|
|
|
\begin{minted}[]{yaml}
|
|
|
---
|
|
|
clef: valeur
|
|
|
liste_de_nombres:
|
|
|
- 1
|
|
|
- 2
|
|
|
- 3
|
|
|
liste_de_clefs_valeurs:
|
|
|
- titre: blade_runner
|
|
|
note: 10
|
|
|
\end{minted}
|
|
|
|
|
|
\subsection{Types de ressources et exemples}
|
|
|
\label{sec:orge9534e4}
|
|
|
\subsubsection{\emph{Namespace}}
|
|
|
\label{sec:org462bf90}
|
|
|
\href{https://kubernetes.io/docs/tasks/administer-cluster/namespaces/\#creating-a-new-namespace}{doc}
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
\subsubsection{\emph{Pod}}
|
|
|
\label{sec:org39c1bdd}
|
|
|
\href{https://kubernetes.io/fr/docs/concepts/workloads/pods/pod-overview/}{doc}
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
|
|
|
\subsubsection{\emph{Deployment}}
|
|
|
\label{sec:org598f74f}
|
|
|
\href{https://kubernetes.io/fr/docs/concepts/workloads/controllers/deployment/}{doc}
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
|
|
|
\subsubsection{\emph{Service}}
|
|
|
\label{sec:org70f82f6}
|
|
|
\href{https://kubernetes.io/fr/docs/concepts/services-networking/service/}{doc}
|
|
|
\begin{minted}[]{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{minted}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section{Aller plus loin}
|
|
|
\label{sec:org09845a1}
|
|
|
\begin{itemize}
|
|
|
\item\relax [1] \label{org0ea15b0} \href{https://www.cncf.io/reports/cncf-annual-survey-2023/}{https://www.cncf.io/reports/cncf-annual-survey-2023/}
|
|
|
\item \emph{Services}: \url{https://kubernetes.io/fr/docs/concepts/services-networking/service/}
|
|
|
\item \emph{Pods}: \url{https://kubernetes.io/docs/concepts/workloads/pods/}
|
|
|
\item \emph{Deployments}: \url{https://kubernetes.io/docs/concepts/workloads/controllers/deployment/}
|
|
|
\end{itemize}
|
|
|
\end{document}
|