Save tuto corrections

This commit is contained in:
nemunaire 2022-02-24 20:43:43 +01:00
commit 10448a6c8d
115 changed files with 1423 additions and 1289 deletions

View file

@ -1,22 +1,21 @@
\newpage
Découverte de `kubectl`
=======================
-----------------------
`kubectl`
([prononcé](https://www.reddit.com/r/kubernetes/comments/5qthoc/how_should_i_pronounce_kubectl/)
'cube C T L', 'cube cuttle', 'kyoob cuddle', 'cube control', ...) est le principal
'cube C T L', 'cube cuttle', 'kyoob cuddle', 'cube control', ...) est le principal
programme que l'on utilise pour interagir avec notre cluster.
Étant donné qu'il s'agit d'un programme client, qui ne fait rien de plus que
discuter avec une API REST HTTP, on peut le considérer comme un gros wrapper au
dessus de `curl`.
Obtenir de l'aide
-----------------
### Obtenir de l'aide
Commençons par apprivoiser `kubectl` en prenant quelques
renseignements et surtout en apprennant comment obtenir de l'aide :
renseignements et surtout en apprennant comment obtenir de l'aide :
<div lang="en-US">
```bash
@ -26,44 +25,43 @@ kubectl explain type
</div>
Les `type`s que vous pouvez découvrir sont ceux que l'on a vu à la
sections précédentes : `node`, `pod`, ...
sections précédentes : `node`, `pod`, ...
La commande `describe` permet d'afficher l'état tel qu'il est attendu
et tel qu'il est actuellement (cela permet de se rendre lorsque les
deux divergent).
`get`
-----
### `get`
Une autre manière, moins verbeuse, de récupérer des informations est
d'utiliser `get` :
d'utiliser `get` :
```bash
kubectl get node
```
On peut ajouter des options pour avoir plus d'infos :
On peut ajouter des options pour avoir plus d'infos :
```bash
kubectl get nodes -o wide
```
... ou rendre la sortie lisible par une machine :
... ou rendre la sortie lisible par une machine :
```bash
kubectl get no -o yaml
kubectl get no -o json
```
On aimera utiliser `jq(1)` avec la sortie `-o json` :
On aimera utiliser `jq(1)` avec la sortie `-o json` :
```bash
kubectl get no -o json | \
jq ".items[] | {name:.metadata.name} + .status.capacity"
```
### Services
#### Services
```bash
kubectl get services
@ -75,15 +73,15 @@ Pour le moment, nous n'avons qu'un seul service, il s'agit de l'API Kubernetes.
`ClusterIP` désigne l'IP d'un service accessible en interne, pour le cluster.
### Conteneurs actifs
#### Conteneurs actifs
Jetons un œil aux conteneurs actifs :
Jetons un œil aux conteneurs actifs :
```bash
kubectl get pods
```
Regardons maintenant les `namespaces` :
Regardons maintenant les `namespaces` :
```bash
kubectl get namespaces
@ -91,34 +89,33 @@ kubectl get namespaces
On l'a vu, les *namespaces* ici désignent des espaces de noms qui n'ont rien à
voir avec les *namespaces* de Linux. Regardons par exemple les conteneurs d'un
autre espace de noms :
autre espace de noms :
```bash
kubectl -n kube-system get pods
```
Eh oui ! De nombreux services de base pour Kubernetes tournent dans des
conteneurs, gérés par lui-même... notamment :
Eh oui ! De nombreux services de base pour Kubernetes tournent dans des
conteneurs, gérés par lui-même... notamment :
- `etcd` : notre base de données clef/valeur,
- `kube-apiserver` : l'API REST avec qui communique `kubectl`,
- `etcd` : notre base de données clef/valeur,
- `kube-apiserver` : l'API REST avec qui communique `kubectl`,
- `kube-controller-manager` et `kube-scheduler`, deux autres composants
indispensables,
- `coredns` : un composant additionnel pour gérer la résolution de noms internes
- `coredns` : un composant additionnel pour gérer la résolution de noms internes
(pour ne pas avoir à s'embêter avec les IP),
- `kube-proxy` : 1 par nœud, pour gérer l'ouverture des ports notamment,
- `kindnet`, `weave` : 1 par nœud, le plugin réseau.
- `kube-proxy` : 1 par nœud, pour gérer l'ouverture des ports notamment,
- `kindnet`, `weave` : 1 par nœud, le plugin réseau.
Mon premier conteneur
---------------------
### Mon premier conteneur
Prêt à lancer notre premier conteneur ?!
Prêt à lancer notre premier conteneur ?!
Pas si vite ! En fait ... Kubernetes ne permet pas de lancer de conteneur...
Pas si vite ! En fait ... Kubernetes ne permet pas de lancer de conteneur...
Nous devons lancer un *pod* (qui ne contiendra qu'un seul conteneur).
### Mon premier pod
#### Mon premier pod
```bash
kubectl run pingpong --image alpine ping 1.1.1.1
@ -127,7 +124,7 @@ kubectl run pingpong --image alpine ping 1.1.1.1
`kubectl` doit nous indiquer nous qu'un *pod* a été créé.
Si l'on affiche la liste des *pod*s, vous devriez avoir quelque chose qui
ressemble à cela :
ressemble à cela :
```
$ kubectl get pods
@ -135,18 +132,18 @@ NAME READY STATUS RESTARTS AGE
pingpong 1/1 Running 0 123s
```
#### Sortie d'un conteneur
##### Sortie d'un conteneur \
Allons maintenant regarder si nous recevons bien nos PONG.
Pour cela, nous allons utiliser la commande `kubectl logs`. Cette commande
s'utilise d'une manière similaire à `docker logs` :
s'utilise d'une manière similaire à `docker logs` :
```bash
kubectl logs pingpong
```
ou bien :
ou bien :
```bash
kubectl logs -f pingpong
@ -155,27 +152,27 @@ kubectl logs -f pingpong
Notez ici l'option -f qui permet de suivre les logs en direct.
Notre premier test ayant réussi, nous pouvons arrêter de DDos Cloudflare :
Notre premier test ayant réussi, nous pouvons arrêter de DDos Cloudflare :
```bash
kubectl delete pods pingpong
```
### Déploiement³
#### Déploiement³
Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
les choses sérieuses : en temps normal avec Kubernetes, nous ne déploierons pas
Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
les choses sérieuses : en temps normal avec Kubernetes, nous ne déploierons pas
de *pod* directement, car cela reviendrait à utiliser Docker. Nous allons
plutôt créer des tâches de déploiement.
Essayons sans plus attendre de lancer nos `ping` à travers une tâche de déploiement :
Essayons sans plus attendre de lancer nos `ping` à travers une tâche de déploiement :
```bash
kubectl create deployment pingpong --image=alpine -- ping 8.8.8.8
```
Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
```
NAME READY STATUS RESTARTS AGE
@ -191,12 +188,12 @@ NAME DESIRED CURRENT READY AGE
replicaset.apps/pingpong-98f6d5899 1 1 0 123s
```
Oula, on a vraiment lancé tout ça ?!
Oula, on a vraiment lancé tout ça ?!
Pas de panique, on peut très facilement le décortiquer :
Pas de panique, on peut très facilement le décortiquer :
Les tâches de déploiement (*deployment.apps*) sont des ressources de
haut niveau et sont là pour s'assurer que les migrations se font en douceur :
haut niveau et sont là pour s'assurer que les migrations se font en douceur :
elles vont permettre de basculer progressivement les *pod*s d'une version X à une
version Y (par exemple si l'on change notre ping d'alpine 3.14 vers alpine
edge), mais éventuellement de revenir sur la version X si besoin, en cours de
@ -207,14 +204,14 @@ s'assurer que le nombre de *pod*s actuellement lancé est bien en adéquation av
le nombre de *pod*s attendu.
\
Pour résumer : `kubectl` a créé une tâche de déploiement
Pour résumer : `kubectl` a créé une tâche de déploiement
`deploy/pingpong`. Cette tâche de déploiement a créé elle-même un *replicatset*
`rs/pingpong-xxxx`. Ce *replicatset* a créé un *pod* `po/pingpong-yyyy`.
### Passage à l'échelle : facile ?
#### Pasage à l'échelle : facile ?
Pour lancer 3 `ping`s en parallèle, modifions la tâche de déploiement comme suit :
Pour lancer 3 `ping`s en parallèle, modifions la tâche de déploiement comme suit :
```bash
kubectl scale deploy/pingpong --replicas 3
@ -227,7 +224,7 @@ de *pod*s en cours d'exécution, il va en lancer de nouveaux, afin de répondre
la demande.
\
Et que se passe-t-il alors, si l'on tue un *pod* ?
Et que se passe-t-il alors, si l'on tue un *pod* ?
```bash
kubectl delete pod pingpong-yyyy
@ -242,14 +239,14 @@ chacun des *pod*s un par un, car de nouveaux seraient créés par le
recréera un similaire (avec de nouveaux *pod*s).
Pour arrêter nos conteneurs, il convient donc de supprimer la tâche de
déploiement :
déploiement :
```bash
kubectl delete deploy pingpong
```
### Exposer son conteneur
#### Exposer son conteneur
Exposer un conteneur revient à créer un nouveau service (une ressource
*service*). Un service est une adresse IP que l'on peut considérer comme stable
@ -262,37 +259,37 @@ Une fois le *service* créé, le serveur DNS interne va permettre de résoudre l
nom du *pod* depuis les autres conteneurs.
#### Types de services
##### Types de services\
Il y a différents types de services :
Il y a différents types de services :
- `ClusterIP` (par défaut) : une adresse IP virtuelle est allouée pour le
- `ClusterIP` (par défaut) : une adresse IP virtuelle est allouée pour le
service, elle n'est accessible que depuis le réseau interne (par les *pod*s et
les nœuds). Il n'y a pas de translation de port à effectuer.
- `NodePort` : un port est alloué pour le service, sur tous les nœuds le
- `NodePort` : un port est alloué pour le service, sur tous les nœuds le
cluster et n'importe qui peut alors s'y connecter. Le port est choisi
aléatoirement.
- `LoadBalancer` : lorsque l'infrastructure sous-jacente fournit un
load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
- `LoadBalancer` : lorsque l'infrastructure sous-jacente fournit un
load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
créé pour utiliser ce load-balancer externe.
- `ExternalName` : une entrée DNS est créée pour avoir un alias.
- `ExternalName` : une entrée DNS est créée pour avoir un alias.
#### Le retour de `youp0m`
##### Le retour de `youp0m`\
Déployons maintenant l'image `youp0m` pour voir comment utiliser les *service*s :
Déployons maintenant l'image `youp0m` pour voir comment utiliser les *service*s :
```bash
kubectl create deployment youp0m --image=nemunaire/youp0m
```
Commençons par créer un service `ClusterIP` :
Commençons par créer un service `ClusterIP` :
```bash
kubectl expose deployment youp0m --port 8080
```
Ce qui donne :
Ce qui donne :
```
$ kubectl get service
@ -304,15 +301,14 @@ Depuis un nœud du cluster, on peut donc venir interroger cette IP. Si l'on
essaie avec plusieurs nœuds, on voit alors que les requêtes sont balancées sur
différents nœuds.
Si vous passez par `kind`, vous pouvez constater le bon fonctionnement grâce à :
Si vous passez par `kind`, vous pouvez constater le bon fonctionnement grâce à :
```bash
docker exec -it kind-control-plane curl 10.102.129.233:8080
```
Kubernetes dashboard
--------------------
### Kubernetes dashboard
L'équipe de Kubernetes propose un tableau de bord assez pratique, qui permet de
voir toutes les *resources*, comme nous l'avons fait avec `kubectl`, mais dans
@ -320,7 +316,7 @@ une interface web.
Ils mettent à disposition un fichier décrivant l'état d'un cluster ayant une
telle application. Nous pouvons demander à ce que notre cluster converge vers
la configuration nécessaire :
la configuration nécessaire :
```bash
kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
@ -329,13 +325,13 @@ kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
::::: {.warning}
Notez que le dashboard, avec cette configuration, va s'exécuter sans les
prérequis minimum de sécurité : pas de certificat TLS, ni
prérequis minimum de sécurité : pas de certificat TLS, ni
d'authentification. Ceci est juste pour jouer avec l'interface, en production,
on n'utilisera pas cette recette.
:::::
Regardons où nous pouvons contacter notre dashboard :
Regardons où nous pouvons contacter notre dashboard :
```bash
$ kubectl get svc
@ -344,7 +340,7 @@ dashboard NodePort 10.96.78.69 <none> 80:31505/TCP 3m10s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m51s
```
Regardons si cela répond :
Regardons si cela répond :
```bash
$ docker exec -it kind-control-plane curl 10.96.78.69:80
@ -362,7 +358,7 @@ configuration. Il va donc falloir indiquer à Kubernetes que l'on désire
utiliser un port spécifique pour exposer le tableau de bord.
Pour ce faire, éditons le fichier `insecure-dashboard.yaml`, pour ajouter, dans
la partie `Service` un *node port* plus spécifique :
la partie `Service` un *node port* plus spécifique :
```yaml
- port: 80
@ -371,8 +367,8 @@ la partie `Service` un *node port* plus spécifique :
nodePort: 30002
```
Maintenant, nous n'allons pas recréer un nouveau dashboard : nous allons
simplement « appliquer » la nouvelle configuration :
Maintenant, nous n'allons pas recréer un nouveau dashboard : nous allons
simplement « appliquer » la nouvelle configuration :
```bash
kubectl apply -f my-insecure-dashboard.yaml