# Kubernetes | Créez des pods et des deployments à l'aide de kubernetes

> [LinkedIn](https://www.linkedin.com/in/carlinfongang/) | [GitLab](https://gitlab.com/carlinfongang) | [GitHub](https://github.com/carlinfongang) | [Credly](https://www.credly.com/users/carlin-fongang/badges)

---

## Contexte

Dans ce laboratoire, nous allons explorer les étapes clés pour déployer et gérer des applications en utilisant Kubernetes et **nginx**.

## Objectifs

Dans ce lab, nous procèderons à :

1. **Rédaction du manifeste pod.yml** : Créez un fichier `pod.yml` pour déployer un pod utilisant l'image `mmumshad/simple-webapp-color`, en spécifiant que la couleur de l'application sera rouge.
    
2. **Lancement et vérification du pod** : Déployez le pod et assurez-vous qu'il est correctement en cours d'exécution dans votre cluster Kubernetes.
    
3. **Exposition du pod** : Exposez le pod en utilisant la commande `kubectl port-forward nom_du_pod 8080:8080 --address 0.0.0.0` pour rendre l'application accessible via le port 8080.
    
4. **Accès à l'application** : Confirmez que l'application est accessible en naviguant sur le port 8080 du nœud.
    
5. **Déploiement de Nginx** : Écrivez un manifeste `nginx-deployment.yml` pour déployer deux réplicas d'un pod Nginx, utilisant la version `1.18.0` de l'image.
    
6. **Vérification du déploiement** : Lancez le déploiement, vérifiez le nom des pods et confirmez que le déploiement, le ReplicaSet et la version de l'image ont été correctement créés.
    
7. **Mise à jour du déploiement** : Modifiez `nginx-deployment.yml` pour utiliser la version `latest` de l'image Nginx, puis appliquez la modification avec `kubectl apply`.
    
8. **Observation des changements** : Examinez les ReplicaSets actifs et l'image utilisée par le ReplicaSet en cours.
    
9. **Nettoyage** : Supprimez toutes les ressources créées et recréez-les en utilisant des commandes impératives pour consolider la maîtrise de Kubernetes.
    

En intégrant kubeadm dans notre flux de travail Kubernetes, vous simplifierons considérablement la gestion du cycle de vie de notre cluster, nous permettant ainsi de nous concentrer davantage sur le déploiement et la gestion de nos applications.

## 1\. Définition des conceptes

### 1.1. C'est quoi kubeadm ?

kubeadm est un outil conçu par la communauté Kubernetes pour simplifier la mise en place et la gestion des composants fondamentaux d'un cluster Kubernetes de manière sécurisée et automatisée. Il est destiné à fournir une méthode standardisée pour la formation rapide de clusters Kubernetes.

### 1.2. Fonctionnalités de kubeadm

**Initialisation du Cluster :** kubeadm initialise les composants nécessaires pour faire fonctionner un cluster Kubernetes, y compris le serveur API, le Controller Manager et l'ordonnanceur (Scheduler). Cette étape comprend la configuration de la sécurité du cluster, la génération de certificats, et la configuration des composants de gestion du cluster.

**Gestion des Tokens et de la Sécurité :** kubeadm génère un token que les autres nœuds peuvent utiliser pour rejoindre le cluster de manière sécurisée. Il configure également les règles de base pour la communication sécurisée entre les nœuds du cluster.

**Configuration de Réseau :** Après l'initialisation, kubeadm attend que l'administrateur installe un add-on réseau avant que les nœuds ne soient prêts à exécuter des applications. Cela garantit que la communication inter-pod sur le cluster est bien établie.

**Ajout de Nœuds :** kubeadm fournit une commande simple pour ajouter des nœuds au cluster. Ceci est essentiel pour l'expansion du cluster.

Mise à niveau du Cluster : Avec kubeadm, la mise à niveau des composants du cluster vers de nouvelles versions est rationalisée et peut être exécutée avec des commandes simples, minimisant ainsi le risque d'erreurs humaines.

### 1.3. Pourquoi utiliser kubeadm ?

**Simplicité :** kubeadm réduit la complexité de mise en place d'un cluster Kubernetes, ce qui le rend accessible même pour ceux qui sont relativement nouveaux dans la technologie Kubernetes.

**Standardisation :** En utilisant kubeadm, vous suivez les meilleures pratiques et les configurations recommandées par la communauté Kubernetes, garantissant ainsi la fiabilité et la sécurité de votre cluster.

**Flexibilité :** kubeadm est conçu pour fonctionner bien avec les systèmes d'exploitation et les environnements d'hébergement les plus courants, ce qui en fait une solution versatile pour divers cas d'utilisation.

## 2\. **Prérequis** : Liste des exigences matérielles et logicielles.

Dans notre cas, nous allons provisionner une instances EC2 s'exécutant sous Ubuntu 20.04 Focal Fossa LTS, grace au provider AWS, à partir delaquelle nous effectuerons toutes nos opérations.

[Provisionner une instance EC2 sur AWS à l'aide de Terraform](https://gitlab.com/CarlinFongang-Labs/Terraform/lab2-terraform-aws) (recommandé)

[Provisionner une instance EC2 sur AWS à l'aide d'Ansible](https://gitlab.com/CarlinFongang-Labs/Ansible/lab10-deploy-ec2)

## 1\. Configuration initiale

### 1.1. Prérequis techniques

Nous utiserons kubeadm pour ce lab, cet outil pour être déployé, nécessite : 2vCPU et 4Go de RAM minimum.

### 1.2. Configuration du cluster

Pour la création de notre cluster, se reférer à la documentation sur [l'installation de kubeadm](https://gitlab.com/CarlinFongang-Labs/kubernetes/lab1.1-install-kubeadm.git)

## 2\. Déploiement du Pod Simple

### 2.1. Création du fichier pod.yml

```bash
sudo nano pod.yml
```

contenu du manifest

```bash
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
  labels:
    app: web
spec:
  containers:
    - name: web
      image: mmumshad/simple-webapp-color
      ports:
        - containerPort: 8080
      env:
        - name: APP_COLOR
          value: red
```

### 2.2. Déploiement du pod avec l'image mmumshad/simple-webapp-color

```bash
kubectl apply -f pod.yml
```

vérification des pods en cours

```bash
kubectl get pod
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939839884/253743b9-4ba0-453b-ae75-56d29d89ff08.png align="center")

## 3\. Vérification et exposition du Pod

### 3.1. Commandes pour lancer et vérifier l'état du pod

```bash
kubectl describe pod simple-webapp-color
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939858986/363314f6-b4e3-403b-82a0-b242e0755bac.png align="center")

Sur cette capture, on peut voir que le pod est assigné au node **k8s-worker1/172.31.30.26** et le label de celui ci est **app=web**

### 3.2. Exposition du pod sur le réseau via port-forward

La commande ci-dessous permet de rediriger et d'écouter sur le port **8080** de toutes les interfaces réseau de la machine hôte, rendant ainsi accessible sur ce port le service fourni par le pod simple-webapp-color dans un cluster Kubernetes.

```bash
kubectl port-forward simple-webapp-color 8080:8080 --address 0.0.0.0
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939876772/a25cdc3b-7570-4996-8691-1f1d9e30c69c.png align="center")
> 
> *Sortie console une fois la commande passée*

### 3.3. Suppression du pod

Pour supprimer le pod crée, de la même façon que nous l'avons lancé, nous allons utiliser la commande :

```bash
kubectl delete -f pod.yml --v=5
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939895362/bd0f22be-c62c-4680-9a16-2dedaae12701.png align="center")

## 4\. Accès et test de l'application

Pour vérifier l'exposition du pod vers l'extérieur, l'on va entrée le nom de domaine/ip public du control node dans un navigateur suivi du port 8080 qui correspond au port d'exposition.

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939908807/2d330731-a3d3-44c0-8a94-de7fec1bb595.png align="center")
> 
> *L'application web tournant sur le pod est bien accessible via internet*

Nous venons donc de déployer notre toute première application grace à kubernetes 🥳🙌

## 5\. Déploiement de Nginx

### 5.1. Rédaction du manifeste nginx-deployment.yml

```bash
sudo nano nginx-deployment.yml
```

```bash
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment 
  labels:
    app: nginx
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18.0
        ports:
        - containerPort: 80
```

### 5.2. Déploiement de Nginx

```bash
kubectl apply -f nginx-deployment.yml --v=5
```

### 5.3. Vérification des pods et des ReplicaSets

```bash
kubectl get pod
kubectl get replicaset
kubectl get deploy
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939929209/ac80582d-1f0c-4292-8f8a-3ae9ddf1b2ce.png align="center")

on peut avoir des information sur le deployment également

```bash
 kubectl describe deploy
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939949833/d43a9b09-ea5d-4f9f-bee2-3166c2ae0be6.png align="center")

Pour avoir plus de détail sur les pods

```bash
kubectl describe pod nginx-deployment-54bcfc567b-nf7dm
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939966307/3dd6a762-0da8-457f-b1bc-b586dae223ba.png align="center")
> 
> *Informations sur le premier pod*

```bash
kubectl describe pod nginx-deployment-54bcfc567b-s9j8b
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712939984849/56aa99d2-2867-4aa5-8fd1-27701540e8ec.png align="center")

Comme on peut le constater, sur chacune des capture, chaque pod est hébergé sur un node distinct.

## 6\. Mise à jour et gestion des versions

### 6.1. Procédure de mise à jour de l'image Nginx vers la version latest

Pour procéder à la mise à jour de Nginx vers la **lastest**, nous allons simplement mettre à jour notre ficher **deployment**

```bash
sudo nano nginx-deployment.yml
```

```bash
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment 
  labels:
    app: nginx
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
```

### 6.2. Application des modifications avec kubectl apply

```bash
kubectl apply -f nginx-deployment.yml
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940007000/a0477aee-d884-4217-a39a-37c08b93a316.png align="center")

On observe une reconfiguration du deploiement et non pas un deploiement à part entier comme au tout début pour la version **1.18.0** de Nginx

### 6.3. Observation des changements dans les Replicasets

```bash
kubectl get replicaset -o wide
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940031469/1d50e3a6-04b9-48c5-b323-b85b4aabff2b.png align="center")

Apres application de la commande, on peut observer que les précédents pods tournant sous **nginx:1.18.0** sont à l'arrêt tandis qu'on à deux nouveaux pods en cours d'exécution et tournant sous la version **latest** Nginx

Il est important de noter que ce basculement est progressif, kubernetes va commencer pas créer un à un les nouveaux pods, tant dis qu'il va supprimer progressivement les anciens pods tout en gardant en cours d'exécution le nombre de replicas définit préalablement dans le deployment, soit **"2"**

## 7\. Nettoyage du cluster

### 7.1. Suppression des ressources créées

A présent nous allons supprimer toutes les ressources créees, et reprendre tout celà de façon impérative.

```bash
kubectl delete -f nginx-deployment.yml
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940049613/6fe530f5-da61-466c-9295-fccba4bcebfb.png align="center")
> 
> *suppression des ressources*

### 7.2. Commandes pour recréer les ressources de manière impérative

#### 7.2.1. Création du pod "simple-webapp-color"

```bash
kubectl run --image=mmumshad/simple-webapp-color \
--env="APP_COLOR=blue" \
--restart=Never \
simple-webapp-color
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940066766/e7c7f960-46d7-4a41-b455-b9c56a2664d1.png align="center")
> 
> *Le pod est bien crée*

Exposition du pod à internet

```bash
kubectl port-forward simple-webapp-color 8080:8080 --address 0.0.0.0
```

Une fois le pod exposé, on va de nouveau consulter l'application web grace à l'ip public/domaine de l'instance faisant office de node principal.

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940081359/6dbf928d-b159-4fe7-ba0b-66b547e49f58.png align="center")

Pour supprimer notre pod, nous entrerons la commande suivante :

```bash
kubectl delete pod simple-webapp-color
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940121793/3fb2e7de-31d8-4fa1-811b-123f5159d7f6.png align="center")

#### 7.2.2. Création impératif du deployment

Création du deploiement avec pour image nginx:1.18.0

```bash
kubectl create deployment --image=nginx:1.18.0 nginx-deployment
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940158751/2b4e6290-43d9-484f-a349-2ecd4a4f90ae.png align="center")

Le pod à bien été lancé mais on a un seul pod au lieu de deux comme on le voudrais, pour régler ce problème, nous allons passer la commande suivante :

```bash
 kubectl scale --replicas=2 deployment/nginx-deployment
```

En controllant de nouveaux nos pods, on obtiens bien deux pods sous **nginx:1.18.0**

```bash
kubectl get deploy
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940179396/03d6dca0-3b7f-4cea-9e70-fccc3ed0562d.png align="center")

Pour faire upgrade nginx, nous allons passer la commande suivante :

```bash
kubectl set image deployment/nginx-deployment nginx=nginx:latest
```

pour vérifier la mise à jour :

```bash
kubectl get replicasets -o wide
```

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1712940192228/e2cfe325-8734-4449-8e55-9ae698d2dd00.png align="center")

Nous avons mis en place un objet de type deployment de manière impérative. Cependant, pour faciliter le travail collaboratif, il est recommandé d'utiliser des manifestes qui peuvent être versionnés.

## Documentation

### [Installer kubeadm sur ubuntu](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

### [Creating a Single Control-Plane Cluster with kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)
