Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
elearning:workbooks:kubernetes:k8s03 [2024/02/21 13:01] – admin | elearning:workbooks:kubernetes:k8s03 [2024/12/15 06:51] (Version actuelle) – admin | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ~~PDF: | ||
+ | |||
+ | Version - **2024.01** | ||
+ | |||
+ | Dernière mise-à-jour : ~~LASTMOD~~ | ||
+ | |||
+ | ======DOF304 - Travailler avec des Pods et des Conteneurs====== | ||
+ | |||
+ | =====Contenu du Module===== | ||
+ | |||
+ | * **DOF304 - Travailler avec des Pods et des Conteneurs** | ||
+ | * Contenu du Module | ||
+ | * LAB #1 - Application Configuration | ||
+ | * 1.1 - Présentation | ||
+ | * 1.2 - Création d'une ConfigMap | ||
+ | * 1.3 - Création d'un Secret | ||
+ | * 1.4 - Utilisation de ConfigMaps et de Secrets | ||
+ | * Utilisation de Variables d' | ||
+ | * Utilisation de Volumes de Configuration | ||
+ | * LAB #2 - Gestion des Ressources des Conteneurs | ||
+ | * 2.1 - Présentation | ||
+ | * 2.2 - Resource Requests | ||
+ | * 2.3 - Resource Limits | ||
+ | * LAB #3 - Supervision des Conteneurs | ||
+ | * 3.1 - Présentation | ||
+ | * 3.2 - Liveness Probes | ||
+ | * Le Probe exec | ||
+ | * Le Probe httpGet | ||
+ | * 3.3 - Startup Probes | ||
+ | * 3.4 - Readiness Probes | ||
+ | * LAB #4 - Gestion des Politiques de Redémarrage | ||
+ | * 4.1 - Présentation | ||
+ | * 4.2 - Always | ||
+ | * 4.3 - OnFailure | ||
+ | * 4.4 - Never | ||
+ | * LAB #5 - Création de Pods Multi-conteneurs | ||
+ | * 5.1 - Présentation | ||
+ | * 5.2 - Mise en Place | ||
+ | * LAB #6 - Conteneurs Init | ||
+ | * 6.1 - Présentation | ||
+ | * 6.2 - Mise en Place | ||
+ | * LAB #7 - Scheduling | ||
+ | * 7.1 - Présentation | ||
+ | * 7.2 - Mise en Place | ||
+ | * LAB #8 - DaemonSets | ||
+ | * 8.1 - Présentation | ||
+ | * 8.2 - Mise en Place | ||
+ | * LAB #9 - Pods Statiques | ||
+ | * 9.1 - Présentation | ||
+ | * 9.2 - Mise en Place | ||
+ | |||
+ | =====Ressources===== | ||
+ | |||
+ | ====Lab #1==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #2==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #3==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #4==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #5==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #6==== | ||
+ | |||
+ | * https:// | ||
+ | |||
+ | ====Lab #7==== | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | ====Lab #8==== | ||
+ | |||
+ | * https:// | ||
+ | |||
+ | ====Lab #9==== | ||
+ | |||
+ | * https:// | ||
+ | |||
+ | |||
+ | =====LAB #1 - Application Configuration===== | ||
+ | |||
+ | ====1.1 - Présentation==== | ||
+ | |||
+ | La gestion de la configuration d' | ||
+ | |||
+ | Il y a deux façons de stocker des informations dans K8s : | ||
+ | |||
+ | * ConfigMaps, | ||
+ | * Secrets. | ||
+ | |||
+ | Les données stockées dans des ConfigMaps et des Secrets peuvent être passées aux conteneurs en utilisant des : | ||
+ | |||
+ | * Variables d' | ||
+ | * Volumes de configuration. | ||
+ | |||
+ | ====1.2 - Création d'une ConfigMap==== | ||
+ | |||
+ | Pour commencer, créez le fichier **myconfigmap.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: ConfigMap | ||
+ | metadata: | ||
+ | name: my-configmap | ||
+ | data: | ||
+ | key1: Hello, world! | ||
+ | key2: | | ||
+ | Test | ||
+ | multiple lines | ||
+ | more lines | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que les données sont stockées dans des **Key-values**. La première donnée dans la section **data** est **key1: Hello, world!** tandis que la deuxième, **key2**, est en plusieurs lignes. | ||
+ | </ | ||
+ | |||
+ | Créez maintenant la ConfigMap : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | configmap/ | ||
+ | </ | ||
+ | |||
+ | Pour consulter le contenu de la ConfigMap, utilisez la commande **kubectl describe** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | Name: | ||
+ | Namespace: | ||
+ | Labels: | ||
+ | Annotations: | ||
+ | |||
+ | Data | ||
+ | ==== | ||
+ | key1: | ||
+ | ---- | ||
+ | Hello, world! | ||
+ | key2: | ||
+ | ---- | ||
+ | Test | ||
+ | multiple lines | ||
+ | more lines | ||
+ | |||
+ | |||
+ | BinaryData | ||
+ | ==== | ||
+ | |||
+ | Events: | ||
+ | </ | ||
+ | |||
+ | ====1.3 - Création d'un Secret==== | ||
+ | |||
+ | Créez maintenant le fichier **mysecret.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Secret | ||
+ | metadata: | ||
+ | name: my-secret | ||
+ | type: Opaque | ||
+ | data: | ||
+ | secretkey1: | ||
+ | secretkey2: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que les clefs secrets n'ont pas encore été définies. | ||
+ | </ | ||
+ | |||
+ | Cryptez maintenant les deux clefs en utilisant **base64** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | c2VjcmV0 | ||
+ | |||
+ | root@kubemaster: | ||
+ | YW5vdGhlcnNlY3JldA== | ||
+ | </ | ||
+ | |||
+ | Copiez et collez les chaînes base64 dans le fichier mysecret.yaml : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Secret | ||
+ | metadata: | ||
+ | name: my-secret | ||
+ | type: Opaque | ||
+ | data: | ||
+ | secretkey1: c2VjcmV0 | ||
+ | secretkey2: YW5vdGhlcnNlY3JldA== | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Remplacez les chaînes par celles que VOUS avez créé. | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le Secret : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | secret/ | ||
+ | </ | ||
+ | |||
+ | ====1.4 - Utilisation de ConfigMaps et de Secret==== | ||
+ | |||
+ | ===Utilisation des Variables d' | ||
+ | |||
+ | Créez le fichier **envpod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: envpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | env: | ||
+ | - name: CONFIGMAPVAR | ||
+ | valueFrom: | ||
+ | configMapKeyRef: | ||
+ | name: my-configmap | ||
+ | key: key1 | ||
+ | - name: SECRETVAR | ||
+ | valueFrom: | ||
+ | secretKeyRef: | ||
+ | name: my-secret | ||
+ | key: secretkey1 | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la variable **$CONFIGMAPVAR** contiendra la valeur de **key1** de la **ConfigMap** et que la variable **$SECRETVAR** contindra la valeur de **secretkey1** du **Secret**. | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/envpod created | ||
+ | </ | ||
+ | |||
+ | Consultez maintenant les logs du pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | configmap: Hello, world! secret: secret | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le conteneur dans le pod voit bien les valeurs des deux variables. | ||
+ | </ | ||
+ | |||
+ | ===Utilisation des Volumes de Configuration=== | ||
+ | |||
+ | Créez le fichier **volumepod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: volumepod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | volumeMounts: | ||
+ | - name: configmap-volume | ||
+ | mountPath: / | ||
+ | - name: secret-volume | ||
+ | mountPath: / | ||
+ | volumes: | ||
+ | - name: configmap-volume | ||
+ | configMap: | ||
+ | name: my-configmap | ||
+ | - name: secret-volume | ||
+ | secret: | ||
+ | secretName: my-secret | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Utilisez maintenant la commande **kubectl exec** pour consulter les config data files dans le conteneur : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | key1 | ||
+ | key2 | ||
+ | |||
+ | root@kubemaster: | ||
+ | Hello, world!root@kubemaster: | ||
+ | |||
+ | root@kubemaster: | ||
+ | Test | ||
+ | multiple lines | ||
+ | more lines | ||
+ | |||
+ | root@kubemaster: | ||
+ | secretkey1 | ||
+ | secretkey2 | ||
+ | |||
+ | root@kubemaster: | ||
+ | secretroot@kubemaster: | ||
+ | |||
+ | root@kubemaster: | ||
+ | anothersecretroot@kubemaster: | ||
+ | |||
+ | root@kubemaster: | ||
+ | </ | ||
+ | |||
+ | Dernièrement, | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | pod " | ||
+ | </ | ||
+ | |||
+ | =====LAB #2 - Gestion des Ressources des Conteneurs===== | ||
+ | |||
+ | ====2.1 - Présentation==== | ||
+ | |||
+ | Deux aspects importants de la gestion des ressources des conteneurs sont : | ||
+ | |||
+ | * **Resource Requests**, | ||
+ | * Une Resource Request permet de définir des ressources telles le CPU et la mémoire au moment du **scheduling**. Autrement dit, si la Resource Request est de 5Go, le scheduleur des pods cherchera une noeud ayant 5 Go de RAM disponible. Une Resource Request n'est pas une limite car le pod peut utiliser plus ou moins de mémoire. | ||
+ | * **Resource Limits**, | ||
+ | * Une Resource Limit permet de définir des limites des ressources telles le CPU et la mémoire. Différents Container Runtimes réagissent de manières différentes devant une Resource Limit. Par exemple, certains vont arrêter le processus du conteneur en cas de dépassement de la limite. Dans le cas de Docker, si la limite du CPU est dépassé, Docker va limiter l' | ||
+ | |||
+ | Pour les deux types, les demandes et les limites de la mémoire sont généralement exprimées en **Mi**, tandis que les les demandes et les limites du CPU sont exprimées en 1/1000 d'un processeur. Par exemple le chiffre 250m représente 250/1000 d'un CPU ou 1/4. | ||
+ | |||
+ | ====2.2 - Resource Requests==== | ||
+ | |||
+ | Créez le fichier **bigrequestpod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: bigrequestpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | resources: | ||
+ | requests: | ||
+ | cpu: " | ||
+ | memory: " | ||
+ | </ | ||
+ | |||
+ | Créez le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez maintenant le statut du pod créé : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | bigrequestpod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le statut du pod est en **pending**. Le pod restera en pending car ni **kubenode1**, | ||
+ | </ | ||
+ | |||
+ | ====2.3 - Resource Limits==== | ||
+ | |||
+ | Créez le fichier **resourcepod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: resourcepod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | resources: | ||
+ | requests: | ||
+ | cpu: " | ||
+ | memory: " | ||
+ | limits: | ||
+ | cpu: " | ||
+ | memory: " | ||
+ | </ | ||
+ | |||
+ | Créez le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez le statut des pods : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | bigrequestpod | ||
+ | my-deployment-67b5d4bf57-6wcrq | ||
+ | myapp-deployment-689f9d59-c25f9 | ||
+ | myapp-deployment-689f9d59-nn9sw | ||
+ | myapp-deployment-689f9d59-rnc4r | ||
+ | resourcepod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le statut du pod **bigrequestpod** est **toujours** en **pending**. | ||
+ | </ | ||
+ | |||
+ | =====LAB #3 - Supervision des Conteneurs===== | ||
+ | |||
+ | ====3.1 - Présentation=== | ||
+ | |||
+ | La supervision des conteneurs concerne la surveillance de la santé des conteneurs afin d' | ||
+ | |||
+ | Il existe plusieurs types de sondes : | ||
+ | |||
+ | * **Liveness Probes**, | ||
+ | * Par défaut K8s considère un conteneur HS uniquement quand le conteneur en question s' | ||
+ | * Liveness probes permettent une configuration plus sophistiquée de ce mécanisme. | ||
+ | * **Startup Probes**, | ||
+ | * Similaires aux Liveness Probes, les Startup Probes n' | ||
+ | * **Readiness Probes**, | ||
+ | * Similaires aux Startup Probes car ils n' | ||
+ | |||
+ | ====3.2 - Liveness Probes==== | ||
+ | |||
+ | ===Le Probe exec=== | ||
+ | |||
+ | Créez le fichier **livenesspod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: livenesspod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | livenessProbe: | ||
+ | exec: | ||
+ | command: [" | ||
+ | initialDelaySeconds: | ||
+ | periodSeconds: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Dans le fichier ci-dessus, si la commande **echo " | ||
+ | </ | ||
+ | |||
+ | Créez le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez le statut du pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | livenesspod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod est en bonne santé et à un statut de **running**. | ||
+ | </ | ||
+ | |||
+ | ===Le Probe httpGet=== | ||
+ | |||
+ | Créez le fichier **livenesspodhttp.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: livenesspodhttp | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | livenessProbe: | ||
+ | httpGet: | ||
+ | path: / | ||
+ | port: 80 | ||
+ | initialDelaySeconds: | ||
+ | periodSeconds: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Dans le fichier ci-dessus, si la commande **GET /** s' | ||
+ | </ | ||
+ | |||
+ | Créez le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez le statut du pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | livenesspodhttp | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod est en bonne santé et à un statut de **running**. | ||
+ | </ | ||
+ | |||
+ | ====3.3 - Startup Probes==== | ||
+ | |||
+ | Créez le fichier **startuppod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: startuppod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | startupProbe: | ||
+ | httpGet: | ||
+ | path: / | ||
+ | port: 80 | ||
+ | failureThreshold: | ||
+ | periodSeconds: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Dans le fichier ci-dessus, le Startup Probe va attendre un maximum de 30 secondes pour que l' | ||
+ | </ | ||
+ | |||
+ | Créez le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez le statut du pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | livenesspod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod est en bonne santé et à un statut de **running**. | ||
+ | </ | ||
+ | |||
+ | ====3.4 - Readiness Probes==== | ||
+ | |||
+ | Créez le fichier **readinesspod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: readinesspod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | readinessProbe: | ||
+ | httpGet: | ||
+ | path: / | ||
+ | port: 80 | ||
+ | initialDelaySeconds: | ||
+ | periodSeconds: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Dans le fichier ci-dessus, si la commande **GET /** s' | ||
+ | </ | ||
+ | |||
+ | Créez le pod et consultez son statut : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | NAME | ||
+ | readinesspod | ||
+ | NAME | ||
+ | readinesspod | ||
+ | NAME | ||
+ | readinesspod | ||
+ | NAME | ||
+ | readinesspod | ||
+ | NAME | ||
+ | readinesspod | ||
+ | NAME | ||
+ | readinesspod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod est a un statut de Running 4 secondes après son démarrage. Par contre, le pod ne passe qu'en READY au bout de 13 secondes quand le Readiness Probe a réussi. | ||
+ | </ | ||
+ | |||
+ | =====LAB #4 - Gestion des Politiques de Redémarrage===== | ||
+ | |||
+ | ====4.1 - Présentation==== | ||
+ | |||
+ | K8s peut redémarrer des conteneurs en cas de problèmes. Il y a trois politiques de redémarrage : | ||
+ | |||
+ | * **Always**, | ||
+ | * Always est la politique par défaut, | ||
+ | * Always redémarre **toujours** un conteneur quelque soit le code retour quand le conteneur est arrêté. | ||
+ | * **OnFailure**, | ||
+ | * OnFailure ne redémarre un conteneur que dans ls cas où celui-ci sort avec un code retour autre que 0 ou dans le cas où un Liveness Probe a rapporté la mauvaise santé du conteneur. Dans le cas contraire, où le conteneur a terminé sa tâche et sort avec un code retour de 0, la politique ne le redémarre pas. | ||
+ | * **Never**, | ||
+ | * Never est l' | ||
+ | |||
+ | ====4.2 - Always==== | ||
+ | |||
+ | Créez le fichier **alwayspod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: alwayspod | ||
+ | spec: | ||
+ | restartPolicy: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | Créez le pod et consultez son statut : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | NAME READY | ||
+ | alwayspod | ||
+ | NAME READY | ||
+ | alwayspod | ||
+ | NAME READY | ||
+ | alwayspod | ||
+ | NAME READY | ||
+ | alwayspod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod a été redémarré. | ||
+ | </ | ||
+ | |||
+ | ====4.3 - OnFailure==== | ||
+ | |||
+ | Créez le fichier **onfailure.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: onfailure | ||
+ | spec: | ||
+ | restartPolicy: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | Créez le pod et consultez son statut : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod n'a pas été redémarré. | ||
+ | </ | ||
+ | |||
+ | Supprimez maintenant le pod onfailure : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | </ | ||
+ | |||
+ | Modifiez ensuite le fichier **onfailure.yaml** en ajoutant la chaîne **this is a bad command** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: onfailure | ||
+ | spec: | ||
+ | restartPolicy: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | Créez le pod et consultez son statut : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | NAME READY | ||
+ | onfailure | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod a été redémarré à cause de l' | ||
+ | </ | ||
+ | |||
+ | ====4.4 - Never==== | ||
+ | |||
+ | Créez le fichier **never.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: never | ||
+ | spec: | ||
+ | restartPolicy: | ||
+ | containers: | ||
+ | - name: busybox | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | Créez le pod et consultez son statut : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/never created | ||
+ | NAME READY | ||
+ | never | ||
+ | NAME READY | ||
+ | never | ||
+ | NAME READY | ||
+ | never | ||
+ | NAME READY | ||
+ | never | ||
+ | NAME READY | ||
+ | never | ||
+ | NAME READY | ||
+ | never | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod n'a pas été redémarré. | ||
+ | </ | ||
+ | |||
+ | =====LAB #5 - Création de Pods Multi-conteneurs===== | ||
+ | |||
+ | ====5.1 - Présentation==== | ||
+ | |||
+ | Il est toujours préférable de ne mettre qu'un seul conteneur dans un pod. L' | ||
+ | |||
+ | Cette interaction prend la forme de partager : | ||
+ | |||
+ | * le même espace réseau, | ||
+ | * les conteneurs peuvent se communiquer sur tous les ports, même si les ports ne sont pas exposés au cluster, | ||
+ | * le même espace de stockage, | ||
+ | * les conteneurs peuvent partager les mêmes volumes. | ||
+ | | ||
+ | ====5.2 - Mise en Place==== | ||
+ | |||
+ | Commencez par créer le fichier **multicontainerpod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: multicontainerpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx | ||
+ | - name: redis | ||
+ | image: redis | ||
+ | - name: couchbase | ||
+ | image: couchbase | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le fichier créera trois conteneurs - **nginx**, **redis** et **couchbase**. | ||
+ | </ | ||
+ | |||
+ | Créez ensuite le pod : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | multicontainerpod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez qu'il y a actuellement 0 de 3 pods dans un état de READY. | ||
+ | </ | ||
+ | |||
+ | Attendez quelques minutes et constatez de nouveau l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | multicontainerpod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez qu'il y a actuellement 3 de 3 pods dans un état de READY. | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **helper.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: helperpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: busybox1 | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | volumeMounts: | ||
+ | - name: sharedvol | ||
+ | mountPath: /output | ||
+ | - name: helper | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | volumeMounts: | ||
+ | - name: sharedvol | ||
+ | mountPath: /input | ||
+ | volumes: | ||
+ | - name: sharedvol | ||
+ | emptyDir: {} | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que ce fichier créera un pod contenant deux conteneurs - **busybox1** et **helper**. Chaque conteneur partage un volume identique qui s' | ||
+ | </ | ||
+ | |||
+ | Créez le pod **helper** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Consultez les logs du conteneur **helper** dans le pod **helperpod** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | logs data | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le conteneur **busybox1** a écrit la chaîne **logs data** dans le fichier **/ | ||
+ | </ | ||
+ | |||
+ | =====LAB #6 - Conteneurs Init==== | ||
+ | |||
+ | ====6.1 - Présentation==== | ||
+ | |||
+ | Un Conteneur Init est un conteneur qui ne s' | ||
+ | |||
+ | * isoler, d'une manière sécurisée, | ||
+ | * injecter des données dans un volume partagé, | ||
+ | * faire patienter un pod en attendant que d' | ||
+ | |||
+ | ====6.2 - Mise en Place==== | ||
+ | |||
+ | Commencez par créer le fichier **initpod.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: initpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | initContainers: | ||
+ | - name: delay | ||
+ | image: busybox | ||
+ | command: [' | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le conteneur **delay** va faire patienter la création du conteneur **nginx** pendant 30 secondes. | ||
+ | </ | ||
+ | |||
+ | Créez le pod **initpod** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/initpod created | ||
+ | </ | ||
+ | |||
+ | Consultez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | initpod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le **STATUS** du pod est **Init: | ||
+ | </ | ||
+ | |||
+ | Patientez au moins 30 secondes puis exécutez la dernière commande de nouveau : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | initpod | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le **STATUS** du pod est **Running**. | ||
+ | </ | ||
+ | |||
+ | =====LAB #7 - Scheduling===== | ||
+ | |||
+ | ====7.1 - Présentation==== | ||
+ | |||
+ | **Scheduling** est le processus d' | ||
+ | |||
+ | Le Scheduler prend sa décision en fonction d'un un contrôle : | ||
+ | |||
+ | * des ressources disponibles sur les neouds en fonction des **Resource Resquests**, | ||
+ | * des configurations des **nodeSelectors** qui utilisent des **Node Labels**, | ||
+ | * des instructions de type **nodeName** qui forcent le choix d'un noeud par rapport à un autre. | ||
+ | |||
+ | ====7.2 - Mise en Place==== | ||
+ | |||
+ | Commencez par visualiser les noeuds du cluster : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME STATUS | ||
+ | kubemaster.ittraining.loc | ||
+ | kubenode1.ittraining.loc | ||
+ | kubenode2.ittraining.loc | ||
+ | </ | ||
+ | |||
+ | ===nodeSelector==== | ||
+ | |||
+ | Attribuez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | node/ | ||
+ | </ | ||
+ | |||
+ | Créez maintenant le fichier **nodeselector.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: nodeselector | ||
+ | spec: | ||
+ | nodeSelector: | ||
+ | mylabel: " | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez l' | ||
+ | </ | ||
+ | |||
+ | Créez le pod **nodeselector** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Constatez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | nodeselector | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod nodeselector a été schedulé sur le noeud **kubenode1**. | ||
+ | </ | ||
+ | |||
+ | ===nodeName=== | ||
+ | |||
+ | Créez maintenant le fichier **nodename.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: nodename | ||
+ | spec: | ||
+ | nodeName: kubenode2.ittraining.loc | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod va être schedulé sur **kubenode2.ittraining.loc** grâce à l' | ||
+ | </ | ||
+ | |||
+ | Créez le pod **nodename** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod/ | ||
+ | </ | ||
+ | |||
+ | Constatez l' | ||
+ | |||
+ | < | ||
+ | pod/ | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | nodename | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod a été schedulé sur **kubenode2.ittraining.loc** grâce à l' | ||
+ | </ | ||
+ | |||
+ | =====LAB #8 - DaemonSets===== | ||
+ | |||
+ | ====8.1 - Présentation==== | ||
+ | |||
+ | Un DaemonSet : | ||
+ | |||
+ | * crée une copie d'un pod sur tous les noeuds disponibles, | ||
+ | * crée une copie d'un pod sur tout nouveau noeud ajouté au cluster, | ||
+ | * respecte les contraintes de Node Labels. | ||
+ | |||
+ | ====8.2 - Mise en Place==== | ||
+ | |||
+ | Commencez par nettoyer le cluster : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | pod " | ||
+ | |||
+ | root@kubemaster: | ||
+ | deployment.apps " | ||
+ | deployment.apps " | ||
+ | </ | ||
+ | |||
+ | Créez ensuite le fichier **daemonset.yaml** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | root@kubemaster: | ||
+ | apiVersion: apps/v1 | ||
+ | kind: DaemonSet | ||
+ | metadata: | ||
+ | name: mydaemonset | ||
+ | spec: | ||
+ | selector: | ||
+ | matchLabels: | ||
+ | app: mydaemonset | ||
+ | template: | ||
+ | metadata: | ||
+ | labels: | ||
+ | app: mydaemonset | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | </ | ||
+ | |||
+ | Créez le DaemonSet **mydaemonset** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | daemonset.apps/ | ||
+ | </ | ||
+ | |||
+ | Constatez le statut du **DaemonSet** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME DESIRED | ||
+ | mydaemonset | ||
+ | </ | ||
+ | |||
+ | Constatez maintenant qu'il a un pod sur chaque noeud : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME READY | ||
+ | mydaemonset-hmdhp | ||
+ | mydaemonset-kmf4z | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez qu'il n'y ait pas de pod sur **kubemaster**. En effet, le kubemaster a le drapeau **no taint** fixé qui empêche la création de pods sur lui. | ||
+ | </ | ||
+ | |||
+ | =====LAB #9 - Pods Statiques===== | ||
+ | |||
+ | ====9.1 - Présentation==== | ||
+ | |||
+ | Un Static Pod (//Pod Statique//) est : | ||
+ | |||
+ | * un pod qui est contrôlé par le **kubelet** sur le noeud concerné au lieu d' | ||
+ | * ce type de pod peut être créé même s'il n y'ait pas de Control Plane, | ||
+ | * si le Control Plane existe, un **Mirror Pod** (//Pod Miroir//) est créé dans le Control Plane pour représenter le pod statique afin de faciliter la consultation son statut. Par contre, le pod ne peut ni être changé, ni être géré à partir du Control Plane, | ||
+ | * un pod créé en utilisant un fichier yaml situé dans un chemin **spécifique** sur le noeud concerné, | ||
+ | * pour un cluster installé avec **kubeadm**, | ||
+ | |||
+ | ====9.2 - Mise en Place==== | ||
+ | |||
+ | Connectez-vous à kubenode1 et devenez l' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | trainee@192.168.56.3' | ||
+ | Linux kubenode1.ittraining.loc 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64 | ||
+ | |||
+ | The programs included with the Debian GNU/Linux system are free software; | ||
+ | the exact distribution terms for each program are described in the | ||
+ | individual files in / | ||
+ | |||
+ | Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent | ||
+ | permitted by applicable law. | ||
+ | Last login: Sun Sep 4 13:01:18 2022 from 192.168.56.2 | ||
+ | trainee@kubenode1: | ||
+ | Mot de passe : fenestros | ||
+ | root@kubenode1: | ||
+ | </ | ||
+ | |||
+ | Créez le fichier **/ | ||
+ | |||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Créez le pod **mystaticpod** : | ||
+ | |||
+ | < | ||
+ | root@kubenode1: | ||
+ | root@kubenode1: | ||
+ | apiVersion: v1 | ||
+ | kind: Pod | ||
+ | metadata: | ||
+ | name: mystaticpod | ||
+ | spec: | ||
+ | containers: | ||
+ | - name: nginx | ||
+ | image: nginx: | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que kubelet va voir que le fichier a été créé et ensuite pouruivra avec la création du pod. | ||
+ | </ | ||
+ | |||
+ | Re-démarrez le service **kubelet** pour démarrer le pod statique **immédiatement** sans attendre : | ||
+ | |||
+ | < | ||
+ | root@kubenode1: | ||
+ | </ | ||
+ | |||
+ | Retournez au **kubemaster** et constatez la présence d'un pod miroir : | ||
+ | |||
+ | < | ||
+ | root@kubenode1: | ||
+ | déconnexion | ||
+ | trainee@kubenode1: | ||
+ | déconnexion | ||
+ | Connection to 192.168.56.3 closed. | ||
+ | |||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | mydaemonset-hmdhp | ||
+ | mydaemonset-kmf4z | ||
+ | mystaticpod-kubenode1.ittraining.loc | ||
+ | </ | ||
+ | |||
+ | Supprimez maintenant le pod statique : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | pod " | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que la suppression semble avoir réussi. | ||
+ | </ | ||
+ | |||
+ | Constatez les pods en cours d' | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | NAME | ||
+ | mydaemonset-hmdhp | ||
+ | mydaemonset-kmf4z | ||
+ | mystaticpod-kubenode1.ittraining.loc | ||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | **Important** : Notez que le pod **mystaticpod-kubenode1.ittraining.loc** est revenu. En effet, la suppression précédente n'a supprimé que le miroir qui a ensuite ête regénéré. | ||
+ | </ | ||
+ | |||
+ | Pour supprimer le pod statique, connectez-vous à **kubenode1** : | ||
+ | |||
+ | < | ||
+ | root@kubemaster: | ||
+ | trainee@kubenode1' | ||
+ | Linux kubenode1.ittraining.loc 4.9.0-19-amd64 #1 SMP Debian 4.9.320-2 (2022-06-30) x86_64 | ||
+ | |||
+ | The programs included with the Debian GNU/Linux system are free software; | ||
+ | the exact distribution terms for each program are described in the | ||
+ | individual files in / | ||
+ | |||
+ | Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent | ||
+ | permitted by applicable law. | ||
+ | Last login: Thu Sep 15 17:51:03 2022 from 192.168.56.2 | ||
+ | |||
+ | trainee@kubenode1: | ||
+ | Mot de passe : fenestros | ||
+ | |||
+ | root@kubenode1: | ||
+ | |||
+ | root@kubenode1: | ||
+ | |||
+ | root@kubenode1: | ||
+ | déconnexion | ||
+ | |||
+ | trainee@kubenode1: | ||
+ | déconnexion | ||
+ | Connection to kubenode1 closed. | ||
+ | |||
+ | root@kubemaster: | ||
+ | </ | ||
+ | |||
+ | ----- | ||
+ | |||
+ | Copyright © 2024 Hugh Norris | ||