Vous êtes sur la page 1sur 39

La solution d’orchestration de containers

Présentation

Kubernetes signifie ‘pilote’ en Grec ancien, ce qui évoque un gouvernail de commande.

Kubernetes, aussi appelé ‘K8S’ (puisque 8 lettres sont comprises entre le ‘k’ et le ‘s’), est une plateforme
logicielle Open Source extensible et portable, dont l’objet est d’assurer la gestion de charges de
travail (Workloads) et de services assurés par des containers Linux.

Kubernetes favorise l’écriture de configuration déclarative (declarative configuration) et


l'automatisation.

L’objectif de Kubernetes est de pouvoir orchestrer un cluster de containers en automatisant tous les
processus manuels associés au déploiement, à la gestion et à la mise à l'échelle des applications
définies dans des containers d'applications.

Kubernetes fonctionne sur le concept du mode déclaratif, ce qui signifie qu’il se charge d’atteindre
l’état de fonctionnement dicté par l’administrateur.

Les containers peuvent êtres répartis sur des 'nœuds' appelés ‘nodes’, définis à l’intérieur d'un
ensemble de machines, le tout, constituant le 'cluster'.

➔ L’intérêt d'un cluster est de pouvoir assurer la haute disponibilité des services.

D’où vient Kubernetes

À l'origine, la plateforme Kubernetes a été développée et conçue par des ingénieurs de chez Google,
qui est l'un des premiers contributeurs aux technologies de containers Linux (LXC).

A titre indicatif, en 2016 Google déploie plus de 2 milliards de containers par semaine via
une plateforme interne nommée Borg, qui est la ‘grande sœur’ de Kubernetes.

Google a fait don du projet Kubernetes à la Cloud Native Computing Foundation (CNCF),
lors de sa création en 2015.

La documentation est ici : https://kubernetes.io/fr/docs/tutorials/kubernetes-basics/

Kubernetes v240310 Jean GAUTIER 1


Intérêts de Kubernetes

La technologie Kubernetes offre une plateforme réservée à la planification et à l'exécution de


containers sur des clusters de machines physiques ou virtuelles.

Kubernetes apporte une solution efficace pour la mise en œuvre d'une infrastructure de déploiement
automatique de containers dans des environnements de production, que ce soit en cloud ou en
infrastructures locales ('on-premise').

L’orchestration des containers vise à automatiser :


✗ leur déploiement
✗ la gestion
✗ la mise à l’échelle
✗ leur mise en réseau
✗ l’auto réparation

Kubernetes s'occupe de tout, il est notamment capable d’automatiser le démarrage et l’arrêt de


nœuds (nodes), afin d’éviter d’avoir à faire intervenir l’humain dans une chaîne de processus de
déploiement à grande échelle.

Kubernetes v240310 Jean GAUTIER 2


Architecture
Kubernetes réalise l'orchestration de containers, en ce sens qu'il permet de gérer efficacement et de
manière sûr, des grappes de machines, appelées ‘Clusters’.

Le terme Cluster désigne un déploiement représentant une architecture de containers, répartis.

➢ Les Clusters constituent des ensembles de machines, appelées ‘nodes’


➢ Les nodes regroupent des machines appelées ‘pods’
➢ Les pods sont les machines qui encapsulent un ou plusieurs Containers sur lesquels
s’exécutent les process en fonctionnement dans le cluster
Les pods sont dotés de ressources de stockage et d’une identité réseau unique, ils servent
d’environnement d’exécution de base de kubernetes

➔ Dans la pratique, il est conseillé de n'associer qu’un seul container par pod !

Il existe deux types de ‘nodes’ :


1. le ‘Master’ qui est le nœud maître dont le rôle est de piloter les ‘Workers’.
2. les ‘Workers’ qui sont les nœuds de travail où s’exécutent les applications.

Kubernetes v240310 Jean GAUTIER 3


La configuration des éléments de kubernetes
En utilisant l’outil en ligne de commande ‘kubectl’ ou en injectant des instructions à l’aide d’un
fichier descripteur en ‘yaml’, l’administrateur DevOps met en place la configuration de l’état
souhaité du cluster et Kubernetes

La configuration de l’état souhaité constitue le ‘control plane’ (plan de contrôle), elle s’établit sur le
nœud ‘Master’.

Le but du ‘control plane’ est d’amener et de maintenir le cluster dans l’état souhaité.
➔ Grace au plan de contrôle, le Master’ prend les décisions de planification et de
modification nécessaires, puis il transfère ses instructions aux ' Workers’.

✗ Le ‘Master’ assure la gestion des 'Workers' en appliquant le ‘plan de contrôle'.


✗ Les 'Workers' sont les machines de calcul chargées de l’exécution des applications.
Ce sont les Workers qui exécutent les applications, via les containers, repartis en ’pods’

Organisation des opérations


Dans un déploiement de cluster kubernetes, l'administrateur DevOps déclare et définit les
‘nodes’, les ‘pods’ et les ‘Containers’ qu'ils contiennent.
Kubernetes s'occupe du reste : il gère l'orchestration des containers.

Lors du déploiement d’un nouveau container, l’orchestrateur démarre le déploiement vers un


cluster en ciblant le ‘node’ approprié, en s'appuyant sur les exigences ou restrictions définies
dans le ‘Control plan’.

La configuration du plan de contrôle est décrite dans des fichiers de type YAML ou JSON,
appelés 'manifest'.

Le ‘manifest’ indique notamment où trouver les images de containers, comment établir un


réseau et où stocker les journaux.

Kubernetes v240310 Jean GAUTIER 4


Présentation des composants essentiels

• etcd
etcd la base de données qui constitue le magasin de données des informations du cluster, au format :
clé-valeur.
Toutes les ressources du cluster y sont inscrites.

• API Server
APIServer est une interface REST qui s’occupe de lire et écrire dans la base ‘etcd’ en mode ‘CRUD’
(Create, Read, Update, Delete)
API Server s’occupe également de transporter les informations du plan de contrôle.

• Scheduler
Le scheduler s’occupe d'affecter un ‘node’ aux ‘pods’ qui sont créés.
Dès qu'un ‘pod ‘est créé ou modifié, le scheduler va transmettre des requêtes à l'’API server’ afin de
modifier les ressources.

• Controller Manager
Le ‘Controller Manager’ gère les briques de type ‘contrôleur’ afin de placer et de maintenir le
cluster, dans l’état souhaité.

• Kubelet
Kubelet est le composant du ‘control plane’ qui est exécuté sur les ‘workers nodes’ afin de gérer tout
ce qui se passe sur le nœud.

Kubelet surveille l'API Server ‘pour découvrir les ‘pods’ qui lui ont été affectés et démarre alors les
conteneurs du ‘pod‘ via le ‘container runtime’.

Kubernetes v240310 Jean GAUTIER 5


Fonctionnement de Kubernetes
Kubernetes exploite un ensemble de services permettant de choisir automatiquement le ‘node’ le
plus approprié pour réaliser une tâche, d’allouer les ressources et d’attribuer le travail aux ‘pods’
disponibles.

Le Master surveille l’infrastructure du cluster, démarre et arrête les ‘nodes’ supplémentaires en


fonction des règles qui ont été fixées.
Il va être en mesure de définir quel ‘node’ de type ‘Worker’’doit être utilisé en contrôlant qu’il reste
suffisamment de ressources disponibles afin d’y déployer de nouveaux containers.

Pour exécuter les opérations, l'administrateur utilise la commande 'kubectl' permettant de passer les
ordres aux ‘nodes’, afin d’administrer dynamiquement le cluster Kubernetes.

Par exemple, la commande 'kubectl run' est équivalente à la commande 'docker run'.

Lorsqu'un 'node' reçoit les commandes, kubernetes alloue dynamiquement les ressources aux pods,
afin de de permettre l’exécution des tâches demandées et de planifier un pod.
‘kubelet’ est un agent logiciel qui s'exécute sur chaque nœud, afin de commander le fonctionnement
des containers et d'en contrôler l'état.
C'est le 'kubelet' du nœud qui donne l'ordre à Docker de lancer les containers spécifiés.

• Le ‘kubelet’ permet en outre d’informer le ‘Master’ de l’état de disponibilité et


d‘occupation du ‘node’ et des ‘pods’ qui sont disponibles .

L’administrateur DevOps va se contenter d’administrer le serveur maître et non, chaque nœud


séparément.

Les formats de codification tels que JSON (JavaScript Object Notation), REST (Representational State
Transfer) ou YAML sont très impliqués dans la constitutions de l’infrastructure.

Kubernetes v240310 Jean GAUTIER 6


La notion de services

Le service est un point d’entrée vers un groupe de containers identiques, définit sous forme d’une
adresse IP virtuelle (VIP).

Le pod permet d'encapsuler un ou plusieurs containers en offrant des ressources de stockage


communes (volume) et peut piloter l'ensemble des containers en utilisant une adresse IP virtuelle
globale.

➔ Les services permettent l'abstraction des pods.

Kubernetes offre nativement les services de proxy, de nommage DNS, de routage et d’adressage IP,
permettant d’associer une adresse et un nom de domaine à un service applicatif disponible sur les
containers de l’infrastructure.
Cette notion de services, permet de rendre un serveur accessible en visant les pods opérationnels où
ce service est définit et de garantir la répartition de charges (Load balancing) entre les containers des
différents nodes.

Kubernetes v240310 Jean GAUTIER 7


Depuis 2018, Kubernetes ne supporte plus Docker !

Qu'est ce qu'un ‘Container runtime’


Un ‘Container runtime’ est utilisé pour créer et faire fonctionner les containers.
Son rôle est de piloter les gestionnaires de containers, tels que : 'containerd', 'cri-o', 'kata
container'.
Bien que ‘containerd’ soit le choix de prédilection avec kubernetes, si on ne spécifie pas de runtime
particulier, kubeadm cherchera à détecter quel ‘container runtime’ est installé, afin de l’utiliser.

L'Open Container Initiative (OCI) a été créée afin de standardiser les outils et API d’exécution des
containers.
➔ Il s'agit du standard 'runc' qui est issu de Docker

containerd est désormais un projet de la Cloud Native Computing Foundation (CNCF).

Kubernetes utilise une interface API spécifique nommée ‘CRI' (Container Runtime Interface) pour
dialoguer avec le ‘Container runtime’.

➔ C’est le composant ‘kubelet’ qui assure la communication entre Kubernetes et les ‘runtime’.

L'utilisateur interagit directement avec la ‘runtime de haut niveau‘ dont le rôle est d’assurer
la récupération des images de containers.

Une fois ces activités de haut niveau effectuées, elle délègue à la ‘runtime de bas niveau’ les
tâches pour créer les conteneurs.

Kubernetes v240310 Jean GAUTIER 8


Mise en place rapide d’un cluster

Expérimentations diverses

Pré-requis pour installer un cluster Kubernetes :

✔ Plusieurs machines sous Linux Debian avec accès root (sudo)


✔ Deux Go de RAM minimum par machine
✔ Deux processeurs par machine
✔ Connectivité réseau complète entre toutes les machines du cluster
✔ Résolution du noms des machines (fichiers 'hosts' ou DNS)
✔ Connexion avec l’utilisateur ‘root’
✔ Le 'swap' disque doit être désactivé de manière permanente

Pour installer un cluster Kubernetes, plusieurs possibilités

✔ Soit opter pour une installation standard officielle de Kubernetes avec ‘kubeadm’ qui permet de
déployer un 'vrai' cluster, en installant le nœud ‘Master’ et en inscrivant des nœuds de travail
(Workers) sur les machines cibles.

✔ Soit envisager une découverte et prise en main de Kubernetes, en utilisant une solution
d’expérimentation simple et efficace, rendant un cluster opérationnel en quelques minutes.
Dans ce cas, on pourra mettre en place une architecture à nœud unique, (Master/Workers), telle que
l'application 'minikube'.

✔ Soit en visant un déploiement d'un cluster léger en exploitant des procédure d'auto-installation ,
telles que l’application ‘K3S’ ou RKE qui sont des implémentation axée sur la légèreté, permettant
de mettre un cluster en production de façon simple et rapide.

Kubernetes v240310 Jean GAUTIER 9


Expérimentation Kubernetes avec ‘kubeadm’
Pour une installation 'standard', kubeadm est le projet officiel permettant de démarrer un cluster
Kubernetes.

Pour mener à bien cette expérimentation, nous devons préparer 3 x machine Linux Debian 64 bits,
équipée chacune d’au moins 2 x CPU, de 3 GiO de RAM et d’un disque de stockage de 40GiO

➔ La machine n°1 sera le ‘nœud master’, les autres machines, seront respectivement
les ‘nœuds workers, 1 et 2

Commandes à exécuter sur TOUS les nœuds

Préparation initiale des machines


1. swapoff -a
2. sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

Installation des composants de base


1. apt update -y
2. apt install -y containerd sudo curl apt-transport-https ca-certificates gpg bash-completion snapd
software-properties-common wget
3. containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
4. sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml
5. systemctl enable --now containerd

Activer les fonctionnalités réseau nécessaires


1. tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF

2. modprobe overlay && modprobe br_netfilter

3. cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf


net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

4. sysctl --system

Kubernetes v240310 Jean GAUTIER 10


Commandes à exécuter sur TOUS les nœuds

Installation des outils 'kubeadm' et 'kubectl'

➔ Il est recommandé d’appliquer la procédure officielle, accessible ici

• kubeadm est l’installeur Kubernetes à exécuter sur chacun des nœuds du cluster
• kubelet est le démon en charge d’exécuter et de gérer les conteneurs sur chacun des nœuds du cluster
• kubectl est l’interface qui fournit la ligne de commande permettant de communiquer avec le cluster

Attention pour les deux commandes suivantes, bien faire en sorte que toutes les instructions
soient définie sur une seule ligne (Astuce : copier/coller l'instruction dans un 'bloc note')

1. curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o


/etc/apt/keyrings/kubernetes-apt-keyring.gpg

2. echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg]


https://pkgs.k8s.io/core:/stable:/v1.28/deb/ / " > /etc/apt/sources.list.d/kubernetes.list

3. apt update -y
4. apt install -y kubelet kubeadm kubectl
5. apt-mark hold kubelet kubeadm kubectl

6. source <(kubectl completion bash)

Kubernetes v240310 Jean GAUTIER 11


Commandes à exécuter UNIQUEMENT sur le nœud MASTER
Initialisation du cluster
Création d’un nouveau cluster

1. kubeadm init --cri-socket /run/containerd/containerd.sock --v=5 --pod-network-cidr=10.5.0.0/16

Le message qui s'affiche en fin de procédure représente la commande qu'il faudra utiliser sur les Workers, afin de
les joindre au Cluster

Exemple de message :
kubeadm join 192.168.100.43:6443 --token w0mvog.nxnh1mihgy20mvtw --discovery-token-ca-cert-hash
sha256:5a668a0625c7b698d3c531aad5569bcbb91a6467f28e722351cd4a7be4fde014

En cas d’échec, on peut annuler le déploiement avec la commande :


kubeadm reset

Finalisation de la configuration de ‘kubectl’

1. export KUBECONFIG=/etc/kubernetes/admin.conf
2. mkdir -p $HOME/.kube
3. cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
4. chown $(id -u):$(id -g) $HOME/.kube/config
5. export KUBECONFIG=/etc/kubernetes/admin.conf

Les nœuds ne seront pas prêts tant qu’aucun plugin réseau ne sera actif
➔ Il faut donc installer un plugin de gestion réseau, tel que Calico ou Flannel, Cilium, ...

Soit Flannel, en faisant :


• wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
• kubectl apply -f kube-flannel.yml

ou bien Calico, en faisant :


1. curl https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml -O
2. kubectl apply -f calico.yaml
ou alors Canal, qui est un mixte de Flannel et Calico, avec les commandes suivantes :
1. curl https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/canal.yaml -O
2. kubectl apply -f canal.yaml

ou encore Cilium, avec la procédure suivante :


1. snap install helm --classic
2. helm repo add cilium https://helm.cilium.io/
3. helm install cilium cilium/cilium --version 1.11.2 --namespace kube-system --set
ipam.mode=kubernetes --set kubeProxyReplacement=strict --set k8sServiceHost=192.168.100.100
--set k8sServicePort=6443

Kubernetes v240310 Jean GAUTIER 12


Commandes à exécuter UNIQUEMENT sur les nœuds ‘workers’

Ajouter les nœuds workers au cluster

Pour joindre le cluster, il suffit de coller la commande récupérée lors de l’initialisation du cluster
kubeadm join x.x.x.x:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

où :
✗ x.x.x.x est l’adresse IP du Master
✗ <token> est le jeton qui permet au nœud de s’identifier
✗ <hash> permet au nœud de s’assurer de l’authenticité du nœud maître.

Une fois les nœuds ajoutés, pour contrôler que tous c’est bien passé, on vérifie l’existence des
nœuds, depuis le Master
kubectl get nodes -o wide

Si besoin, il est possible de visualiser ou régénérer un nouveau jeton (token) sur le Master
• Pour obtenir le jeton : kubeadm token list
• Pour en créer un nouveau (expire après 24 H) : kubeadm token create --print-join-command
• Pour obtenir le hash de la clé utilisée :
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed
's/^.* //'

Kubernetes v240310 Jean GAUTIER 13


Installation du dashboard sous kubeadm
Le dashboard est un tableau de bord permettant de superviser et administrer un cluster kubernetes, via une
interface accessible par un navigateur web.

Installation
1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/
recommended.yaml

Contrôle des éléments


1. kubectl get all -n kubernetes-dashboard

Modification du type de service


1. kubectl edit svc -n kubernetes-dashboard kubernetes-dashboard

Vérifier le fonctionnement du service


1. kubectl get svc -n kubernetes-dashboard

Créer un compte utilisateur


Fichier 'dashboard-user.yaml'
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-user
namespace: kubernetes-dashboard

• kubectl apply -f dashboard-user.yaml

Kubernetes v240310 Jean GAUTIER 14


Établir le lien entre l'utilisateur et le service
Fichier 'dashboard-bind.yaml'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboard-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-user
namespace: kubernetes-dashboard

• kubectl apply -f dashboard-bind.yaml

Créer et récupérer le jeton d'accès


1. kubectl create token dashboard-user -n kubernetes-dashboard

Il suffit de copier le
jeton

Se connecter à l'interface
https://node2.local:32321/#/login ← On se connecte sur le nœud sur lequel tourne le service

Insérer le jeton dans le champ prévu

Kubernetes v240310 Jean GAUTIER 15


2 - Expérimentation Kubernetes avec ‘minikube’
Dans le cadre d’une mise en labo à des fins d’évaluation, plutôt que d’installer une ‘vrai’
infrastructure comportant plusieurs machines, on peut évaluer le fonctionnement de Kubernetes en
utilisant une simple machine regroupant à la fois les nœuds Master et les nœuds Workers.
➔ On peut alors utiliser minikube

minikube est une application open-source permettant de déployer un cluster kubernetes à nœud
unique, sur une seule machine.

• minikube nécessite un hyperviseur de machines virtuelles, afin de créer une VM, pour
fonctionner ou un environnement de containérisation

Procédure d'installation de minikube

Préparation de la machine
• apt update -y && apt upgrade -y
• apt install curl wget apt-transport-https gnupg2 sudo software-properties-common -y
• reboot

Installation de Docker
• install -m 0755 -d /etc/apt/keyrings
• curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o
/etc/apt/trusted.gpg.d/debian.gpg
• add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $
(lsb_release -cs) stable"
• apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Installation de minikube
• curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
• install minikube-linux-amd64 /usr/local/bin/minikube
• curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
• chmod +x ./kubectl && sudo mv ./kubectl /usr/local/bin
• source <(kubectl completion bash)
• echo "source <(kubectl completion bash)" >> ${HOME}/.bashrc

Lancement et vérifications de fonctionnement


• minikube start --driver docker

➔ A ce stade des opération, Kubernetes est déployé et le cluster, initialisé

Kubernetes v240310 Jean GAUTIER 16


Vérifications de base
Examiner le fonctionnement
minikube status

Voir les informations du cluster (affiche l’état de fonctionnement et le socket d’accès réseau)
kubectl cluster-info

Mettre à jour le cluster


minikube start --kubernetes-version=latest

Afficher la configuration par défaut du cluster


kubectl config view

Voir les pods de l’espace de nom


kubectl get pods -A

Voir les services existants


Un service est une application du cluster, exposée vers l’extérieur (possède une adresse IP)
kubectl get services

Supprimer un service
kubectl delete service -l app=’nom’

Examiner la définition d’un pod


kubectl describe pods ‘nom’

Voir les ‘nodes’ actifs


kubectl get nodes

Kubernetes v240310 Jean GAUTIER 17


Lister les extensions minikube disponibles
minikube addons list

Activer/Désactiver une extension


minikube addons enable <nom> / minikube addons disable <nom>

Activer une extension au démarrage


minikube start --addons <name1> --addons <name2>

Voir les logs d’un pod


kubectl logs ‘nom’

Exécuter une commande dans un pod


kubectl exec nom -- ‘commande’

Se connecter au shell d’un pod, en mode interactif


kubectl exec -ti ‘nom’ -- bash

Kubernetes v240310 Jean GAUTIER 18


Installation du dashboard sous minikube

Le dashboard est un tableau de bord permettant de superviser et administrer un cluster kubernetes, via une
interface accessible par un navigateur web.

Avec minikube, dashboard est installable en ajoutant simplement un module (add-on)


minikube addons enable dashboard

Accéder à l’environnement global


La machine locale doit supporter l’environnement graphique

minikube dashboard &

Si la machine ne possède pas d’environnement graphique, il faut une liaison de type ‘reverse proxy’.

Établir l’accès au ‘dashboard’ depuis une machine extérieure


minikube addons enable ingress
minikube dashboard &
kubectl proxy --address='x.x.x.x' --accept-hosts='^*$' &
→ où ‘x.x.x.x’ est l’adresse de la machine master

Pour accéder au Dashboard depuis un poste client réseau, il faut se connecter sur l’adresse de la
machine master
http://x.x.x.x:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
#/workloads?namespace=default
→ où ‘x.x.x.x’ est l’adresse de la machine master

Kubernetes v240310 Jean GAUTIER 19


3 - Expérimentation Kubernetes avec ‘K3S’
K3S est une solution logicielle proposée par la société ‘Rancher’ permettant de mettre en place
rapidement un cluster Kubernetes léger.

K3S est la solution idéale pour la mise en place d’un cluster kubernetes destiné à l’usage des objets
‘IoT’ ou impliquant des machines d’architecture de type ‘ARM’ (comme le raspberry pi).

K3s consiste en une simple application d’environ 50Mo, nécessitant seulement 512 de RAM pour
fonctionner !
Elle s’appuie sur le runtime de container ‘containerd’, utilise le gestionnaire de réseau ‘flannel’ et
exploite une base de données SQLite à la place de etcd.

Pour la mise en œuvre d’un cluster, il suffit de lancer le script de déploiement sur la machine
destinée à la fonction de ‘Nodes Manager’ et ensuite, d’inscrire le ou les nœuds de type ‘Workers’,
sur lesquels les ‘pods’ pourront alors êtres déployés.

Kubernetes v240310 Jean GAUTIER 20


Exemple du déploiement d’un cluster ‘K3S’ sur un ensemble de trois machines

Pour cette mise en œuvre, on utilise un ensemble de machines composé de :

1. Une première machine utilisée en nœud ‘Manager’


Nom = ‘k3s-m’ - Adresse IP = ‘192.168.100.100’

2. Une deuxième machine utilisée en nœud ‘Worker’ 1


Nom = ‘k3s-nd1’ - Adresse IP = ‘192.168.100.110’

3. Une troisième machine utilisée en nœud ‘Worker’ 2


Nom = ‘k3s-nd2’ - Adresse IP = ‘192.168.100.120’

Installation de k3s sur la machine ‘k3s-m’


Création d’un fichier ‘/etc/hosts’, comportant :
127.0.0.1 localhost
192.168.100.100 k3s-m
192.168.100.110 k3s-nd1
192.168.100.120 k3s-nd2

Copie du fichier ‘/etc/hosts’ sur les nœuds ‘workers’


scp /etc/hosts root@k3s-nd1:/etc/
scp /etc/hosts root@k3s-nd2:/etc/

Installation de k3s
curl -sfL https://get.k3s.io | sh -

On obtient un ‘token’ qui permettra aux nœuds ‘Workers’ de joindre le cluster, p our le voir
cat /var/lib/rancher/k3s/server/node-token

Copier le ‘token’ sur les nœuds 'Workers'


cat /var/lib/rancher/k3s/server/node-token | ssh root@k3s-nd1 'dd of=token'
cat /var/lib/rancher/k3s/server/node-token | ssh root@k3s-nd2 'dd of=token'
→ Le token sera copié sur les machine cibles (workers), sous ‘/root/token’

Kubernetes v240310 Jean GAUTIER 21


Installation et intégration des nœuds ‘Workers’ au cluster

On affiche et on capture le contenu du ‘token’


cat /root/token ← capturer le contenu (avec la souris)

On définit des variables pour le token et le nœud ‘Manager’


k3s_url="https://k3s-m:6443"
k3s_token="xxxx" ← où xxxx est la contenu du ‘token’

On joint le cluster
curl -sfL https://get.k3s.io | K3S_URL=${k3s_url} K3S_TOKEN=${k3s_token} sh -

On obtient en retour :
[INFO] Finding release for channel stable
[INFO] Using v1.28.4+k3s2 as release
[INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.28.4+k3s2/sha256sum-amd64.txt
[INFO] Skipping binary downloaded, installed k3s matches hash
[INFO] Skipping installation of SELinux RPM
[INFO] Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/crictl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/ctr symlink to k3s, already exists
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s-agent.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s-agent.service
[INFO] systemd: Enabling k3s-agent unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service â /etc/systemd/system/k3s-agent.service.
[INFO] Host iptables-save/iptables-restore tools not found
[INFO] Host ip6tables-save/ip6tables-restore tools not found
[INFO] systemd: Starting k3s-agent

Vérification du cluster

kubectl get nodes -A -o wide

kubectl cluster-info

➔ A ce stade, le cluster est opérationnel


Il est alors possible d’y associer d’autres nœud ‘Worker’ et d’y déployer des applications

Kubernetes v240310 Jean GAUTIER 22


Bonus - Déploiement d’un cluster k3S avec Vagrant et Ansible
Il est possible de déployer un cluster k3s en se servant des applications ‘Vagrant’ et ‘Ansible’

Créer un fichier vagrant file ‘vagrantfile’


IMAGE = "debian/buster64"
RAM = 1024
CPU = 2
Nom-Master="master"
Nbr-Workers = 2
RESEAU = "192.168.100"

Vagrant.configure("2") do |config|
config.ssh.insert_key = true

config.vm.provider "virtualbox" do |v|


v.RAMory = RAM
v.cpus = CPU
end

config.vm.define Nom-Master do |master|


master.vm.box = IMAGE
master.vm.network "private_network", ip: "#{RESEAU}.100"
master.vm.hostname = Nom-Master
end

(1..Nbr-Workers).each do |i|
config.vm.define "worker-#{i}" do |worker|
worker.vm.box = IMAGE
worker.vm.network "private_network", ip: "#{RESEAU}.#{i + 10}"
worker.vm.hostname = "worker-#{i}"
end
end
end

Déploiements des machines


La commande suivante va déployer les machines en exploitant le fichier vagrant, créé précédemment
vagrant up

Création du playbook de configuration et du fichier d’inventaire pour Ansible


Le playbook va configurer la commande kubectl du Master, afin de permettre l’accès au cluster

cp -r inventory/sample inventory/vagrant-cluster
→on obtient le fichier ‘inventory/vagrant-cluster/hosts.ini’

➔ Il faut adapter la configuration aux machines du cluster

Kubernetes v240310 Jean GAUTIER 23


Le fichier inventaire ‘hosts.ini’
[master]
master ansible_host=localhost ansible_ssh_port=222 ansible_user=vagrant

[nodes]
worker-1 ansible_host=localhost ansible_ssh_port=221 ansible_user=vagrant
worker-2 ansible_host=localhost ansible_ssh_port=222 ansible_user=vagrant

[k3s_cluster:children]
master
nodes

Il faut ajuster les variables situées dans le fichier ‘all.yaml’, situé sous ‘group_vars’
k3s_version: v1.20.6+k3s1
ansible_user: vagrant
systemd_dir: /etc/systemd/system
master_ip: 10.0.0.10
extra_server_args: "--flannel-iface eth0"
extra_agent_args: "--flannel-iface eth0"

Création des paires de clés SSH et ajout les clés privées des machines
eval $(ssh-agent)
ssh-add .vagrant/machines/master/virtualbox/private_key
ssh-add .vagrant/machines/worker-1/virtualbox/private_key

Lancement du déploiement
ansible-playbook site.yml -i inventory/vagrant-cluster/hosts.ini

Kubernetes v240310 Jean GAUTIER 24


Interface d'administration du cluster Kubernetes
Portainer est un container applicatif, permettant la gestion et l’administration de containers Docker et de
clusters Kubernetes.
L’installation consiste à déployer un pod ‘portainer’ en exposant un port permettant d’accéder à
l’application via un navigateur WEB.

L’installation (community edition, pour la version gratuite) se fait simplement par le déploiement du fichier yaml

Récupération du fichier yaml


wget https://downloads.portainer.io/ce2-14/portainer.yaml

Déploiement du pod
kubectl apply -n portainer -f portainer.yaml

Les ports exposés par défaut, sont :


◦ TCP/30777 pour un accès en HTTP
◦ TCP/30779 pour un accès en HTTPS

Configuration initiale
On se connecte à l’interface WEB de portainer
L’interface initiale oblige à créer un utilisateur avec un mot de passe d’au moins 12 caractères.

Attention
Si on attend plus de 3 minutes avant de valider la configuration, une sécurité bloque l’accès au pod
Il faudra supprimer ce pod, un nouveau pod sera généré, sur lequel on pourra alors se connecter
Procédure :
• kubectl get pods -A ← Pour voir le nom du pod
• kubectl delete pod nom_du_pod -n portainer ← Pour supprimer le pod

Kubernetes v240310 Jean GAUTIER 25


Exploitation pratique d'un cluster minikube

Prise en main et premières commandes

Déploiement de l’application 'nginx' sur un cluster (en exposant un port TCP)

Il s’agit de créer un ‘déployment’ qui permet de mettre en place une application sur le
cluster et de la rendre accessible
• kubectl create deployment srv-1 --image nginx
→ Créer une instance nommée ‘srv-1’

• kubectl expose deployment srv-1 --name appli-1 --type NodePort --port=80


→ Établie une correspondance de port TCP

• kubectl get deployment srv-1


→ Vérifie le déploiement du serveur

• kubectl get services appli-1


→ Affiche l’état du service publié

• minikube service appli-1 --url

Exposer le service ‘hello-minikube’ dans le navigateur web

• minikube service hello-minikube


• kubectl port-forward service/appli-1 8080:80 --address x.x.x.x
→ Associe le port local 8080 au port 80 du service, sur l’adresse IP x.x.x.x de la machine

Boucle de Création / Suppression de ‘déployments’

• for i in {1..4}; do kubectl create deployment srv-$i --image nginx; done

• kubectl get deployments → Voir les déploiements effectués

• for i in {1..4}; do kubectl delete deployment srv-$i ; done

Kubernetes v240310 Jean GAUTIER 26


Pratique : Déploiement d’un environnement et mise en place d’une application
Un fichier ‘yaml’ va permettre de mettre en place :

✔ Un espace de noms dédié (Namespace), ce qui est une bonne pratique


✔ Un déploiement (Deployment) permettant de définir le nombre de répliquas afin de constituer le pod
✔ Un service (Service) qui permet aux pods de communiquer entre eux
✔ Un accès entrant (Ingress) permettant d’exposer le pod en y associant des règles de trafic

Etape 1 - Écriture du fichier ‘deploy.yml’, contenant :


---
apiVersion: v1
kind: Namespace
metadata:
name: k3s-test
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deploy
namespace: k3s-test
labels: Etape 2 - Déployer l’environnement
app: whoami
spec: kubectl apply -f deploy.yml
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami:v1.8.0
ports:
- name: whoami
containerPort: 80
--- Etape 3 - Contrôler le résultat
apiVersion: v1
kind: Service kubectl get namespaces
metadata:
name: whoami-svc
kubectl get pods --namespace k3s-test -o wide
namespace: k3s-test kubectl get deployments --namespace k3s-test -o wide
labels:
service: whoami kubectl get services --namespace k3s-test -o wide
spec: kubectl get ingress --namespace k3s-test -o wide
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
selector:
app: whoami
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
namespace: k3s-test
annotations: Etape 4 - se connecter sur l’application
traefik.ingress.kubernetes.io/router.entrypoints: web
spec: http://adresse_du_master/test
rules:
- http:
paths:
- path: /test
pathType: Prefix
backend:
service:
name: whoami-svc
port:
number: 80

Kubernetes v240310 Jean GAUTIER 27


Le modèle réseau de Kubernetes
Le modèle de réseau Kubernetes constitue la base permettant de comprendre comment les conteneurs, les
pods et les services communiquent.

• Chaque pod dispose de sa propre adresse IP


• Les Containers d’un même pod partagent l’adresse du pod
• Les différents pods peuvent communiquer ensemble directement (sans NAT)
• L’isolation est définie par l’utilisation de stratégies réseau (network policies)

➔ Les pods sont vues comme des machines à l’intérieur desquelles les Containers sont vus comme des
applications.

Bien que Kubernetes assure lui-même la prise en charge du réseau, il s’agit d’une gestion basique.
Il est préférable d’utiliser un composant tiers utilisant l’API ‘CNI’ (Container Network Interface).

Il existe un nombre important de type de plugin CNI, mais les deux principaux, sont :
• Le plugin Network qui permet de raccorder les pods au réseau
• Le plugin IPAM (IP Address Management), responsable de l’allocation des adresses IP

L’extension ‘Calico’ est un composant additionnel pour Kubernetes très répandu, qui fournit à la fois le
plugin réseau et le plugin IPAM.

Le service Kube proxy


Le service kube-proxy de Kubernetes permet l'accès à un groupe de pods en tant que service réseau,
représenté comme une adresse IP virtuelle unique.

Une application mise en ligne est représentée sous forme d’un service, le composant ‘kube-proxy’ équilibre
la charge de connexion sur l’ensemble des pods où se trouve l’application, en exposant une adresse IP
Virtuelle.

Les groupes de pods sont généralement définis à l'aide d'un sélecteur de libellé.

Kubernetes DNS
Chaque cluster Kubernetes fournit un service DNS afin de publier chaque pod et chaque service
Une liste de recherche DNS incluant l’espace de noms du pod et le domaine par défaut du cluster.

Kubernetes v240310 Jean GAUTIER 28


Le modèle original de fonctionnement de réseau Kubernetes spécifie que les pods doivent pouvoir
communiquer entre eux directement, mais pas que leur adresse IP soit routable en dehors du cluster.

Plusieurs normes ont été proposées pour régir la mise en réseau de conteneurs, notamment le modèle de
réseau de conteneurs (CNM) et l'interface de réseau de conteneurs (CNI).

Container Network Model


Container Network Model (CNM) est un standard proposé par Docker qui fournit des intégrations à divers
produits, notamment Calico, Cisco, Open Virtual Networking (OVN), VMware

Container Network Interface


Container Network Interface (CNI) est un standard proposé par CoreOS, créé comme une spécification
minimale qui fonctionne comme un simple contrat entre les plugins réseau et le runtime du conteneur.

CNI permet de configurer dynamiquement les ressources réseau et notamment, d’appliquer des stratégies
d’accès réseau, nommées ‘Network Policies’.

Une ‘Network’Policy’ permet de définir des règles de pare-feu pour les pods, agissant en entrée (ingress)
comme en sortie (egress).

Les stratégies réseau s’appuient sur les labels pour sélectionner les pods sur lesquels les règles vont
s’appliquer.
➔ C’est le plugin réseau CNI qui implémente ces stratégies.

Kubernetes ingress
Ingress s'appuie sur les services Kubernetes pour assurer l'équilibrage de charge au niveau de la couche
d'application, en mappant les requêtes HTTP et HTTPS avec des domaines ou des URL particuliers vers les
services Kubernetes.

Ingress permet d’exposer plusieurs sites HTTP/HTTPS via une seule et même adresse IP ou en les associant
à un nom de domaine distinct et de les exposer grâce à un service de type ‘reverse-proxy’.

Kubernetes egress
Contrairement au trafic entrant, il n'existe pas de ressource Kubernetes Egress établie par défaut

Kubernetes v240310 Jean GAUTIER 29


Il existe plusieurs moyens de rendre accessible un service d’un cluster pour l’extérieur

Le service ‘ClusterIP’
Le service ClusterIP est le service d’accès IP par défaut de Kunernetes.
Il permet aux pods d’un cluster d’accéder aux différents services, mais ne rend pas possible l’accès depuis
l’extérieur.

Exemple de service de type ‘ClusterIP’


apiVersion: v1
kind: Service
metadata:
name: my-internal-service
spec:
selector:
app: my-app
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP

Pour accéder à un service HTTP il est possible de démarrer et utiliser le service proxy propre à Kunernetes
• kubectl proxy --port=8080

Il devient alors possible de se connecter au service précédemment présenté par :


• http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/

➔ Comme cette méthode s’appuie sur kubectl pour authentifier une demande de connexion, elle ne doit
pas être utilisée en dehors d’un labo ou de procédures de test.

Le service ‘NodePort’
Le service ‘NodePort’ est le moyen le plus primitif d’acheminement du trafic externe sur un service cloud
interne.
• Ce service affecte un port spécifique par service, par node
• Les n° de ports sont automatiquement choisis dans la plage ‘30000 - 32767’

Exemple de service de type ‘NodePort’


apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP

Kubernetes v240310 Jean GAUTIER 30


Le service ‘LoadBalancer’
Un service de type ‘LoadBalancer’ est le moyen idéal bien que plus complexe, pour exposer un service sur
Internet.

Avec un service exposé par un ‘LoadBalancer’, il n’y a aucune restriction d’accès depuis l’extérieur, ce qui
permet de rendre accessible tout type de service.

➔ Il faut donc envisager d’utiliser des règles de contrôle de trafic

Le service ‘Ingress’
Un service Ingress offre de multiples possibilités de configuration pour permettre l’accès aux services depuis
l’extérieur.
Ce service s’appuie sur l’utilisation d’un ‘Ingress Controller’ qui est un service de type reverse-proxy

Il existe plusieurs ‘Ingress Controller’, avec pour chacun, plusieurs ‘plugins’, permettant de couvrir
différents besoins (certificats SSL, ….)

➔ Avec Ingrees, il est possible d’exposer de multiples services sous une seule et même adresse IP
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: other
servicePort: 8080
rules:
- host: foo.mydomain.com
http:
paths:
- backend:
serviceName: foo
servicePort: 8080
- host: mydomain.com
http:
paths:
- path: /bar/*
backend:
serviceName: bar
servicePort: 8080

Kubernetes v240310 Jean GAUTIER 31


L’objet ingress ‘reverse proxy’

Par défaut, lorsque l’on déploie une application, celle-ci n’est accessible depuis l’extérieur que si la
commande ‘kubectl port-forward’ est utilisée.

Les objets Ingress sont des ‘reverse-proxy’ utilisés pour faciliter l’accès à un service HTTP/HTTPS.

Un ‘reverse-proxy’ est un composant capable notamment de :


• Fournir l’accès à un programme depuis l’extérieur
• Répartir la charge sur plusieurs serveurs
• Prendre en charge la gestion de la sécurité

Un Ingress est un objet permettant de programmer le reverse proxy dans Kubernetes : il a besoin d’un
‘ingress controller’ installé sur le cluster agissant au niveau des protocoles HTTP/HTTPS (ports TCP
80/443)
L’ingress controller redirige les requêtes vers différents services (qui à leur tour redirigent vers différents
ports sur les pods), en fonction de l’URL.
➔ L’ingress controller Nginx est de loin le plus utilisé

Déclaration d’une règle Ingress


La déclaration d’un objet Ingress est assez similaire à celle d’un service :
• Un en-tête va indiquer l’API utilisée et le type d’objet
• Un champ metadata avec le nom de l’objet
• Un champ spec avec les caractéristiques de la règle Ingress

Exemple
Création d’un fichier ‘ingress.yaml’, contenant :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http
spec:
rules:
- host: "ns.labo" Permet de définir une règle qui fera suivre les requêtes visant
http: ‘ns.labo/site1’ vers les pods groupés sous le nom
paths:
- path: /site du service ‘http-servers’, sur le port 8080
pathType: Prefix
backend:
service:
name: http-servers
port:
number: 8080

Pour l’appliquer au contexte du cluster :


• kubectl apply -f ingress.yaml

Consultation des règles Ingress


• kubectl get ingress

Kubernetes v240310 Jean GAUTIER 32


Accès au point d’entrée du contrôleur Ingress

Pour rendre facilement un service HTTP/HTTPS accessible, on publie chaque application (site) sous forme
d’hôte virtuel (virtual host) que l’on associe à un nom DNS

Hôte virtuel par défaut


Un hôte virtuel est un mécanisme utilisé par les serveurs HTTP afin de mutualiser plusieurs sites sur un
même serveur.
Avec l’utilisation d’un reverse-proxy, ce dernier , détecte l’information du nom DNS du serveur visé par le
client, afin de faire suivre la requête à la bonne destination.

Le mécanisme ‘nip.io’
Dans une règle Ingress, le champ ‘host’ permet de spécifier le nom de l’hôte virtuel.
Le champ host associé à une règle Ingress doit forcément être une entrée DNS et non une adresse IP.

Avec de type de déclaration, il est possible de passer une adresse constituée de l’adresse IP suivie par le nom
de domaine ‘nip.io’.

Par exemple, dans le cas de l’adresse IP 192.168.100.250, ce domaine sera 192.168.100.250.nip.io

➔ Ce mécanisme s’applique à tous les sous-domaines

Création d’un hôte virtuel


Afin de faire pointer la règle Ingress sur l’entrée DNS, il est nécessaire de modifier le contenu du fichier
ingress.yaml.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http
spec:
rules:
- host: "srv-1.192.168.100.250.nip.io"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: http
port:
number: 8080

kubectl apply -f mailhog/

Kubernetes v240310 Jean GAUTIER 33


Les Network Policies
Par défaut les pods acceptent le trafic de n’importe quelle source.
Afin de les isoler, il faut mettre en place une ‘NetworkPolicy’ permettant de définir une sélection et un
filtrage.

Un pod auquel une ‘NetworkPolicy’ sera appliqué, rejettera toutes les connexions qui ne sont pas autorisées
par cette dernière.

Exemple pratique d’objet de stratégie réseau (NetworkPolicy)

Soit deux pods :


✔ Un serveur de base de données mysql, définit sous le label ‘role: bdb’
✔ Un serveur WEB nginx définit sous le label ‘role: http’

Création d’une stratégie (Network Policy) autorisant le trafic entrant sur le port TCP/3306 du pod ‘BDB’,
uniquement s’il provient du pod WEB

Création des pods (fichier deploy.yaml)


apiVersion: v1
kind: pod
metadata:
labels:
role: bdb
name: BDB
spec:
containers:
- image: mysql
name: mysql

kind: pod
metadata: Création de la règle (fichier policy.yaml)
labels: apiVersion: networking.k8s.io/v1
role: http kind: NetworkPolicy
name: WEB metadata:
spec: name: test-network-policy
containers: namespace: default Sélectionne, grâce au label, les Pods destinataires à protéger
- image: nginx spec:
name: nginx podSelector:
matchLabels:
kubectl create -f deploy.yaml role: bdb
Défini le type de règle (Ingress ou Egress)
policyTypes:
- Ingress
ingress:
- from: Sélectionne, grâce au label,
- podSelector: les Pods sources filtrés par la règle
matchLabels:
role: http Indique les ports filtrés par la règle
ports:
- protocol: TCP
port: 3306

Application de la règle
kubectl create -f policy.yaml

Kubernetes v240310 Jean GAUTIER 34


Principales commandes kubectl
Doc officielle, disponible ici

kubectl config view Affiche les paramètres de kubeconfig


kubectl config view -o jsonpath='{.users[?(@.name == "bob")].user.password}' Affiche le mot de passe pour ‘bob’
kubectl config view -o jsonpath='{.users[].name}' Affiche le premier utilisateur
kubectl config view -o jsonpath='{.users[*].name}' Affiche une liste d'utilisateurs
kubectl config get-contexts Affiche la liste des contextes
kubectl config current-context Affiche le contexte courant (current-context)
kubectl config use-context my-cluster Définit ‘my-cluster’ comme contexte courant

Ajoute un nouveau cluster prenant en charge l'authentification de base


kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword

Enregistre de manière permanente le namespace pour toutes les commandes kubectl


kubectl config set-context --current --namespace=ggckad-s2

Définir et utiliser un contexte avec utilisateur et namespace spécifiques


kubectl config set-context gce --user=cluster-admin --namespace=foo && kubectl config use-context gce

Supprime l'utilisateur foo


kubectl config unset users.foo

Création d'objets
✗ Les manifests Kubernetes peuvent être définis en YAML (.yml ou .yaml) ou JSON (.json)
✗ La commande ‘kubectl apply’ permet de créer et mettre à jour des ressources dans un cluster

kubectl apply -f ./my-manifest.yaml Crée une ou plusieurs ressources


kubectl apply -f ./my1.yaml -f ./my2.yaml Crée depuis plusieurs fichiers
kubectl apply -f ./dir Crée une ou plusieurs ressources depuis tous les manifests dans dir
kubectl apply -f https://git.io/vPieo Crée une ou plusieurs ressources depuis une url
kubectl create deployment nginx --image=nginx Démarre une instance unique de nginx
kubectl explain pods Affiche la documentation pour les manifests pod

Créer plusieurs objets depuis l'entrée standard (stdin)


cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: pod
metadata:
name: busybox-sleep
spec:
containers: Créer un Secret contenant plusieurs clés
- name: busybox
image: busybox cat <<EOF | kubectl apply -f -
args: apiVersion: v1
- sleep kind: Secret
- "1000000" metadata:
--- name: mysecret
apiVersion: v1 type: Opaque
kind: pod data:
metadata: password: $(echo -n "s33msi4" | base64 -w0)
name: busybox-sleep-less username: $(echo -n "jane" | base64 -w0)
spec: EOF
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000"
EOF

Kubernetes v240310 Jean GAUTIER 35


Visualisation et recherche de ressources
kubectl get services Liste tous les services d'un namespace
kubectl get pods --all-namespaces Liste tous les pods de tous les namespaces
kubectl get pods -o wide Liste tous les pods du namespace courant, avec plus de détails
kubectl get deployment my-dep Liste un déploiement particulier
kubectl get pods Liste tous les pods dans un namespace
kubectl get pod my-pod -o yaml Affiche le YAML du pod

La commande ‘describe’ avec un affichage verbeux


kubectl describe nodes my-node
kubectl describe pods my-pod

Liste les services triés par nom


kubectl get services --sort-by=.metadata.name

Liste les pods classés par nombre de redémarrage


kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

Affiche les volumes persistants classés par capacité de stockage


kubectl get pv --sort-by=.spec.capacity.storage

Affiche la version des labels de tous les pods ayant un label app=cassandra
kubectl get pods --selector=app=cassandra -o jsonpath='{.items[*].metadata.labels.version}'

Affiche tous les nœuds (en utilisant un sélecteur 'node-role.kubernetes.io/master')


kubectl get node --selector='!node-role.kubernetes.io/master'

Affiche tous les pods en cours d'exécution dans le namespace courant


kubectl get pods --field-selector=status.phase=Running

Affiche les IPs externes de tous les nœuds


kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

Affiche les labels pour tous les pods


kubectl get pods --show-labels

Vérifie quels nœuds sont prêts


JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"

Liste tous les Secrets actuellement utilisés par un pod


kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq

Liste les événements (Events) classés par timestamp


kubectl get events --sort-by=.metadata.creationTimestamp

Compare l'état actuel du cluster à l'état du cluster si le manifeste était appliqué


kubectl diff -f ./my-manifest.yaml

Kubernetes v240310 Jean GAUTIER 36


Mise à jour de ressources
Depuis la version 1.11, ‘rolling-update’ est déprécié et remplacé par ‘rollout’

kubectl set image deployment/frontend www=image:v2 Rolling update du conteneur ‘www’ du déploiement ‘frontend’
kubectl rollout history deployment/frontend Vérifie l'historique de déploiements incluant la révision
kubectl rollout undo deployment/frontend Rollback du déploiement précédent
kubectl rollout undo deployment/frontend --to-revision=2 Rollback à une version spécifique
kubectl rollout status -w deployment/frontend Écoute le status du rolling update du déploiement’frontend’
kubectl rollout restart deployment/frontend Rolling restart du déploiement ‘frontend’
cat pod.json | kubectl replace -f - Remplace un pod, en utilisant un JSON passé en entrée standard

Remplace de manière forcée, supprime puis re-crée la ressource


kubectl replace --force -f ./pod.json

Crée un service pour un nginx répliqué, qui rend le service sur le port 80 et se connecte aux conteneurs sur le port 8000
kubectl expose rc nginx --port=80 --target-port=8000

Modifie le ‘tag’ de l'image du conteneur unique du pod à v4


kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -

kubectl label pods my-pod new-label=awesome Ajoute un Label


kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq Ajoute une annotation
kubectl autoscale deployment foo --min=2 --max=10 Mise à l'échelle automatique du déploiement ‘foo’

Édition de ressources
Édite n'importe quelle ressource de l'API dans un éditeur

kubectl edit svc/docker-registry Édite le service nommé docker-registry


KUBE_EDITOR="nano" kubectl edit svc/docker-registry Utilise un autre éditeur

Mise à l'échelle de ressources


kubectl scale --replicas=3 rs/foo Scale du replicaset 'foo' à 3
kubectl scale --replicas=3 -f foo.yaml Scale une ressource spécifiée dans ‘foo.yaml’ à 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql Passe à 3, si la taille du déploiement ‘mysql’ est 2
kubectl scale --replicas=3 rc/foo rc/bar rc/baz Passe à 3 plusieurs contrôleurs de réplication

Suppression de ressources
kubectl delete -f ./pod.json Supprime un pod en utilisant ‘pod.json’
kubectl delete pod,service foo bar Supprime les pods et services ‘foo’ et ‘bar’
kubectl delete pods,services -l name=myLabel Supprime les pods et services ayant le label ‘myLabel’
kubectl -n my-ns delete pod,svc --all Supprime tous les pods et services du namespace ‘my-ns’

Kubernetes v240310 Jean GAUTIER 37


Interaction avec des pods en cours d'exécution
kubectl logs my-pod Affiche les logs du pod (stdout)
kubectl logs -l name=myLabel Affiche les logs des pods ayant le label name=myLabel (stdout)
kubectl logs my-pod --previous Affiche les logs du pod pour une instance précédente
kubectl logs my-pod -c my-container Affiche les logs d'un conteneur particulier
kubectl logs -l name=myLabel -c my-container Affiche les logs des pods avec le label ‘myLabel’
kubectl logs my-pod -c my-container --previous Affiche les logs d'un conteneur particulier
kubectl logs -f my-pod Fait défiler les logs du pod
kubectl logs -f my-pod -c my-container Fait défiler les logs d'un conteneur particulier du pod
kubectl logs -f -l name=myLabel --all-containers Fait défiler les logs de tous les pods ayant le label ‘myLabel’
kubectl run -i --tty busybox --image=busybox -- sh Exécute un pod comme un shell interactif
kubectl run nginx --image=nginx -nmynamespace Exécute le pod nginx dans un namespace spécifique
kubectl run nginx --image=nginx --dry-run -o yaml > pod.yml Simule l'exécution de ‘nginx’ et écrit avec sortie dans ‘pod.yml’

kubectl attach my-pod -i Attache à un conteneur en cours d'exécution


kubectl port-forward my-pod 5000:6000 Attache le port local 5000 au port 6000 de my-pod
kubectl exec my-pod -- ls / Exécute une commande dans un pod existant
kubectl exec my-pod -c my-container -- ls / Exécute une commande dans un pod existant
kubectl top pod POD_NAME --containers Affiche les métriques pour un pod donné et ses conteneurs

Interaction avec des Nœuds et Clusters


kubectl cordon my-node Marque my-node comme non assignable
kubectl drain my-node Draine my-node en préparation d'une mise en maintenance
kubectl uncordon my-node Marque my-node comme assignable
kubectl top node my-node Affiche les métriques pour un nœud donné
kubectl cluster-info Affiche les adresses du master et des services
kubectl cluster-info dump Affiche l'état courant du cluster sur stdout
kubectl cluster-info dump --output-directory=/path/to/cluster-state Affiche l'état courant du cluster sur /path/to/cluster-state

Types de ressources

kubectl api-resources Liste tous les types de ressources pris en charge avec leurs noms courts
kubectl api-resources --namespaced=true Toutes les ressources cantonnées à un namespace
kubectl api-resources --namespaced=false Toutes les ressources non cantonnées à un namespace
kubectl api-resources -o name Toutes les ressources avec un affichage simple
kubectl api-resources -o wide Toutes les ressources avec un affichage étendu
kubectl api-resources --verbs=list,get Toutes les ressources prenant en charge les verbes de requête ‘list’ et ‘get’
kubectl api-resources --api-group=extensions Toutes les ressources dans le groupe d'API ‘extensions’

Kubernetes v240310 Jean GAUTIER 38


Formatage de l'affichage
Pour afficher les détails dans un format spécifique, utilisez l'option ‘-o’(--output)

Format d'affichage Description


-o=custom-columns=<spec> Affiche un tableau en spécifiant une liste de colonnes séparées par des virgules
-o=custom-columns-file=<filename> Affiche un tableau en utilisant les colonnes spécifiées dans le fichier <filename>
-o=json Affiche un objet de l'API formaté en JSON
-o=jsonpath=<template> Affiche les champs définis par une expression jsonpath
-o=jsonpath-file=<filename> Affiche les champs définis par l'expression jsonpath
-o=name Affiche seulement le nom de la ressource et rien de plus
-o=wide Affiche dans le format texte avec toute information supplémentaire
-o=yaml Affiche un objet de l'API formaté en YAML

Exemples utilisant ‘-o=custom-columns’

Toutes les images s'exécutant dans un cluster


kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'

Toutes les images excepté "registry.k8s.io/coredns:1.6.2"


kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="registry.k8s.io/coredns:1.6.2")].image'

Tous les champs dans metadata quel que soit leur nom
kubectl get pods -A -o=custom-columns='DATA:metadata.*'

Verbosité de l'affichage de Kubectl et débogage


La verbosité de Kubectl est contrôlée par une des options ‘-v’ ou ‘--v’ suivie d'un entier représentant le niveau de log.

Kubernetes v240310 Jean GAUTIER 39

Vous aimerez peut-être aussi