# TP2 : Kubernetes Ingress (cluster kind) ## Compléter le schéma suivant avec des objets Kubernetes ![](https://i.imgur.com/DDC9aKe.png) ## Installer Kind et créer votre premier cluster Kind est un outil permettant d'exécuter des clusters Kubernetes locaux à l'aide de "nœuds" de conteneur Docker. kind a été principalement conçu pour tester Kubernetes lui-même, mais peut être utilisé pour le développement local ou CI. Pour installer kind, sur linux il suffit d'executer les commandes suivantes : ```bash curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind ``` Pour créer le cluster, voici la commande : ```bash jere@LAPTOP-ADMIN:~tp02/c-cluster$ kind create cluster --name cluster-kind1 ``` ## Installer le Nginx ingress Controller ### Etape 1 : * entrée ```bash cat <<EOF | kind create cluster --config=- kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: "ingress-ready=true" extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCP EOF ``` * sortie ```bash Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.25.3) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind ``` ### Etape 2 : ```bash jere@LAPTOP-ADMIN:~/tp02/c-cluster$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created serviceaccount/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created configmap/ingress-nginx-controller created service/ingress-nginx-controller created service/ingress-nginx-controller-admission created deployment.apps/ingress-nginx-controller created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created ``` ## Builder et publier (à partir de l’image nginx) sur le DockerHub, une image docker pour chacun des sites web présent sur le schéma précédent. Vous devez avoir 3 images (une par magasin tacos, pizzas et burgers) Pour cette partie, j'ai créer un dossier pour chaque restaurant contenant 2 fichiers : * index.html : avec une balise title associé au restaurant * Dockerfile : qui va récupérer l'image de nginx et copier le fichier index.html dans le conteneur dans le dossier "usr/share/nginx/html" Voici l'arborescence : ```bash jere@LAPTOP-ADMIN:~/cours-cloud/conteneur-cours/repo-tp-conteneurisation/02-KUBERNETES/tp02/conf-dockerfile$ tree -a . ├── burger │ ├── Dockerfile │ └── burger.html ├── pizza │ ├── Dockerfile │ └── pizza.html └── tacos ├── Dockerfile └── tacos.html ``` BUILD ```bash docker build -t pizza -f Dockerfile . docker build -t bt-tacos -f Dockerfile . docker build -t bt-burger -f Dockerfile . ``` TAG ```bash jere@LAPTOP-ADMIN:~tp02/conf-dockerfile$ docker tag pizza jeremyyn/restaurants:pizza jere@LAPTOP-ADMIN:~tp02/conf-dockerfile$ docker tag bt-tacos jeremyyn/restaurants:bt-tacos jere@LAPTOP-ADMIN:~tp02/conf-dockerfile$ docker tag bt-burger jeremyyn/restaurants:bt-burger ``` PUSH ```bash docker push jeremyyn/restaurants:pizza docker push jeremyyn/restaurants:bt-tacos docker push jeremyyn/restaurants:bt-burger ``` Puis vérifier les push sur le repo : ![](https://i.imgur.com/eg05jLT.png) ![](https://i.imgur.com/dj7CjQH.png) ## Ecrire les fichiers yaml vous permettant de déployer sur votre cluster kind installé en local les composants décrits sur le schéma de la question 3 et les images crées à la question 4 ### Arborescence update avec le fichiers ingress.yml et conf.yml pour chaques restaurants : ```bash └── tp02 ├── burger │ ├── ConfBurger.yml │ ├── Dockerfile │ └── index.html ├── ingress.yml ├── pizza │ ├── ConfPizza.yml │ ├── Dockerfile │ └── index.html └── tacos ├── ConfTacos.yml ├── Dockerfile └── index.html ``` Fichier ingress.yml ```bash= apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-resource-backend-restaurants annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: mypizza.eatsout.com http: paths: - pathType: Prefix path: "/" backend: service: name: nginx-pizza-web-service port: number: 80 - host: burgerandtacos.eatsout.com http: paths: - pathType: Prefix path: "/burgers" backend: service: name: nginx-burger-web-service port: number: 80 - pathType: Prefix path: "/tacos" backend: service: name: nginx-tacos-web-service port: number: 80 ``` Fichier ConfPizza.yml ```bash= --- apiVersion: v1 kind: Service metadata: name: nginx-pizza-web-service spec: selector: app: nginx-web-pizza ports: - name: http port: 80 targetPort: 80 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-pizza-web-deployment spec: replicas: 1 selector: matchLabels: app: nginx-web-pizza template: metadata: labels: app: nginx-web-pizza spec: containers: - name: cont-pizza image: jeremyyn/restaurants:pizza ports: - containerPort: 80 ``` Fichier ConfBurger.yml ```bash= --- apiVersion: v1 kind: Service metadata: name: nginx-burger-web-service spec: selector: app: nginx-web-burger ports: - name: http port: 80 targetPort: 80 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-burger-web-deployment spec: replicas: 1 selector: matchLabels: app: nginx-web-burger template: metadata: labels: app: nginx-web-burger spec: containers: - name: cont-burger image: jeremyyn/restaurants:bt-burger ports: - containerPort: 80 ``` Fichier ConfTacos.yml ```bash= --- apiVersion: v1 kind: Service metadata: name: nginx-tacos-web-service spec: selector: app: nginx-web-tacos ports: - name: http port: 80 targetPort: 80 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-tacos-web-deployment spec: replicas: 1 selector: matchLabels: app: nginx-web-tacos template: metadata: labels: app: nginx-web-tacos spec: containers: - name: cont-tacos image: jeremyyn/restaurants:bt-tacos ports: - containerPort: 80 ``` ### Sortie curl pour vérifier le fonctionnement Chercher la balise h1 avec le titre du restaurant😉 Pizza ```bash= jere@LAPTOP-ADMIN:~/02-KUBERNETES$ curl mypizza.eatsout.com <!DOCTYPE html> <html> <head> <title>Starter template - Axentix</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.css" /> </head> <body class="layout"> <header> <nav class="navbar shadow-1 primary"> <button class="btn rounded-1 white hide-md-up btn-small mr-2" data-target="main-sidenav"> Menu </button> <a href="#" target="_blank" class="navbar-brand">Axentix</a> <div class="navbar-menu ml-auto"> <a class="navbar-link active hide-sm-down" href="#">Link 1</a> <a class="navbar-link hide-sm-down" href="#">Link 2</a> <a class="navbar-link hide-sm-down" href="#">Link 3</a> <div id="navbar-dropdown" data-ax="dropdown" class="dropdown" data-dropdown-prevent-viewport="true"> <a class="navbar-link" href="#" data-target="navbar-dropdown">Dropdown</a> <div class="dropdown-content white shadow-1 dropdown-right"> <a class="dropdown-item" href="#">Item 1</a> <a class="dropdown-item" href="#">Item 2</a> </div> </div> </div> </nav> </header> <div class="sidenav white shadow-1" id="main-sidenav" data-ax="sidenav"> <div class="sidenav-header"> <img src="https://useaxentix.com/img/axentix.svg" alt="" class="sidenav-logo" /> </div> <a href="#" class="sidenav-link active">Link 1</a> <a href="#" class="sidenav-link">Link 2</a> <a href="#" class="sidenav-link">Link 3</a> </div> <main> <h1 class="text-center font-w300 mx-2">PIZZA !</h1> </main> <footer class="footer primary"> Copyright © 2023 - Example </footer> <script src="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.js"></script> </body> </html> ``` Tacos ```bash= jere@LAPTOP-ADMIN:~/02-KUBERNETES$ curl burgerandtacos.eatsout.com/tacos <!DOCTYPE html> <html> <head> <title>Starter template - Axentix</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.css" /> </head> <body class="layout"> <header> <nav class="navbar shadow-1 primary"> <button class="btn rounded-1 white hide-md-up btn-small mr-2" data-target="main-sidenav"> Menu </button> <a href="#" target="_blank" class="navbar-brand">Axentix</a> <div class="navbar-menu ml-auto"> <a class="navbar-link active hide-sm-down" href="#">Link 1</a> <a class="navbar-link hide-sm-down" href="#">Link 2</a> <a class="navbar-link hide-sm-down" href="#">Link 3</a> <div id="navbar-dropdown" data-ax="dropdown" class="dropdown" data-dropdown-prevent-viewport="true"> <a class="navbar-link" href="#" data-target="navbar-dropdown">Dropdown</a> <div class="dropdown-content white shadow-1 dropdown-right"> <a class="dropdown-item" href="#">Item 1</a> <a class="dropdown-item" href="#">Item 2</a> </div> </div> </div> </nav> </header> <div class="sidenav white shadow-1" id="main-sidenav" data-ax="sidenav"> <div class="sidenav-header"> <img src="https://useaxentix.com/img/axentix.svg" alt="" class="sidenav-logo" /> </div> <a href="#" class="sidenav-link active">Link 1</a> <a href="#" class="sidenav-link">Link 2</a> <a href="#" class="sidenav-link">Link 3</a> </div> <main> <h1 class="text-center font-w300 mx-2">TACOS !</h1> </main> <footer class="footer primary"> Copyright © 2023 - Example </footer> <script src="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.js"></script> </body> </html> ``` Burger ```bash= jere@LAPTOP-ADMIN:~/02-KUBERNETES$ curl burgerandtacos.eatsout.com/burgers <!DOCTYPE html> <html> <head> <title>Starter template - Axentix</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.css" /> </head> <body class="layout"> <header> <nav class="navbar shadow-1 primary"> <button class="btn rounded-1 white hide-md-up btn-small mr-2" data-target="main-sidenav"> Menu </button> <a href="#" target="_blank" class="navbar-brand">Axentix</a> <div class="navbar-menu ml-auto"> <a class="navbar-link active hide-sm-down" href="#">Link 1</a> <a class="navbar-link hide-sm-down" href="#">Link 2</a> <a class="navbar-link hide-sm-down" href="#">Link 3</a> <div id="navbar-dropdown" data-ax="dropdown" class="dropdown" data-dropdown-prevent-viewport="true"> <a class="navbar-link" href="#" data-target="navbar-dropdown">Dropdown</a> <div class="dropdown-content white shadow-1 dropdown-right"> <a class="dropdown-item" href="#">Item 1</a> <a class="dropdown-item" href="#">Item 2</a> </div> </div> </div> </nav> </header> <div class="sidenav white shadow-1" id="main-sidenav" data-ax="sidenav"> <div class="sidenav-header"> <img src="https://useaxentix.com/img/axentix.svg" alt="" class="sidenav-logo" /> </div> <a href="#" class="sidenav-link active">Link 1</a> <a href="#" class="sidenav-link">Link 2</a> <a href="#" class="sidenav-link">Link 3</a> </div> <main> <h1 class="text-center font-w300 mx-2">BURGER !</h1> </main> <footer class="footer primary"> Copyright © 2023 - Example </footer> <script src="https://cdn.jsdelivr.net/npm/axentix@2.2.1/dist/axentix.min.js"></script> </body> </html> ``` ## Votre magasin de tacos devient très populaire (il va avoir 3 fois plus de commandes). Il va vous falloir gérer une charge importante sur le Service de commande des tacos. Comment gérez-vous cela ? Comment vérifier que la charge est bien répartie (avec quelle commande kubectl ?) ? Pour vérifier que la charge soit bien répartie, on peut utiliser la commande "kubectl top pod". Elle permet de donner des informations sur l'utilisation des ressources sur les pods. Cependant lorsqu'on execute la commande, un message d'erreur apparait : ![](https://i.imgur.com/BveT1Vj.png) ESCOBAR JEREMY M2 INFRA CLOUD