diff --git a/README.md b/README.md index 91335c543c1f1a38d90fb5dbaa97b71f607b2295..67574563e552ceb57c72d982b234d12f5cbc66e7 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Il va falloir mettre en place quelque utilitaires de base pour pouvoir réaliser Pour configurer l'accès au cluster de test de ViaRézo, il faut que tu ailles récupérer un fichier sur le cluster de test de ViaRézo: ```bash +mkdir ~/.kube ssh 138.195.139.40 "sudo cp ~root/.kube/config ." scp 138.195.139.40:config ~/.kube/config ``` @@ -40,7 +41,7 @@ Un petit conseil pour ceux qui n'utilisent pas OhMyZsh: **installer ohmyzsh**. ## 1. Créer un namespace pour le groupe -Un namespace, c'est une façon d'isoler des resources entre elles. On va donc créer un namespace pour le groupe, c'est dans ce namespace que vous allez travailler. +Un namespace, c'est une façon d'isoler des resources entre elles. On va donc créer un namespace pour le groupe, dans lequel vous allez travailler. Pour un seul des membres du groupe uniquement: @@ -48,18 +49,21 @@ Pour un seul des membres du groupe uniquement: kubectl create namespace <le nom de mon équipe géniale> ``` -On définit ensuite ce namespace comme namespace par défaut (Pour tous les membres du groupe): +On définit ensuite ce namespace comme option par défaut (Pour tous les membres du groupe): ```bash kubectl config set-context --current --namespace <le nom de mon équipe géniale> ``` Cela veut dire que si vous ne spécifiez pas explicitement de namespace lorsque vous créez des ressources, elles seront créées dans ce namespace. + +C'est ici qu'on va déployer notre application, mais avant de la déployer sur Kubernetes, il est impératif de la Dockerisé. + ## 2. Il est temps de construire l'application elle-même Et cette application c'est VRoum. Pour cette première partie, l'objectif est de construire les images qui vont faire tourner notre site, il y a deux images à vous répartir (ou à faire ensemble séquentiellement). -Pour un petit pense-bête sur Docker, n'hésite pas à lire [cette petite fiche](./Docker.md) +Si vous avez un petit trou de mémoire sur Docker, n'hésitez pas à lire [cette petite fiche](./Docker.md) ou alors à aller sur internet. ### 2.1 Le Front @@ -68,7 +72,11 @@ Le code source du front est dans le dossier front. Ton objectif est de créer un Dockerfile et de faire tourner le front de VRoum en local. Le front est fait en React: vous deverez donc faire un **multi-stage** build: - Stage 0: build l'application React (Attention le .env doit être rempli pour cette étape) + - partir d'une image node + - installer les dépendences (`npm install`) + - puis build le frontend (`npm run build`) - Stage 1: Servir le site avec une image Nginx. + - juste copier le build de l'étape précédence dans le bon dossier. (``Ne vous embếtez pas à modifier la conf nginx, c'est une perte de temps``) #### 2.1.2 Tester l'image Test ton image Docker: @@ -80,6 +88,9 @@ Vérifie ensuite dans ton navigateur que tu peux bien voir le front de Vroum #### 2.1.3 Challenge supplémentaire (Facultatif) Il est souvent considéré comme une mauvaise pratique d'avoir des conteneurs qui tournent avec l'utilisateur **root** en production. Vérifie que ce n'est pas le cas ou alors fait les changements nécéssaires. +> Hint: `docker exec -it vroum-front ...` + +``Attention si ton image ne tourne pas en root, ça veut dire qu'elle n'expose pas le site web sur le port 80, mais plutôt 8080 (par exemple). C'est à prendre en compte pour les étapes suivantes.`` ### 2.2 Le Back @@ -88,24 +99,26 @@ Le code source du back est dans le dossier back. Ton objectif est de créer un Dockerfile et de construire une image avec pour enfin le faire tourner en local. Le back est fait en Django, tu dois donc: - partir d'une image python - - installer les dépendences nécessaires avec pip - - lancer le serveur python dans l'entrypoint + - installer les dépendences nécessaires (`pip install -r ...`) + - Dans l'entrypoint, faire les _migrations_ puis lancer le serveur. -``Attention: ne pas ajouter de fichier non désiré dans l'image (par exemple le .env ou les node_modules s'il y en a)`` +``Attention: ne pas ajouter de fichier non désiré dans l'image (par exemple le .env ou les node_modules s'il y en a).`` #### 2.2.2 Tester l'image Pour tester que le back fonctionne bien il va falloir d'abord remplir un **.env** dans le dossier du back: - Pensez à mettre `PRODUCTION` en `FALSE` pour utiliser du SQLite, les informations pour la BDD ne compte alors pas. -Puis faire tourner le back: + - Tu peux aller récupérer les cliendid et secret du client OAuth `VRoum Formation Kubernetes`. + +Puis faire lancer le back: ``` docker run -p 8000:8000 --env-file .env vroum-back ``` Faire des curl pour tester que tout marche à peu près bien. -Pour tester le back, tu peux ausi utiliser le front en lançant les deux conteneurs simultanément. +Pour tester le back, tu peux ausi utiliser le front en lançant les deux conteneurs simultanément, dans ce cas, pense à bien configurer **BACK_ROOT** et **FRONT_ROOT** en accord avec **REACT_APP_API_URL** et **REACT_APP_CLIENT_URL**. -#### 2.2.3 Challenge supplémentaire (Facultatif et plus dur que pour le front) +#### 2.2.3 Challenge supplémentaire (Facultatif) Il est souvent considéré comme une mauvaise pratique d'avoir des conteneurs qui tournent avec l'utilisateur **root** en production. Vérifie que ce n'est pas le cas ou alors fait les changements nécéssaires. @@ -115,7 +128,7 @@ Utilise une image alpine (python:3.8-alpine) comme base pour ton image. ## 3. Déployer l'application sur kubernetes -Kubernetes c'est un orchestrateur de conteneur. Ca permet de gérer pleins de conteneurs et de faire des trucs inteligents avec comme créer des réplicat et de recréer dynamiquement les conteneurs qui crashent. +Kubernetes c'est un orchestrateur de conteneur. Ca permet de gérer pleins de conteneurs et avec des fonctionnalités plutôt sympa comme nomamment le redémarrage des conteneurs qui ont crashé ou la gestion dynamique du nombre de réplique de ces conteneurs. Kubernetes fonctionne sur un mode de déclaration des ressources. On écrit ce qu'on veux dans des fichiers yaml et il suffit de lancer la commande ``` @@ -134,74 +147,80 @@ kubectl describe <objet> <nom de l'objet> ### 3.1 Déployer un pod à la main sur kubernetes -Dans un premier temps, pour créer la BDD, on va faire tourner un simple pod _mysql_. Cette solution est loin d'être optimal mais va nous permettre de se familiariser avec **kubectl**. +Dans un premier temps, pour créer la BDD, on va faire tourner un simple pod _mysql_. Cette solution est loin d'être optimal mais va nous permettre de se familiariser avec **kubectl**. Pour créer un pod _mysql_ c'est pas très compliqué, mais il y a pas mal de variables d'environnement à remplir: ```bash kubectl run mysql --image=mysql --port 3306 --env "MYSQL_USER=vroum" --env "MYSQL_PASSWORD=password" --env "MYSQL_DATABASE=vroum" --env "MYSQL_RANDOM_ROOT_PASSWORD=yes" ``` -Vérifie que ton pod tourne comme il faut avec: +Vérifiez que votre **pod** tourne comme il faut avec: ```bash kubectl get pod mysql ``` (Ça peut prendre un peu de temps) -Récupère un shell dans le pod avec: +Récupèrez un shell dans le **pod** avec: ```bash kubectl exec -it mysql -- bash ``` -Vérifie que tu peux te connecter à la base de donnée: +Vérifiez que vous pouvez vous connecter à la base de donnée: ```bash -mysql -u username --database vroum -p +mysql -u vroum --database vroum -p ``` -Regarde les logs de ton pod pour voir comment il se porte: +Regardez les logs de votre **pod** pour voir comment il se porte: ```bash kubectl logs mysql ``` -Récupère un peu plus d'information pour ton pod +Récupère un peu plus d'information sur ton pod ```bash kubectl get pod mysql -o wide ``` -Tu peux notamment voir l'addresse du pod au sein du cluster, tu en auras besoin pour configure ton back. +Vous pouvez notamment voir l'adresse du **pod** au sein du cluster, tu en auras besoin pour configurer ton back et qu'il se connecte à la BDD. + ### 3.2 Pousser les images sur le registry -La première étape du déploiement sur kubernetes va être de pousser les images sur le registry afin que le cluster kube puisse les récupérer. Le registry c'est un serveur qui stocke les images docker. -Pour cela il faut d'abord renomer nos images docker afin d'indiquer a docker ou les pousser. La forme du tag du docker doit être : +Un registry c'est un serveur qui stocke et distribue des images Docker, il va ici servir au cluster Kubernetes comme point d'accès pour récupérer les images que vous avez construites. La première étape va donc être de _push_ vos images sur le registry. +Pour cela il faut d'abord renommer nos images Docker afin d'indiquer a Docker où les _push_. La forme du tag du docker doit être : ``` -registry/project/nom_de_l'image:version +<registry>/<project>/<image>:<tag> ``` +Le tag sert à définir plusieurs versions de la même image, c'est un peu l'analogue des branche git mais en Docker. -Dans notre cas on souhaite pousser sur le registry de viarezo (registry.viarezo.fr) dans le projet "formation-kube", cela donne donc: +Dans notre cas on souhaite pousser sur le registry de viarezo [registry.viarezo.fr](https://registry.viarezo.fr) dans le projet "formation-kube", cela donne donc: -La commande pour tagger une image est `tag`: +La commande pour tagger une image déjà construite est `tag`: ```bash docker tag <image> registry.viarezo.fr/formation-kube/<image>:<version> ``` +Une alternative est de construire directement l'image avec le bon `tag`: +```bash +docker build . -t registry.viarezo.fr/formation-kube/<image>:<version> +``` -Il faut ensuite s'authentifier au près du registry avec la commande `login`: +Il faut ensuite s'authentifier auprès du registry avec la commande `login`: ```bash -# En utilisant Bitwarden +# En utilisant les identifiants qui sont sur Bitwarden docker login registry.viarezo.fr ``` -Il suffit ensuite de pousser l'image avec +Il suffit ensuite de _push_ l'image avec ``` docker push registry.viarezo.fr/formation-kube/vroum-front:<un truc rigolo unique> ``` -Note importante, - Si vous avez décidé de sauter ou d'abandonner la partie précédente, vous pourrez trouver une image pour le back et pour le front disponible sur le registry avec le `tag` **:correction**. +>Note importante: +>> Si vous avez décidé de sauter ou d'abandonner la partie précédente, vous pourrez trouver une image pour le back disponible avec le `tag` **:correction**. Pour le front, il faudra le build vous même avec le Dockerfile donné en solution (2.1.3). -Maintenant les choses sérieuses commencent, on commence à faire du Kubernetes et à déployer des ressources, à chaque fois il faudra créé une ressource pour le back et une pour le front, vous pouvez vous partager les tâches ou tout faire ensemble séquentiellement au choix. +Maintenant les choses sérieuses commencent, on à enfin affaire à du Kubernetes. On va donc successivement déployer des ressources nécessaire au bon fonctionnement de notre application, à chaque fois il faudra créé une ressource pour le back et une pour le front, vous pouvez vous partager les tâches ou tout faire ensemble séquentiellement (au choix). ### 3.3 Déploiement -L'unité de base de kubernetes c'est le **pod**. Un **pod** correspond à un ou plusieurs conteneurs gérés ensemble. -Il est possible de créer un pod directement (comme on l'a vu précédemment) mais en pratique c'est rarement fait. Habituellement on créé les pods au travers de **deployment**. Le **deployment** est une resource qui permet de créer un ou plusieurs **pods** et de gérer leur cycle de vie. Il s'assure qu'il y ait toujours le bon nombre de réplicat disponible sur le cluster en récréant/supprimant des pods si besoin. +L'unité de base de kubernetes c'est le **pod**. Un **pod** correspond à un ou plusieurs conteneurs gérés ensemble. Ils scalent ensemble et sont tués ensemble quand il faut. +Il est possible de créer des pods directement (comme on l'a vu précédemment) mais en pratique c'est rarement fait. Habituellement on créé les pods au travers d'un **deployment**. Le **deployment** est une resource qui permet de créer un **pods** et de gérer son cycle de vie: son nombre de réplique, la mise à jour de son image Docker, etc. Il s'assure qu'il y ait toujours le bon nombre de réplicat disponible sur le cluster en récréant/supprimant des pods si besoin. Le déploiement de base se décrit grace au template suivant (N'hésitez pas a installer l'extension kubernetes de vscode qui écrit les templates toute seule): @@ -229,7 +248,7 @@ spec: ports: - containerPort: <Port> ``` -Ecrivez donc un déploiement pour le back et un pour le front. +Ecrivez donc un déploiement pour le back et un pour le front. Vérifiez ensuite que vos pods sont bien marqués en ready. En ce qui concerne les labels, un déploiement régis les pods qui contiennent les labels qui sont dans sont _selector.matchLabels_, il faut donc que pour le front et le back ces labels soit différent, et que les labels dans _selector.matchLabels_ soit inclue dans les labels du template. @@ -244,18 +263,55 @@ patek: annulé ``` Attention pour le back, il est nécéssaire de passer au conteneur des [variables d'environnement](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/) ! -Pour l'instant ne vous embêtez pas avec les secrets. + Tu peux retrouver les client ID et client secret sur l'auth (J'ai créé un client dédié `VRoum Formation Kubernetes`), tandis que les variables de la base de données sont à récupérer à l'étape n-2. +``N'hésite pas à mettre plusieurs **replicas** dans tes déploiements (2–3 pas 18 non plus) pour voir un peu comment kubernetes gère la création de plusieurs répliques`` + + Tu peux alors tester que ton front marche bien avec ``` kubectl port-forward <nom_du_pod> <port_de_ton_pc>:<port_du_pod> ``` mais il n'arrivera pas à se connecter au back tant que l'on ne l'a pas exposé sur internet... +> Attention +> Si vous vous êtes trompé dans votre image Docker et que vous avez du vous y prendre à deux fois, vous vous rendrez compte que par défaut, Kubernetes ne re-_pull_ pas l'image du registry même si vous supprimer le **deployment** et le recréez. Le trick, c'est de changer l'**imagePullPolicy** dans le template du pod. C'est pas top de le faire en production, car les **pods** mettent plus de temps à se créer, mais en testing c'est souvent pratique. + +### 3.4 Secret + +Vous avez du voir qu'il y a quelque informations sensibles dans nos fichier yaml (surtout celui du **deployment** du back), il faut donc que vous créiez un [secret](https://kubernetes.io/fr/docs/concepts/configuration/secret/) qui les contient et que vous l'utilisiez pour définir vos variable d'environnement. + +Voici un exemple de secret: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +stringData: + username: ouioui + password: taxi123 +``` + +Et vous pouvez référencer un secret dans votre déploiement avec ce bout de yaml ci-dessous: +```yaml +env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username +``` + +Un **secret** n'est en soit pas plus secret qu'une autre resource, il obéit simplement à des règles de contrôle d'accès qui sont différentes, néanmoins dans certaines configuration de clusters il peut être chiffré avant écriture sur le disque. + + +Pensez bien à tester votre déploiement avec le **secret**. + ### 3.4 Service -Un service est une entitée qui permet aux pods de communiquer entre eux au sein du cluster. Il s'occupe aussi du load balancing entre les réplicats des pods. +Un service est une entitée qui permet aux pods de communiquer entre eux au sein du cluster, Il s'occupe notamment du load balancing entre les différents réplicats des pods. Le template d'un service est le suivant : ``` yaml apiVersion: v1 @@ -270,12 +326,12 @@ spec: targetPort: <Target Port> ``` -Le **selector** est particulièrement important, il permet de _séléctionner_ les pods qui appartiennent à ce service. Les labels qui sont dedans doivent donc correspondre aux labels que vous avez mis dans votre déploiement. +Le **selector** est particulièrement important, il permet de _séléctionner_ les **pods** qui appartiennent à ce service. Les labels qui sont dedans doivent donc correspondre aux **labels** que vous avez mis dans votre **deployment**. -Le **targetPort** correspond au port que vous avez choisi d'exposer dans votre déploiement (le champs _containerPort_), et le **port** correspond au port sur lequel vous aimeriez bien joindre ce service (pour les service http c'est donc souvent 80). +Le **targetPort** correspond au port que vous avez choisi d'exposer dans votre déploiement (le champs _containerPort_), et le **port** correspond au port sur lequel vous aimeriez bien joindre ce **service** (pour les service http c'est donc souvent 80). ### 3.5 Exposer un service vers l'exterieur -Avec notre service nous avons exposés notre app au sein du cluster. Maintenant nous allons l'exposer vers le moooooooonde. Pour cela nous allons mettre en place des Ingress. Un Ingress est un proxy qui en fonction du nom de domaine de la requête redirige vers le service adapté. Ici, à ViaRézo, nous utilisons des IngressRoutes gérés par traefik. Traefik est un logiciel qui s'occupe de gérer toutes les routes décrites dans desIngressRoutes. +Avec notre service nous avons exposé notre app au sein du cluster. Maintenant nous allons l'exposer vers le moooooooonde. Pour cela nous allons mettre en place des Ingress. Un **Ingress** est un proxy qui en fonction du nom de domaine de la requête redirige vers le service adapté. Ici, à ViaRézo, nous utilisons des IngressRoutes gérés par l'**IngressController** Traefik. Traefik est un logiciel qui s'occupe de gérer toutes les routes décrites dans des **IngressRoutes**. Pour les noms de domaine, il faut créer une entrée A sur le DNS qui redirige vers traefik. Cette partie a déja été faite pour vous, prenez juste un nom de domaine en ``.kube.test.viarezo.fr`` @@ -298,7 +354,7 @@ spec: tls: secretName: <secret du certificat> ``` -Afin d'avoir du https signé par letsencrypt, il faut aussi créer un **certificate**: +Afin d'avoir du https signé par _letsencrypt_, il faut aussi créer un **certificate**: ```yaml # certificate.yaml apiVersion: cert-manager.io/v1 @@ -318,7 +374,7 @@ Ce **certificate** va être automatiquement être signé par Letsencrypt grace ``Attention, pensez à mettre le même nom de domaine pour le back et le front et à filter sur le PathPrefix pour le back (/api), pour éviter les problèmes de CORS, et à rebuild l'image du front si nécessaire pour bien mettre les bonnes REACT_APP_CLIENT_URL et REACT_APP_API_URL`` -``Pour l'auth, il faut que tu ajoutes **mondomaine/api/auth/callback** dans les URIs de redirection du client Auth **VRoum Formation Kubernetes`` +``Pour l'auth, il faut que tu ajoutes **mondomaine/api/auth/callback** dans les URIs de redirection du client Auth **VRoum Formation Kubernetes**`` Si ça ne fonctionne pas, on n'oublie pas les outils classique de débug sur kubernetes: ```bash @@ -335,8 +391,8 @@ Si c'est le cas **bravo !**. A ce point de la formation vous devez avoir les fichiers suivants. ``` -deploiement_front.yaml -deploiement_back.yaml +deployment_front.yaml +deployment_back.yaml service_front.yaml service_back.yaml ingressroute_front.yaml @@ -347,30 +403,30 @@ Afin d'éviter de rentrer en conflit avec la suite, pensez à supprimer vos ress Vous pouvez le faire avec la commande suivante. ```bash -kubeclt delete -f le_dossier_qui_contient_tous_mes_fichiers +kubeclt delete -f le_dossier_qui_contient_tous_mes_manifestes ``` ### 3.6 Helm le ansible de kubernetes -C'est bien sympatique tout ça mais c'est loooong. Heureusement helm est la. +C'est bien sympatique tout ça mais si on veut changer le nom de l'application (vroum en vroum-vroum par exemple), il faut le changer à au moins une dizaine d'endroite et c'est loooong. Heureusement Helm est là pour nous aider à faire un peu de templating. Helm permet de templatiser les fichiers kubernetes. Une application Helm s'appelle une chart. Une chart s'organise comme suit: -``` -VROUM -│ Chart.yaml -│ values.yaml -│ -└───templates - │ deployment_front.yaml - │ deployment_backt.yaml - | service_front.yaml - | service_back.yaml - | ingress_front.yaml - | ingress_back.yaml - | certificate.yaml - -``` -Le fichier Chart.yml décrit l'application. Il s'écrit sous la forme : -``` +```bash +vroum +├── Chart.yaml +├── templates +│ ├── certificate.yaml +│ ├── deployment_back.yaml +│ ├── deployment_front.yaml +│ ├── ingressroute_back.yaml +│ ├── ingressroute_front.yaml +│ ├── service_back.yaml +│ └── service_front.yaml +└── values.yaml + +``` +Le fichier Chart.yml permet de décrire l'application : +```yaml +# Chart.yaml apiVersion: v2 name: <nom> description: <description> @@ -413,25 +469,27 @@ helm template <nom_de_la_chart> Vous pouvez ensuite lancer un -```bash -helm install <nom de l'installation> <chemin vers la charte> +``` +helm install <nom de l'application> <chemin vers la charte> ``` pour installer votre application. Si vous avez besoin de modifier votre charte puis de réappliquer des changements, il faudra utiliser la commande `upgrade`: -```bash -helm upgrade <nom de l'installation> <chemin vers la charte> +``` +helm upgrade <nom de l'application> <chemin vers la charte> ``` -Normalement à ce moment votre vroum est disponible sur son nom de domaine. -Vous pouvez ensuite désinstaller votre charte avec -```bash +Normalement à ce moment votre **VRoum** est disponible sur son nom de domaine. +Bon bah voilà on a terminé ? Presque encore un petit bout de chemin pour proprifier tous ça. + +Vous pouvez désinstaller votre charte avec +``` helm uninstall <nom_de_l'installation> ``` avant de passer à la suite. -Vous l'aurez remarqué, Helm permet de définir une chart, de l'installer, de la désinstaller et de la mettre à jours. Dans ce sens, Helm s'apparente à un gestionnaire de paquets pour kubernetes. +Vous l'aurez remarqué, Helm permet de définir une chart, de l'installer, de la désinstaller et de la mettre à jours. Dans ce sens, Helm s'apparente à un gestionnaire de paquets pour Kubernetes. ## 4. Helm le apt de kubernetes @@ -450,26 +508,39 @@ Puis on va commencer par ajouter un repo de charte helm (celui de bitnami, c'est helm repo add bitnami https://charts.bitnami.com/bitnami ``` -Crééz le fichier values.yaml qui contient +Dans un premier temps on va crééer un secret qui contient nos _credentials_ pour MySQL: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: mysql-credentials +type: Opaque +stringData: + mysql-root-password: verystrongpassword + mysql-password: password +``` + +Puis crééz le fichier values.yaml qui contient ```yaml auth: - rootPassword: verystrongpassword - username: username + existingSecret: mysql-credentials + username: vroum database: vroum - password: password ``` -Installe mysql avec +Finalement installez mysql avec ```bash helm install mysql bitnami/mysql -f values.yaml ``` +Lorsque l'on passe en argument un `values.yaml` comme cela, seul les variables qui sont redéfinies dedans sont changées par rapport au variables par [défaut](https://github.com/bitnami/charts/blob/master/bitnami/mysql/values.yaml). -Récupère le nom du service mysql + +Récupérez le nom du service mysql ```bash kubectl get services ``` -Modifie les variables d'environnement pour ton déploiement back pour qu'il se connecte à cette nouvelle BDD. +Modifiez les variables d'environnement du déploiement de votre back pour qu'il se connecte à cette nouvelle BDD. ### 4.2 Utiliser les dépendences helm @@ -494,21 +565,20 @@ dependencies: repository: https://charts.bitnami.com/bitnami ``` -Et ajoute dans ton values.yaml +Glisse le secret de l'étape précédente dans tes templates et ajoute dans ton values.yaml ```yaml mysql: auth: - rootPassword: verystrongpassword + existingSecret: mysql-credentials username: vroum database: vroum - password: password ``` -``N'hésite pas à modifier tes templates pour ne pas avoir de valeurs en double dans ton values.yaml`` +``N'hésite pas à modifier tes templates pour ne pas avoir de valeurs en double dans ton values.yaml, voir même avoir un seul secret au lieu de deux`` -Désormais, lorsque tu déploiera **VRoum** comme à l'étape précédente, ton application sera déployé avec ta base de donnée MySQL. +Désormais, lorsque tu déploiera **VRoum** comme à l'étape précédente, ton application sera déployé avec sa base de donnée MySQL. -MySQL peut prendre pas mal de temps à se lancer et ton back, va probablement redémarrer plusieurs fois avant de démarrer correctement, il risque même de `CrashLoopBackoff` et donc de ne pas tenter de redémarrer pendant 5mins. +MySQL peut prendre pas mal de temps à se lancer et ton back, va probablement redémarrer plusieurs fois avant de démarrer correctement, il risque même de `CrashLoopBackoff` et donc de ne pas tenter de redémarrer pendant 1 minute. Si tu n'as pas envie d'attendre, tu peux le relancer à la main: @@ -527,15 +597,45 @@ Pour la prochaine étape, tu peux supprimer le `Chart.lock` et le dossier `Chart Tu disposes désormais d'une application que tu peux installer et désinstaller facilement, en https, avec une bdd, etc... C'est plutôt cool non ? Mais bon il faut encore déployer l'appli à la main et c'est un peu contraignant. -## 5. ArgoCD -Vous qui arrivez ici, BRAVO! +## 5. Le GitOps +Nous ce qu'on aime bien faire sur Kubernetes c'est du **GitOps**, ça veut dire que l'on veut piloter notre cluster à partir d'un repo git de façon **déclarative**. Cela a plusieurs avantages: + - Le repo git est toujours synchronisé avec le cluster + - Un déploiement, c'est simplement un _merge_ sur _main_ + - `git revert` pour _rollback_ une update qui a cassé + - ... + + +On va donc s'empresser de mettre notre **charte** sur un repo git, mais pour l'instant on ne peut pas car on a encore des informations sensibles qui sont en clair dans cette charts, il va falloir les chiffré un peu à la manière d'_ansible vault_ avant de les push + +### 5.1 SealedSecrets +SealedSecrets c'est un opérateur qui tourne sur le cluster et dispose d'une clé privée pour déchiffrer les **SealedSecrets** que vous allez créer et en faire des **Secrets** Kubernetes. + +Pour créer ce **SealedSecret** à partir du secret de votre **charte**, on va utiliser un utilitaire qui s'appelle `kubeseal`, que vous pouvez télécharger sur leur [Github](https://github.com/bitnami-labs/sealed-secrets/releases/tag/v0.18.0) (! Prenez bien l'architecture qui correspond à votre système.), puis avec un coup de `tar` et en mettant l'executable dans votre `path`, vous devriez pouvoir lancer un `kubeseal --version`. + +Commence par exporter ces variables d'environnements pour configurer `kubeseal`: +```bash +export SEALED_SECRETS_CONTROLLER_NAMESPACE=sealed-secrets +export SEALED_SECRETS_CONTROLLER_NAME=testing-sealed-secrets +export SEALED_SECRETS_FORMAT=yaml +export SEALED_SECRETS_SCOPE=cluster-wide +``` + +Tu peux désormais créer un **SealedSecret** à partir de ton **Secret**: +```bash +cat my_un_encrypted_secret.yaml | kubeseal > my_encrypted_secret.yaml +``` +Puis le glisser dans ta charte à la place du secret chiffré. + + +Retente d'installer ta charte avec ce nouveau **SealedSecret** à la place. + +### 5.2 ArgoCD -Il ne vous reste plus qu'a automatiser ce déploiement. Pour cela on utilise un utilitaire du nom de ArgoCD. ArgoCD synchronise automatiquement le cluster avec les ressources décrites sur le gitlab. +Il ne vous reste plus qu'a automatiser le déploiement de VRoum. Pour cela on utilise un utilitaire du nom de ArgoCD. ArgoCD synchronise automatiquement le cluster avec les ressources décrites sur le gitlab. Dans le cadre d'une mise en production tout se passerais sur le dépot [argocd](https://gitlab.viarezo.fr/ViaRezo/kubernetes/argocd) du Gitlab. Cependant pour l'occasion vous allez reconfigurer un nouveau dépot de 0. -Vous pouvez donc créer un nouveau dépot sur le gitlab et push votre chart dessus. (Ou alors faire un fork du projet et ajouter votre camarade dessus) +Vous pouvez donc créer un nouveau dépot sur le gitlab et push votre chart dessus. (Attention à bien `gitignore` le **secret** en clair). -``Oui vous avez bien entendu on vous demande de push des secrets sur le gitlab, c'est pas fou mais ça ira le temps de cette formation`` Tous se passe sur le site [argocd.viarezo.fr](https://argocd.viarezo.fr). ``Attention ce site gère aussi la prod`` @@ -543,22 +643,24 @@ ArgoCD fontionne avec des resources appelées **Applications**, chaque Applicati Vous pouvez créer des applications depuis l'interface. D'abord ajouter un nouveau repository sur ArgoCD: - - Sur votre repo git dans _Settings -> Access Tokens_, il faut créer un access token (duh) avec comme droit: _read\_repository_ + - Sur votre repo git dans _Settings -> Access Tokens_, il faut créer un access token avec comme droit: _read\_repository_ - Sur [argocd.viarezo.fr](https://argocd.viarezo.fr) dans _Settings -> Repositories_, ajoute ton repository git. - Attention, l'url doit finir avec .git sinon ça marche pas. + Attention, l'url doit finir avec `.git` sinon ça marche pas. Ensuite créer une application qui déploit ta charte: - Dans Apps, clique sur **New App**. - Dans project, choisi **applications** - Dans Sync Policy, choisi **Automatic** et coche **PRUNE RESOURCES** et **SELF HEAL** - Dans destinations, choisi le cluster en fonction du nom et non de l'url et sélectionne **testing** + - Configure tous ce qui est propre à ta charte. - Pour le reste les arguments par défaut suffisent. Vérifie que ton application s'est bien déployée sur le cluster: ```bash kubectl get all ``` -Si ce n'est pas le cas, **it's debug time**. +Si ce n'est pas le cas, **it's debug time**. +Si tu te balade sur **ArgoCD**, tu te rendra compte qu'il y a pas mal d'outil pour debogguer et que notamment presque toutes les information que tu peux avoir avec des `kubectl ...` sont disponibles dessus au clickodrome. Une fois l'application créée il suffit de push ses modifications sur le gitlab afin qu'elles soient déployées sur le cluster, (ArgoCD peut mettre plusieurs minutes à synchroniser de lui-même, mais on peut accélérer le processus en cliquant sur **refresh** sur l'interface graphique) @@ -571,6 +673,5 @@ Testons ArgoCD (et récapitulons un peu ce que nous avons fait pour l'instant): ## 6. Pour aller plus loin -Appeler un staffeur et demander lui de vous parler de: - - SealedSecrets +Appelez un staffeur et demandez-lui de vous parler de: - ArgoCD Image Updater