diff --git a/.vscode/settings.json b/.vscode/settings.json index 3ed2d4848da522d8ec9e4f8cca17180466aabeb4..5064b9cacc0a06226609a31164cbe0aea96cd3d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,9 +32,12 @@ "halfhour", "konnector", "konnectors", + "kubeconfig", + "KUBECONFIG", "l'ecogeste", "llle", "matomo", + "mespapiers", "metabase", "Metabase", "mjml", @@ -43,8 +46,10 @@ "nginx", "noreply", "numerique", + "openshift", "Openshift", "Scaleway", + "synaaps", "timestep", "usageevent" ] diff --git a/docs/openshift/cicd.md b/docs/openshift/cicd.md new file mode 100644 index 0000000000000000000000000000000000000000..856a0bd20f9f9a95343edccb301eb236e42b3481 --- /dev/null +++ b/docs/openshift/cicd.md @@ -0,0 +1,194 @@ +# CI/CD sur Openshift + +## Runner + +Pour créer un runner capable de déployer nos applications, il faut en faire la demande à partir du [Manager Openshift Synaaps](https://manager.apps.grandlyon.com/), dans la partie `Gestion des runners GITLAB`. + +- Vers quel git le runner doit-il pointer => forge.grandlyon.com (GITLAB SYNAAPS) +- Nom du projet git pointé => nom du projet (sert à identifier le runner) +- Token Git => le registration token obtenu sur la forge + - Pour un projet : Settings > CI/CD > Runners > trois petits points à coté de `New project runner` + - Pour un groupe : Build > Runners > trois petits points à coté de `New group runner` + +## Variables sur la forge + +### Token d'accès au container registry + +Pour qu'Openshift puisse lire les images Docker hébergées sur la forge il aura besoin d'un access token avec les droit read_registry et le rôle de Maintainer. + +Ce token a été créé au niveau du [groupe Factory](https://forge.grandlyon.com/groups/web-et-numerique/factory/-/runners) sur la forge et sa valeur est contenue dans la variable `READ_REGISTRY_TOKEN`, accessible aux sous-projets. + +### KUBECONFIG + +Pour que le runner puisse appliquer des déploiements sur un namespace, il lui en faut les droits. Un compte de service nommé `cicd-robot` est créé sur chaque namespace avec le rôle `dock-air-deployer`, ce qui lui donne un certain périmètre d'autorisations. + +Depuis la console openshift, se rendre sur `User Management > ServiceAccounts > cicd-robot et cliquer sur Actions > Download kubeconfig file`. Le contenu de ce fichier pourra être donné au runner pour avoir les mêmes autorisations que le compte `cicd-robot` + +Le contenu de ce fichier pour les namespace cpd-p01 et cpd-r01 sont stockés dans des variables du groupe Factory sur la forge, respectivement `KUBE_CONFIG_CPD_PROD` et `KUBE_CONFIG_CPD_REC` + +## .gitlab-ci.yml + +### Cas simple : une seule branche à déployer + +On écrit en dur le namespace, l'image à utiliser et l'URL de l'application dans les fichiers de config, exemple du `deployment.yml` de la doc self-data : + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: self-data-doc + namespace: ns-cpd-p01-syn +spec: + replicas: 1 + selector: + matchLabels: + app: self-data-doc + template: + metadata: + labels: + app: self-data-doc + spec: + containers: + - name: self-data-doc + image: registry.forge.grandlyon.com/web-et-numerique/factory/llle_project/self-data-technical-doc:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + nodeSelector: + node-role.kubernetes.io/worker: '' + imagePullSecrets: + - name: forge-secret + +``` + +Dans le fichier .gitlab-ci.yml, ajouter un stage deploy après celui de build, puis définir un job comme celui-ci (exemple d'un déploiement en prod sur la branche master): + +```yaml +deploy_master: + stage: deploy + tags: + - ns-cpd-p01-syn + only: + - master + before_script: + - NAMESPACE=ns-cpd-p01-syn + - export KUBECONFIG=$KUBE_CONFIG_CPD_PROD + script: + - oc create secret -n $NAMESPACE docker-registry forge-secret --docker-server=$CI_REGISTRY --docker-username=forge-secret --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f - + - oc apply -f k8s/deployment.yml + - oc apply -f k8s/service.yml + - oc apply -f k8s/route.yml + - oc delete pod -l app=self-data-doc +``` + +Quelques remarques et explications : + +- Le champ `tags` permet de sélectionner le runner à utiliser pour le déploiement (ici: `ns-cpd-p01-syn` pour la PROD) +- la commande `export KUBECONFIG=...` permet de donner les autorisations nécessaires au runner sur le bon namespace selon les variables stockées dans la forge (`$KUBE_CONFIG_CPD_PROD` ou `$KUBE_CONFIG_CPD_REC`) +- la commande `oc create secret ...` créé un secret nommé `forge-secret` dans Openshift basé sur la variable `$READ_REGISTRY_TOKEN` stockée sur la forge pour pouvoir tirer les images +- On utilise `oc apply ...` pour appliquer les différentes parties de l'application + +!!! warning "Cette dernière étape entraîne une interruption de l'application le temps que le nouveau pod soit lancé (quelques secondes à une minute selon les cas)" + - La commande `oc delete pod -l app=self-data-doc` supprime un pod d'un déploiement basé sur le label défini dans son fichier de config. Cela a pour effet de forcer Openshift à rafraîchir l'image utilisée pour ce déploiement. Sans cela, le pod n'est pas mis à jour car le tag de l'image n'a pas changé, ce qui ne provoque pas la mise à jour du pod. + +### Cas plus complexe : deux branches (recette et production) à déployer + +Pour pouvoir paramétrer nos déploiement selon l'environnement ciblé, il faut variabiliser certains éléments dans les fichiers de déploiement. Pour cela on remplace leur valeur par un placeholder compris entre double accolades ex: `{{NAMESPACE}}`. Voici les paramètres à remplacer et leur placeholder associé : + +- namespace sur lequel déployer => `{{NAMESPACE}}` +- tag de l'image à déployer => `{{IMAGE_TAG}}` +- url de l'application => `{{HOSTNAME}}` + +Exemple du `deployment.yml` de landing page de Mes Papiers : + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: mes-papiers-landing-page + namespace: {{NAMESPACE}} +spec: + replicas: 1 + selector: + matchLabels: + app: mes-papiers-landing-page + template: + metadata: + labels: + app: mes-papiers-landing-page + spec: + containers: + - name: mes-papiers-landing-page + image: registry.forge.grandlyon.com/web-et-numerique/factory/ma-bulle/mes-papiers-landing-page:{{IMAGE_TAG}} + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + nodeSelector: + node-role.kubernetes.io/worker: '' + imagePullSecrets: + - name: forge-secret +``` + +Ces placeholders seront remplacés par la commande **sed** par les valeurs correspondantes au moment de la pipeline de déploiement. Il faut mettre à jour le `gitlab-ci.yml` avec les deux jobs suivants : + +```yaml +deploy_rec: + stage: deploy + before_script: + - NAMESPACE=ns-cpd-r01-syn + - export KUBECONFIG=$KUBE_CONFIG_CPD_REC + script: + - find k8s/ -name '*.yml' -exec sed -i "s/{{NAMESPACE}}/$NAMESPACE/g" {} \; + - sed -i "s/{{IMAGE_TAG}}/dev/" ./k8s/deployment.yml + - sed -i "s/{{HOSTNAME}}/mespapiers-rec.apps.grandlyon.com/g" ./k8s/route.yml + + - oc create secret -n $NAMESPACE docker-registry forge-secret --docker-server=$CI_REGISTRY --docker-username=forge-secret --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f - + + - oc apply -f k8s/deployment.yml + - oc apply -f k8s/service.yml + - oc apply -f k8s/route.yml + + - oc delete pod -l app=mes-papiers-landing-page + tags: + - ns-cpd-r01-syn + only: + - dev + +deploy_prod: + stage: deploy + before_script: + - NAMESPACE=ns-cpd-p01-syn + - export KUBECONFIG=$KUBE_CONFIG_CPD_PROD + script: + - find k8s/ -name '*.yml' -exec sed -i "s/{{NAMESPACE}}/$NAMESPACE/g" {} \; + - sed -i "s/{{IMAGE_TAG}}/main/" ./k8s/deployment.yml + - sed -i "s/{{HOSTNAME}}/mespapiers.apps.grandlyon.com/g" ./k8s/route.yml + + - oc create secret -n $NAMESPACE docker-registry forge-secret --docker-server=$CI_REGISTRY --docker-username=forge-secret --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f - + + - oc apply -f k8s/deployment.yml + - oc apply -f k8s/service.yml + - oc apply -f k8s/route.yml + + - oc delete pod -l app=mes-papiers-landing-page + tags: + - ns-cpd-p01-syn + only: + - main +``` + +Quelques remarques et explications supplémentaires par rapport au cas simple : + +- On utilise le bon namespace (**r**01-syn vs **p**01-syn) et les bonnes variables selon l'environnement ciblé (**dev** vs **main**) +- La commande `find k8s/ -name '*.yml' -exec sed -i "s/{{NAMESPACE}}/$NAMESPACE/g" {} \;` trouve toutes les occurrences du placeholder `{{NAMESPACE}}` dans les fichiers compris dans le dossier `k8s` et les remplace par la variable `$NAMESPACE` définie dans le `before_script` +- La commande `sed -i "s/{{IMAGE_TAG}}/main/" ./k8s/deployment.yml` remplace l'occurrence du placeholder `{{IMAGE_TAG}}` dans le fichier `k8s/deployment.yml` et la remplace par "main" +- La commande `sed -i "s/{{HOSTNAME}}/mespapiers.apps.grandlyon.com/g" ./k8s/route.yml` remplace l'occurrence du placeholder `{{HOSTNAME}}` dans le fichier `k8s/route.yml` et la remplace par l’environnement cible : "mespapiers.apps.grandlyon.com" vs "mespapiers**-rec**.apps.grandlyon.com" diff --git a/docs/openshift/index.md b/docs/openshift/index.md new file mode 100644 index 0000000000000000000000000000000000000000..d0644539b524f8bba563a39a25fcf3cc1013f667 --- /dev/null +++ b/docs/openshift/index.md @@ -0,0 +1,30 @@ +# Présentation + +Plusieurs projets développés par la factory sont déployés sur le cluster Openshift hébergé par Synaaps. La création et l'administration de namespaces passent par le [Manager Openshift Synaaps](https://manager.apps.grandlyon.com/). En cas de besoin, contacter [Pierre-Eliott Bressand](mailto:ext.solutec.pbressand@grandlyon.com) ! + +Un guide complet est disponible sur <https://guide.air.grandlyon.fr> (accessible uniquement sur le réseau Mercure) avec une vidéo-tutoriel expliquant tout le parcours de création de namespace, création d'un projet sur la forge, des fichiers de configuration des déploiements YAML et l'installation du déploiement continu automatisé. + +## Namespaces utilisés + +### Ecolyo Agent + +Deux namespaces sont dédiés à Ecolyo-Agent, le backoffice d'Ecolyo : + +| Environnement | Namespace | +| ------------- | -------------------- | +| Recette | ns-ecolyo-bo-r01-syn | +| Production | ns-ecolyo-bo-p01-syn | + +### Self Data + +Deux namespaces sont dédiés plus généralement au self-data, on y retrouve les landing page pour Mes Papiers et Ma Bulle, ainsi que cette documentation : + +| Environnement | Namespace | +| ------------- | -------------- | +| Recette | ns-cpd-r01-syn | +| Production | ns-cpd-p01-syn | + +## Fichiers de déploiement + +Tous les fichiers de déploiement sont regroupés dans un dossier `k8s` (c'est un raccourci pour Kubernetes). +Il s'agit de fichiers au format `.yaml` décrivant les différentes parties nécessaires au déploiement d'un application (pods, services, routes, etc...). diff --git a/mkdocs.yml b/mkdocs.yml index 15472df619ac929fae9769d43c47ee9bce9dc4c1..b55d7553f5c6387e99b1d9ba2b362cd5c0111654 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -158,3 +158,6 @@ nav: - Use cases: - Enedis [DEPRECATED]: proxy/use_cases/enedis.md - Grdf Adict: proxy/use_cases/grdfadict.md + - Openshift: + - Présentation: openshift/index.md + - CI/CD: openshift/cicd.md