2021 tuto
This commit is contained in:
parent
ba77aca73b
commit
c4bb727cd4
29 changed files with 422 additions and 257 deletions
|
|
@ -84,13 +84,13 @@ kubectl -n kube-system get pods
|
|||
```
|
||||
|
||||
Eh oui ! De nombreux services de base pour Kubernetes tournent dans des
|
||||
conteneurs, géré par lui-même... notamment :
|
||||
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`,
|
||||
- `kube-controller-manager` et `kube-scheduler`, deux autres composants
|
||||
indispensables,
|
||||
- `coredns` : un composant additionnel pour gérer la résolution de noms interne
|
||||
- `coredns` : un composant additionnel pour gérer la résolution de noms internes
|
||||
(pour 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.
|
||||
|
|
@ -110,87 +110,98 @@ Nous devons lancer un *pod* (qui ne contiendra qu'un seul conteneur).
|
|||
kubectl run pingpong --image alpine ping 1.1.1.1
|
||||
```
|
||||
|
||||
Outre un avertissement, `kubectl` doit indiquer nous qu'une tâche de
|
||||
déploiement a été créée.
|
||||
`kubectl` doit nous indiquer nous qu'un *pod* a été créée.
|
||||
|
||||
Si l'on affiche la liste des pods, vous devriez avoir quelque chose qui
|
||||
ressemble à cela :
|
||||
|
||||
```
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pingpong-7d49d9bc9-k8fpg 1/1 Running 0 123s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pingpong 1/1 Running 0 123s
|
||||
```
|
||||
|
||||
#### Déploiement³
|
||||
#### Sortie d'un conteneur
|
||||
|
||||
Si l'on affiche davantage d'informations, on obtient :
|
||||
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` :
|
||||
|
||||
```bash
|
||||
kubectl logs pingpong
|
||||
```
|
||||
|
||||
ou bien :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
kubectl delete deploy/pingpong
|
||||
```
|
||||
|
||||
|
||||
### 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
|
||||
de *pod* directement, car cela reviendrait à utiliser Docker, mais des tâches
|
||||
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 1.1.1.1
|
||||
```
|
||||
|
||||
Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
|
||||
|
||||
```
|
||||
$ kubectl get all
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/pingpong-7d49d9bc9-k8fpg 1/1 Running 0 123s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/pingpong-98f6d5899-5wsrm 0/1 ContainerCreating 0 123s
|
||||
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2m3s
|
||||
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 123h
|
||||
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
deployment.apps/pingpong 1/1 1 1 123s
|
||||
deployment.apps/pingpong 0/1 1 0 123s
|
||||
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
replicaset.apps/pingpong-7d49d9bc9 1 1 1 123s
|
||||
replicaset.apps/pingpong-98f6d5899 1 1 0 123s
|
||||
```
|
||||
|
||||
Pas de panique, on peut très facilement le décortiquer :
|
||||
|
||||
Les tâches de déploiements (*deployment.apps*) sont des ressources de
|
||||
haut-niveau et sont là pour 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 pods d'une version X à une
|
||||
version Y (par exemple si l'on change notre ping d'alpine vers debian), mais
|
||||
éventuellement de revenir sur la version X si besoin, en cours de migration.
|
||||
Elles délèguent aux *replicatsets* la gestion des pods.
|
||||
|
||||
Le *replicatset* est là pour indiquer le nombre de pods que l'on désire, et
|
||||
s'assure que le nombre de pods actuellement lancé est bien en adéquation avec
|
||||
le nombre de pods attendus.
|
||||
s'assurer que le nombre de pods actuellement lancé est bien en adéquation avec
|
||||
le nombre de pods attendu.
|
||||
|
||||
|
||||
Pour résumer : `kubectl run` 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`.
|
||||
|
||||
|
||||
#### Sortie d'un conteneur
|
||||
### Passage à l'échelle : facile ?
|
||||
|
||||
Bref ... 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` :
|
||||
Pour lancer 3 ping en parallèle, modifions la tâche de déploiement comme suit :
|
||||
|
||||
```bash
|
||||
kubectl logs deploy/pingpong
|
||||
```
|
||||
|
||||
Cette ligne est la plus simple, et nous affichera la sortie du premier pod de
|
||||
la tâche de déploiement.
|
||||
|
||||
Pour afficher un pod en particulier, il faut indiquer son nom en entier, en
|
||||
remplaçant `yyyy` par son identifiant :
|
||||
|
||||
```bash
|
||||
kubectl logs -f pingpong-yyyy
|
||||
```
|
||||
|
||||
Notez ici l'option -f qui permet de suivre les logs en direct.
|
||||
|
||||
|
||||
#### Mise à l'échelle : facile ?
|
||||
|
||||
Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
|
||||
les choses sérieuses.
|
||||
|
||||
Pour lancer 8 ping en parallèle, modifions la tâche de déploiement comme suit :
|
||||
|
||||
```bash
|
||||
kubectl scale deploy/pingpong --replicas 8
|
||||
kubectl scale deploy/pingpong --replicas 3
|
||||
```
|
||||
|
||||
À ce stade, comme nous ne modifions que le nombre de replicats, Kubernetes va
|
||||
|
|
@ -199,55 +210,18 @@ tout simplement propager ce nombre au *replicatset* existant. Puis, le
|
|||
de pods 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
|
||||
```
|
||||
|
||||
Cela supprime bien un *pod*, mais un autre est relancé instantannément car le
|
||||
*replicatset* constate une différence dans le nombre attendu.
|
||||
|
||||
#### Autres usages de `run`
|
||||
|
||||
Si l'on veut des tâche qui ne redémarrent pas systématiquement, on peut
|
||||
utiliser : `kubectl run --restart=OnFailure` ou `kubectl run --restart=Never`,
|
||||
... au lieu de créer des tâches de déploiement, cela va créer des *jobs* ou des
|
||||
*pods*. On peut même créer l'équivalent de tâches cron avec : `kubectl run
|
||||
--schedule=...`.
|
||||
|
||||
Comme nous venons de le voir, actuellement `kubectl run` sert un peu à tout et
|
||||
n'importe quoi, la ressource créée n'est pas évidente, c'est pour cela que
|
||||
l'avertissement nous recommande d'utiliser `kubectl create` :
|
||||
|
||||
- `kubectl create deployment` pour créer une tâche de déploiement,
|
||||
- `kubectl create job` pour créer un *job*.
|
||||
|
||||
Dans le futur, `kubectl run` servira à lancer un *pod* à usage unique, sans
|
||||
tâche de déploiement ni réplicat.
|
||||
|
||||
|
||||
En fait, `kubectl run` génère une nouvelle spécification, qu'il envoie à l'API
|
||||
de Kubernetes. On peut voir le fichier généré avec la ligne de commande
|
||||
suivante :
|
||||
|
||||
```bash
|
||||
kubectl run --dry-run -o yaml pingpong --image alpine ping 1.1.1.1
|
||||
```
|
||||
|
||||
Le fichier YAML récupéré peut s'utiliser comme suit :
|
||||
|
||||
```bash
|
||||
kubectl apply -f my-specs.yml
|
||||
```
|
||||
|
||||
|
||||
#### Arrêter de flooder 1.1.1.1
|
||||
|
||||
Ok, on s'est bien amusé à ping Cloudflare, pour ne pas être trop méchants, nous
|
||||
pouvons maintenant arrêter nos pods.
|
||||
|
||||
Comme nous l'avons vu juste avant, il ne s'agit pas de tuer chacun des pods un
|
||||
par un, car de nouveaux seraient créés par le *replicatset*. Si l'on supprime
|
||||
le *replicatset*, la tâche de déploiement en rećréera un similaire.
|
||||
Si nous voulons arrêter de DDoS Cloudflare, il ne s'agit pas de tuer chacun des
|
||||
pods un par un, car de nouveaux seraient créés par le *replicatset*. Si l'on
|
||||
supprime le *replicatset*, la tâche de déploiement en rećréera un similaire.
|
||||
|
||||
Pour arrêter nos conteneurs, il convient donc de supprimer la tâche de
|
||||
déploiement :
|
||||
|
|
@ -276,13 +250,13 @@ Il y a différents types de services :
|
|||
|
||||
- `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 pods et
|
||||
les nœuds). Il n'y a pas de translation de port a effectuer.
|
||||
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
|
||||
cluster, et n'importe qui peut alors s'y connecter. Le port est choisi
|
||||
aléatoirement.
|
||||
- `LoadBalancer` : lorsque l'infrastructure sous-jacente fourni un
|
||||
load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
|
||||
créé pour utiiser ce load-balancer externe.
|
||||
créé pour utiliser ce load-balancer externe.
|
||||
- `ExternalName` : une entrée DNS est créée pour avoir un alias.
|
||||
|
||||
|
||||
|
|
@ -309,3 +283,86 @@ youp0m ClusterIP 10.102.129.233 <none> 8080/TCP 42s
|
|||
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 à :
|
||||
|
||||
```bash
|
||||
docker exec -it kind-control-plane curl 10.96.179.154:8080
|
||||
```
|
||||
|
||||
|
||||
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
|
||||
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 :
|
||||
|
||||
```bash
|
||||
kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
|
||||
```
|
||||
|
||||
Notez que le dashboard, avec cette configuration, va s'exécuter sans les
|
||||
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 :
|
||||
|
||||
```bash
|
||||
$ kubectl get svc
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
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 :
|
||||
|
||||
```bash
|
||||
$ docker exec -it kind-control-plane curl 127.0.0.1:31505
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser.
|
||||
```
|
||||
|
||||
Pas très sympa... il faudrait que l'on puisse le voir dans un navigateur plus
|
||||
... moderne alors.
|
||||
|
||||
Étant donné que notre cluster ne se trouve pas directement sur notre machine,
|
||||
mais dans différents conteneurs Docker, nous ne pouvons pas accéder à
|
||||
`127.0.0.1`. Heureusement, au moment de la création de notre cluster, nous
|
||||
avons renseigné plusieurs ports redirigés au sein de notre 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 :
|
||||
|
||||
```yaml
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
nodePort: 30002
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
En voyant la divergence entre la réalité et la configuration demandée,
|
||||
Kubernetes va tout mettre en œuvre pour se conformer à nos directives. En
|
||||
l'occurrence, il s'agit de changer le port qui expose le service au sein du
|
||||
cluster.
|
||||
|
||||
En fait, on pourra faire exactement la même chose lors d'un changement de
|
||||
version. Kubernetes verra la différence et appliquera une politique de
|
||||
migration déterminée.
|
||||
|
||||
Une fois que c'est fait, nous pouvons fièrement utiliser notre navigateur pour
|
||||
aller sur <http://localhost:30002/> (vous pouvez *Skip* l'authentification,
|
||||
dans cette configuration d'exemple, elle n'est pas nécessaire).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue