10 unités restantes + navigation complète (14 unités)
parent
8583bc2634
commit
dcfea61848
11 changed files with 714 additions and 14 deletions
71
Bases-de-données.md
Normal file
71
Bases-de-données.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Bases de données
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Une **base de données relationnelle** stocke des données en **tables** (lignes/colonnes) reliées.
|
||||
Modèle **client-serveur** : le serveur (PostgreSQL) détient les données ; les applications s'y
|
||||
**connectent** par le réseau, avec un **compte** et un **mot de passe**, sur une **base** donnée.
|
||||
|
||||
**Schéma** = la structure (tables, contraintes). **ACID** = les garanties de fiabilité des
|
||||
transactions (Atomicité, Cohérence, Isolation, Durabilité). **Rôles/permissions** = qui peut lire/écrire.
|
||||
|
||||
Bonne pratique : **une base + un compte dédiés par application** (isolation) — pas un compte
|
||||
tout-puissant partagé.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
`serveur_postgresql` (nœud `data-sql`) est le serveur partagé. L'élégance : un **registre**
|
||||
déclaratif des bases (`plan/bases-donnees.yml`). Chaque entrée dit *quelle base, quel compte, quel
|
||||
secret, pour quel consommateur* :
|
||||
|
||||
```
|
||||
Registre ──> PostgreSQL crée la base + le compte propriétaire
|
||||
──> le rôle consommateur (Keycloak, Forgejo, Icinga…) LIT la même
|
||||
entrée et bâtit sa connexion — via resoudre_base
|
||||
```
|
||||
|
||||
Le **secret** vit dans la **voûte** (Ansible Vault), déréférencé **au déploiement**, jamais en clair
|
||||
dans le plan. C'est une **liaison** *app → base*, de modalité **requise** (Keycloak sans sa base ne
|
||||
démarre pas). Consommateurs prouvés : Keycloak, Forgejo, IcingaDB.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| PostgreSQL | MySQL/MariaDB · SQLite · Oracle · SQL Server |
|
||||
| une base/compte par app | pratique **universelle** d'isolation |
|
||||
| secret en voûte | Vault · SOPS · secrets managers cloud |
|
||||
|
||||
Tu as appris **le modèle client-serveur, le schéma, l'isolation par app, les secrets** — pas
|
||||
« PostgreSQL ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Liste les bases** (sur data-sql-01) :
|
||||
```bash
|
||||
sudo -u postgres psql -c '\l' # keycloak, forgejo, icingadb…
|
||||
sudo -u postgres psql -c '\du' # les comptes propriétaires
|
||||
```
|
||||
2. **Vois l'isolation.** Chaque app a **sa** base et **son** compte — pas de compte partagé.
|
||||
3. **Suis une liaison.** Ouvre `plan/bases-donnees.yml` : l'entrée `keycloak` (serveur, base,
|
||||
propriétaire, secret) est *exactement* ce que le rôle `serveur_keycloak` va lire pour se connecter.
|
||||
4. **Casse & répare.** Change le mot de passe d'un compte dans PostgreSQL (garde l'ancien !) sans
|
||||
mettre à jour la voûte : l'app **ne se connecte plus**. Restaure : ça repart. Tu *sens* que la
|
||||
connexion = *identité + secret cohérents des deux côtés*.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôle : `roles/serveur_postgresql` ; résolveur partagé : `roles/resoudre_base`.
|
||||
- Le registre : `instance/plan/bases-donnees.yml` ; validation : `scripts/bases_donnees.py verifier`.
|
||||
- Sauvegarde (Tier 1, `pg_dumpall`) : unité **Sauvegardes**.
|
||||
64
Cache.md
Normal file
64
Cache.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Cache
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Un **cache** garde en **mémoire** (rapide) des données coûteuses à recalculer ou à relire (disque,
|
||||
base, réseau). Modèle **clé-valeur** : `SET clé valeur`, `GET clé`.
|
||||
|
||||
Comme la mémoire est limitée :
|
||||
- **éviction** — quand c'est plein, on jette (souvent **LRU** : *Least Recently Used*) ;
|
||||
- **TTL** — une valeur peut **expirer** après un délai.
|
||||
|
||||
Règle d'or : **le cache n'est PAS la source de vérité**. Il est **éphémère** — on doit pouvoir le
|
||||
**perdre sans drame** (la vraie donnée est ailleurs). Le vider = plus lent un instant, jamais faux.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
`serveur_redis` (nœud `data-sql`) fournit un cache réseau. Points notables :
|
||||
- **authentification obligatoire** (`requirepass`, secret en voûte) — il est exposé sur le réseau
|
||||
interne, donc on ne laisse jamais un cache ouvert ;
|
||||
- **`maxmemory` + politique `allkeys-lru`** — borne la mémoire, évince en LRU ;
|
||||
- Icinga a son **propre** Redis dédié (`icingadb-redis`) — un cache par besoin, pas un fourre-tout.
|
||||
|
||||
Conséquence directe : Redis est **Tier 3** (éphémère) — **on ne le sauvegarde pas**. C'est le
|
||||
pendant parfait de l'unité *Sauvegardes* : on protège la donnée d'état, **pas** le cache.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Redis | Memcached · Valkey · KeyDB · caches cloud (ElastiCache…) |
|
||||
| LRU + TTL | mécanismes **universels** d'éviction/expiration |
|
||||
| cache éphémère ≠ source de vérité | principe valable partout |
|
||||
|
||||
Tu as appris **le cache clé-valeur, l'éviction LRU, le TTL, l'éphémère** — pas « Redis ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Écris/lis avec authentification** (sur data-sql-01) :
|
||||
```bash
|
||||
redis-cli -a "<mot de passe vault_redis>" SET essai:1 bonjour
|
||||
redis-cli -a "<mot de passe vault_redis>" GET essai:1
|
||||
```
|
||||
2. **Teste le TTL** : `redis-cli -a … SET court 1 EX 5` puis `GET court` avant/après 5 s — il **expire**.
|
||||
3. **Vois la borne** : `redis-cli -a … CONFIG GET maxmemory` et `… maxmemory-policy` (LRU).
|
||||
4. **Casse & répare.** Interroge **sans** mot de passe : `redis-cli GET essai:1` → **`NOAUTH`**
|
||||
(refusé). Puis vide le cache (`FLUSHALL`) : rien ne casse dans l'écosystème — la vraie donnée est
|
||||
en base. Tu *sens* qu'un cache est **jetable**.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôle : `roles/serveur_redis`.
|
||||
- Redis dédié d'Icinga : `roles/serveur_icinga` (`icingadb-redis`).
|
||||
- Tiers de sauvegarde (Redis = Tier 3, non sauvegardé) : unité **Sauvegardes**.
|
||||
72
Courriel.md
Normal file
72
Courriel.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Courriel (SMTP / IMAP)
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Le courriel, c'est **trois rôles** distincts (souvent confondus) :
|
||||
- **MTA** (*Mail Transfer Agent*) : transporte le courrier entre serveurs — protocole **SMTP** (`:25`).
|
||||
- **MDA** (*Mail Delivery Agent*) : dépose le courrier dans la **boîte** et la sert — **IMAP** (`:993`).
|
||||
- **MUA** (*Mail User Agent*) : ton client (Thunderbird, l'appli).
|
||||
|
||||
Deux SMTP différents :
|
||||
- **`:25`** = relais **serveur↔serveur** (pas d'authentification par mot de passe).
|
||||
- **`:587` (soumission)** = un **client authentifié** *envoie* son courrier (**SMTP AUTH + STARTTLS**).
|
||||
|
||||
**LMTP** = remise **locale** du MTA vers le magasin. **Déliverabilité** (vers l'externe) = un tout
|
||||
autre problème : **DKIM** (signer), **SPF**, **DMARC**, réputation IP.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
| Pièce | Rôle |
|
||||
|---|---|
|
||||
| **Postfix** (`serveur_postfix`, edge-mta) | le **MTA** : reçoit `:25`, valide le destinataire **contre LDAP**, remet en **LMTP**. |
|
||||
| **Dovecot** (`serveur_dovecot`, infra-mail) | le **MDA/magasin** : boîtes `/var/vmail`, **IMAP** `:993`. |
|
||||
| **rspamd** (`serveur_rspamd`) | antispam + **signature DKIM**. |
|
||||
|
||||
La **boucle souveraine**, prouvée de bout en bout :
|
||||
```
|
||||
Reçevoir : … ──> Postfix :25 ──> validation LDAP ──> LMTP ──> Dovecot ──> IMAP
|
||||
Envoyer : client ──> :587 (AUTH+STARTTLS) ──> SASL Dovecot/LDAP ──> Postfix ──> remise
|
||||
```
|
||||
Une **identité** (`testmail`, le mot de passe LDAP) sert IMAP *et* la soumission. Le tout **interne,
|
||||
chiffré, sans jamais toucher Internet** (l'envoi vers l'externe = Étape B, déliverabilité).
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Postfix / Dovecot | Exim · Sendmail · Exchange · tout serveur SMTP/IMAP |
|
||||
| SMTP/IMAP/LMTP, `:587` | **protocoles standards** — identiques partout |
|
||||
| DKIM/SPF/DMARC | universels pour la déliverabilité |
|
||||
|
||||
Tu as appris **MTA/MDA/MUA, SMTP vs soumission, IMAP, la déliverabilité** — pas « Postfix ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Envoie via la soumission `:587`** (client authentifié) :
|
||||
```bash
|
||||
swaks --server edge-mta-01.lab.chezlepro.internal:587 --tls \
|
||||
--auth LOGIN --auth-user testmail@lab.chezlepro.internal --auth-password MotDePasseTest123 \
|
||||
--from testmail@lab.chezlepro.internal --to testmail@lab.chezlepro.internal --header 'Subject: essai'
|
||||
```
|
||||
`235 Authentication successful` puis `250 queued` = ① en action.
|
||||
2. **Lis la boîte** (le MDA) : `doveadm search -u testmail mailbox INBOX all | wc -l` sur infra-mail-01.
|
||||
3. **Casse & répare.** Coupe l'annuaire (arrête OpenLDAP), renvoie un courriel : Postfix **rejette le
|
||||
destinataire** (il ne peut plus valider en LDAP). Rallume OpenLDAP : ça repart. Tu *sens* la
|
||||
dépendance **requise** MTA → annuaire.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôles : `roles/serveur_postfix`, `roles/serveur_dovecot`, `roles/serveur_rspamd`.
|
||||
- Conception + Étape B (déliverabilité publique) : `docs/courriel-conception.md`.
|
||||
- Notifications système des nœuds : `client_smtp` (relais vers le MTA).
|
||||
68
Infra-as-Code-et-idempotence.md
Normal file
68
Infra-as-Code-et-idempotence.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Infra as Code & idempotence
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
**Infra as Code (IaC)** : décrire l'infrastructure **dans du code** (versionné, revu, reproductible)
|
||||
plutôt qu'à la main. Le serveur devient le **résultat d'un fichier**, pas d'une suite de clics oubliés.
|
||||
|
||||
**Déclaratif vs impératif** :
|
||||
- *impératif* = « fais ceci, puis cela » (une recette d'étapes) ;
|
||||
- *déclaratif* = « voici l'**état voulu** » (le moteur trouve comment y arriver).
|
||||
|
||||
**Idempotence** : appliquer la **même** description **N fois** donne le **même** résultat. La 1ʳᵉ
|
||||
exécution change des choses ; les suivantes ne changent **rien** (`changed=0`). C'est ce qui rend
|
||||
l'IaC **sûre à rejouer**.
|
||||
|
||||
**Modèle plan → apply** : on décrit (plan), on **prévisualise** (dry-run), on **applique**. Tout est
|
||||
en **contrôle de version** (git), donc auditable et réversible.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
- **Ansible** = le moteur **déclaratif** (des *rôles* décrivant l'état voulu, idempotents).
|
||||
- Le **plan** (`serveurs.yml`, `applications.yml`, `bases-donnees.yml`) décrit *quoi* déployer.
|
||||
- `make instancier` **génère** l'inventaire statique depuis le plan.
|
||||
- `make deployer` applique les rôles ; le `Vérifier` (dry-run) **prévisualise** d'abord.
|
||||
- Tout vit dans **git** (ce dépôt) — reproductible, revu, réversible.
|
||||
|
||||
Preuve d'idempotence, vue partout cette session : redéployer un rôle déjà en place →
|
||||
**`changed=0`**. Et un refactor « neutre » (ex. le binding annuaire) → `changed=0` aussi : *même
|
||||
état voulu = aucune modification*.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Ansible | Terraform · Puppet · Chef · SaltStack · OpenTofu |
|
||||
| plan → dry-run → apply | `terraform plan/apply`, tout workflow IaC |
|
||||
| idempotence | **propriété fondamentale** de toute IaC sérieuse |
|
||||
|
||||
Tu as appris **le déclaratif, l'idempotence, plan→apply, l'infra versionnée** — pas « Ansible ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Sens l'idempotence.** Redéploie un rôle déjà en place (ex. via la GUI ou
|
||||
`make deployer HOTE=…`) : la 2ᵉ fois, **`changed=0`**. Rien à faire = rien n'est touché.
|
||||
2. **Le flux déclaratif.** Édite le plan (un serveur dans la GUI), `⚙ Appliquer le plan`
|
||||
(instancier), puis `Vérifier` (dry-run) : tu **prévisualises** avant d'appliquer.
|
||||
3. **La réversibilité.** `git diff` / `git checkout` sur le plan : l'état est **du code**, donc
|
||||
annulable.
|
||||
4. **Casse & répare.** Modifie à la main un fichier géré par un rôle (ex. un `.conf`), puis
|
||||
redéploie : Ansible **rétablit l'état voulu** (le code gagne sur la dérive manuelle). Tu *sens*
|
||||
que la source de vérité, c'est **le code**.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Le flux : `make instancier` → `make instancier-appliquer` → `make deployer` (ou la GUI).
|
||||
- Le plan : `instance/plan/` ; les rôles : `roles/` ; l'autorité : `AGENTS.md`.
|
||||
- Relations déclaratives entre entités : unité **Liaisons (bindings)**.
|
||||
79
Liaisons-bindings.md
Normal file
79
Liaisons-bindings.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Liaisons (bindings)
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Un système réel n'est pas fait de pièces isolées, mais de **relations** : cette app *utilise* cette
|
||||
base, ce serveur *fait confiance* à cette AC, ce nœud *envoie ses logs* à ce collecteur.
|
||||
|
||||
Deux façons de câbler ces relations :
|
||||
- **En dur** — recopier l'adresse/le nom dans chaque config. Fragile : déplacer une pièce oblige à
|
||||
éditer partout, et ça casse la portabilité.
|
||||
- **En liaisons déclaratives** — on **déclare** « A est lié à B », et le **moteur résout** l'adresse
|
||||
concrète au bon moment. Déplacer B ? On ne touche qu'un endroit.
|
||||
|
||||
> **Analogie NetScaler (Citrix ADC)** : tu *bind* un *service* à un *vserver*, une *policy* à un
|
||||
> *vserver*, un *monitor* à un *service*. Tu ne codes pas des IP en dur — tu **relies des entités**,
|
||||
> et l'appareil fait le reste. Les liaisons de Set-OPS, c'est exactement ce modèle.
|
||||
|
||||
Deux **axes** pour classer une liaison (indépendants) :
|
||||
- **Niveau** : *app→app/base/domaine* (`liens`) ou *nœud→service de flotte* (`intégrations`).
|
||||
- **Modalité** : **requise** (constitutive — sans elle, ça ne s'instancie pas) ou **optionnelle**
|
||||
(élective — un choix, l'absence est légitime).
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
| Type | Où | Résolu en | Exemple |
|
||||
|---|---|---|---|
|
||||
| **`liens`** | `applications.yml` | **config** (host_vars, lookups) | Forgejo → sa base ; app → domaine exposé |
|
||||
| **`intégrations`** | `serveurs.yml` | **groupe + agent client** | nœud → PKI, sauvegarde, métriques… |
|
||||
|
||||
Les **résolveurs partagés** font le pont : `resoudre_base` (app→base) et `resoudre_annuaire`
|
||||
(app→annuaire) lisent un **registre** et bâtissent la connexion — le secret restant déréférencé
|
||||
**dans le rôle**, jamais en clair.
|
||||
|
||||
La **modalité** structure la robustesse : une liaison **requise** absente → le moteur **refuse
|
||||
d'instancier** (ex. une base sans serveur SQL). Une **optionnelle** absente → silence (ex. un nœud
|
||||
sans `client_journal` marche très bien).
|
||||
|
||||
C'est **le** concept de Set-OPS : *tu déclares les liaisons, le moteur câble.*
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| liens/intégrations déclaratifs | **NetScaler bindings** · références de ressources Terraform |
|
||||
| service ↔ backend | Kubernetes : Service↔Pods, Ingress↔Service |
|
||||
| requis vs optionnel | dépendances *hard* vs *soft* (partout) |
|
||||
|
||||
Tu as appris **la relation déclarative, la résolution par un moteur, requis vs optionnel** — pas un
|
||||
produit. C'est un **modèle mental** qui vaut de NetScaler à Kubernetes.
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Lis une liaison.** Ouvre `instance/plan/applications.yml` : une app avec `expose:` (liaison
|
||||
*app→domaine*), et `serveurs.yml` : un nœud avec `integrations:` (liaison *nœud→service*).
|
||||
2. **Vois-la se résoudre.** Après `make instancier`, regarde l'inventaire généré : la cible est
|
||||
devenue une **valeur concrète** (FQDN, groupe) — le moteur a câblé.
|
||||
3. **Requise vs optionnelle.** Compare : retirer `client_journal` d'un nœud → aucun problème
|
||||
(optionnelle). Déclarer une base **sans** serveur → `make instancier`/la validation **échoue**
|
||||
(requise). Tu *sens* la différence de modalité.
|
||||
4. **Casse & répare.** Casse une liaison requise (ex. réfère une base à un serveur inexistant),
|
||||
relance l'instanciation : **échec clair** *avant* tout déploiement. Corrige : ça passe. Le moteur
|
||||
attrape le câblage manquant à ta place.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Conception + **taxonomie (niveau × modalité)** : `docs/bindings-conception.md` (§11).
|
||||
- Résolveurs : `roles/resoudre_base`, `roles/resoudre_annuaire` ; registres : `instance/plan/`.
|
||||
- Toutes les autres unités sont, au fond, des liaisons en action.
|
||||
68
Métriques-et-journaux.md
Normal file
68
Métriques-et-journaux.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Métriques & journaux
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
**Observer** un système, c'est trois familles de données :
|
||||
- **Métriques** : des **nombres dans le temps** (CPU, mémoire, requêtes/s) — des *séries temporelles*.
|
||||
- **Journaux (logs)** : des **événements textuels** datés (« service démarré », « erreur X »).
|
||||
- *(Traces : le parcours d'une requête — hors périmètre ici.)*
|
||||
|
||||
Deux **modèles de collecte** opposés, à bien distinguer :
|
||||
- **Pull / scrape** : le collecteur **va chercher** les métriques chez chaque nœud (qui les *expose*).
|
||||
- **Push / ship** : chaque nœud **envoie** ses journaux vers un collecteur central.
|
||||
|
||||
Le motif **agent/exporter** : sur chaque machine, un petit agent expose des métriques (*exporter*)
|
||||
ou expédie des logs (*shipper*). Le serveur central agrège ; un tableau de bord **visualise**.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
| Pièce | Modèle | Rôle |
|
||||
|---|---|---|
|
||||
| **Prometheus** (`serveur_prometheus`) | **PULL** | scrape `node_exporter` (installé par `client_metrique`) sur chaque nœud, port `:9100`. |
|
||||
| **Loki** (`serveur_loki`) | **PUSH** | reçoit les journaux `journald` expédiés par `client_journal`. |
|
||||
| **Grafana** (`serveur_grafana`) | — | tableaux de bord au-dessus des **deux** (au SSO). |
|
||||
|
||||
Le point-clé prouvé cette session : un serveur d'observabilité **sans agents** ne voit que
|
||||
lui-même. En déployant `client_metrique`/`client_journal` (des **liaisons nœud, optionnelles**),
|
||||
Grafana voit **toute la flotte**. *Serveur ≠ agent* : les deux sont nécessaires.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Prometheus (pull) | tout Prometheus, VictoriaMetrics, la logique **scrape** |
|
||||
| Loki (push) | ELK/Elasticsearch, Graylog, la logique **ship** |
|
||||
| Grafana | Kibana, Datadog, Grafana Cloud |
|
||||
| exporter/shipper | motif **universel** (node_exporter, Fluent Bit, Vector…) |
|
||||
|
||||
Tu as appris **métriques vs logs, pull vs push, le motif agent** — pas « Prometheus ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Interroge les métriques** (sur obs-01) — combien de nœuds scrapés, tous **UP** ?
|
||||
```bash
|
||||
curl -s 'http://localhost:9090/api/v1/query?query=up{job="node"}' | python3 -m json.tool | grep -E 'instance|"1"'
|
||||
```
|
||||
2. **Vois les journaux** : `curl -s http://localhost:3100/loki/api/v1/label/host/values` → les nœuds
|
||||
qui expédient leurs logs.
|
||||
3. **Ouvre Grafana** (`https://grafana.lab.chezlepro.internal`) — métriques *et* logs au même endroit.
|
||||
4. **Casse & répare.** Arrête `prometheus-node-exporter` sur un nœud : dans Prometheus, sa cible passe
|
||||
**`up=0`** (DOWN). Redémarre : elle repasse UP. Tu *sens* que c'est **l'agent** qui nourrit le
|
||||
serveur (modèle pull).
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôles : `roles/serveur_prometheus`, `roles/serveur_loki`, `roles/serveur_grafana`.
|
||||
- Agents : `roles/client_metrique` (node_exporter), `roles/client_journal` (→ Loki).
|
||||
- Ces agents sont des **liaisons optionnelles** : unité **Liaisons**.
|
||||
69
Reverse-proxy-et-TLS.md
Normal file
69
Reverse-proxy-et-TLS.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Reverse-proxy & TLS
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Un **reverse-proxy** est un **point d'entrée unique** devant plusieurs services. Il :
|
||||
- **route par nom** (`grafana.…` → tel backend, `forge.…` → tel autre) — via l'en-tête `Host` / **SNI** ;
|
||||
- **termine le TLS** : il porte les certificats, parle HTTPS au client et (souvent) HTTP en interne ;
|
||||
- centralise journaux, limites de débit, en-têtes de sécurité (et un **WAF** éventuel).
|
||||
|
||||
**Terminaison TLS** = le chiffrement s'arrête au proxy ; derrière, le réseau interne est de confiance.
|
||||
Un seul endroit gère les certificats → simple et cohérent.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
`serveur_nginx` déployé sur l'**edge** (`infra-edge`) est le reverse-proxy. Le point élégant :
|
||||
l'**exposition est auto-dérivée**. Déclarer `expose: [icinga.lab.chezlepro.internal]` sur une app
|
||||
génère **tout** :
|
||||
|
||||
```
|
||||
expose ──> vhost nginx (route par nom)
|
||||
──> SAN ajouté au certificat de l'edge (step-ca)
|
||||
──> enregistrement A dans PowerDNS
|
||||
──> alias plancher /etc/hosts
|
||||
```
|
||||
|
||||
Le client parle **HTTPS vérifié** à l'edge ; l'edge relaie en **HTTP** au backend interne (Grafana,
|
||||
Forgejo, Keycloak…). Une seule ligne déclarative, toute la chaîne câblée. C'est une **liaison**
|
||||
(*app → domaine*) — voir l'unité *Liaisons*.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| nginx reverse-proxy | HAProxy · Traefik · Caddy · Apache · Envoy |
|
||||
| edge + terminaison TLS | tout load-balancer / ingress cloud, un NetScaler ADC |
|
||||
| routage par SNI/Host | mécanisme **standard** de tout proxy HTTP |
|
||||
|
||||
Tu as appris **le reverse-proxy, le routage par nom, la terminaison TLS** — pas « nginx ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Route par nom.** Deux noms, un seul edge (`192.168.15.21`) :
|
||||
```bash
|
||||
curl -sI --resolve grafana.lab.chezlepro.internal:443:192.168.15.21 \
|
||||
--cacert /etc/step/certs/root_ca.crt https://grafana.lab.chezlepro.internal/ | head -1
|
||||
```
|
||||
Change `grafana` en `forge` : même IP, **backend différent**. C'est le routage par SNI.
|
||||
2. **Vois la terminaison TLS.** Le certificat présenté est celui de l'**edge** (avec les SAN des
|
||||
exposés) : `openssl s_client -connect 192.168.15.21:443 -servername grafana.lab… | openssl x509 -noout -text | grep -A1 'Subject Alternative'`.
|
||||
3. **Casse & répare.** Arrête le backend (ex. `systemctl stop grafana-server` sur obs-01) et rouvre
|
||||
Grafana : l'edge répond **502 Bad Gateway** (le proxy est là, le service non). Redémarre : ça
|
||||
remarche. Tu distingues **le proxy** de **ce qu'il sert**.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôle : `roles/serveur_nginx` ; les sites se déclarent côté nginx (`serveur_nginx_sites`).
|
||||
- Machinerie d'exposition : `expositions_des_applications` (dérive vhost + SAN + A + plancher).
|
||||
- Frontière **publique** (au-delà de l'edge interne) : `docs/` + Étape B (OPNsense).
|
||||
65
Supervision-et-impact.md
Normal file
65
Supervision-et-impact.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Supervision & impact
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
**Observabilité** (métriques/logs) = **passive** : on regarde des données. **Supervision** =
|
||||
**active** : le système **fait des tests** (« le port 443 répond-il ? le disque est-il plein ? »),
|
||||
tient un **état** (OK / WARNING / CRITICAL) et **alerte** quand ça se dégrade.
|
||||
|
||||
Distinction utile : Grafana te *montre* des tendances ; un moteur de supervision *décide* qu'un
|
||||
service est en panne et *prévient*. Complémentaires, pas interchangeables.
|
||||
|
||||
**Modélisation d'impact métier** (BPM) : agréger des checks techniques en **services de haut
|
||||
niveau**. « Le service *Courriel* est-il sain ? » = (Postfix **ET** Dovecot **ET** l'annuaire).
|
||||
On raisonne en **impact**, pas en cases isolées.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
La pile Icinga, en trois étages :
|
||||
|
||||
| Étage | Pièce | Rôle |
|
||||
|---|---|---|
|
||||
| **Moteur** | `serveur_icinga` (icinga2 + IcingaDB) | exécute les **checks**, tient l'**état**, alerte. |
|
||||
| **UI** | `serveur_icingaweb2` | l'interface (états, acquittements, downtimes), **au SSO**. |
|
||||
| **Impact** | module **BPM** | des **processus métier** qui roulent la santé de plusieurs checks en un état. |
|
||||
|
||||
Ce que Grafana ne fait **pas** : le BPM. « Grafana peut-il remplacer le BPM ? » → **non** : l'un
|
||||
*visualise des mesures*, l'autre *modélise l'impact métier*. On veut **les deux**.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Icinga | Nagios · Zabbix · Checkmk · Sensu |
|
||||
| checks actifs + alerting | modèle **universel** de la supervision |
|
||||
| BPM / impact | *business service monitoring* (concept répandu) |
|
||||
|
||||
Tu as appris **supervision active vs observabilité passive, l'état, l'alerting, l'impact** — pas
|
||||
« Icinga ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Ouvre Icinga Web 2** (`https://icinga.lab.chezlepro.internal`, via le SSO) : la liste des hôtes
|
||||
et services **supervisés**, avec leur **état** (vert/jaune/rouge).
|
||||
2. **Vois l'impact.** Menu *Business Processes* → « **Supervision Chezlepro** » : un processus qui
|
||||
**agrège** des checks (load, procs, ping…) en un état roulé. C'est l'impact, pas une case.
|
||||
3. **Casse & répare.** Provoque l'échec d'un check (ex. arrête un service surveillé) : l'état passe
|
||||
**CRITICAL**, et le **processus BPM** qui en dépend **rougit** (l'impact remonte). Répare : tout
|
||||
reverdit. Tu *sens* la différence entre *mesurer* et *superviser/alerter*.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôles : `roles/serveur_icinga` (moteur), `roles/serveur_icingaweb2` (UI + module BPM).
|
||||
- SSO devant Icinga Web : `roles/serveur_oauth2_proxy` (passerelle) — unité **Identité & SSO**.
|
||||
- Complément visuel : unité **Métriques & journaux** (Grafana).
|
||||
75
Sécurité-et-durcissement.md
Normal file
75
Sécurité-et-durcissement.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Sécurité & durcissement
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
Sécuriser un système, ce sont quelques principes qui se combinent :
|
||||
- **Défense en profondeur** : plusieurs couches — si l'une cède, les autres tiennent.
|
||||
- **Moindre privilège** : chacun (compte, service) n'a **que** les droits nécessaires.
|
||||
- **Réduction de la surface d'attaque** : moins de services exposés = moins de portes.
|
||||
- **Contrôle d'accès obligatoire (MAC)** : le noyau confine chaque programme (AppArmor/SELinux).
|
||||
- **Audit** : tracer les événements sensibles pour pouvoir enquêter.
|
||||
- **Anti-force-brute** : bloquer les tentatives répétées (fail2ban).
|
||||
- **Pare-feu** : filtrer le trafic réseau.
|
||||
- **Mises à jour** : combler les failles connues, automatiquement.
|
||||
|
||||
Aucune de ces couches ne suffit seule. Ensemble, elles rendent l'intrusion **coûteuse**.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
Le **durcissement fait partie du socle** — il tourne sur **chaque** nœud (via `serveur_durci`),
|
||||
pas en option :
|
||||
|
||||
| Couche | Rôle Set-OPS |
|
||||
|---|---|
|
||||
| MAC | `apparmor` |
|
||||
| Audit | `auditd` |
|
||||
| Anti-force-brute SSH | `fail2ban_ssh` |
|
||||
| Durcissement noyau | `sysctl_hardening` |
|
||||
| Pare-feu | `nftables_baseline` (*installé et préparé, désactivé par défaut*) |
|
||||
| Mises à jour | `unattended_upgrades` |
|
||||
| SSH | `ssh_baseline` + `ssh_hardening` (clé d'abord, `PermitRootLogin no`…) |
|
||||
| Moindre privilège | compte technique `ansible` + `sudo_ansible` (pas de root direct) |
|
||||
|
||||
Nuance importante : le **pare-feu** est *préparé mais pas activé* dans le template — on l'active sur
|
||||
un **clone/serveur final** avec des règles adaptées à son rôle (couper l'accès à l'aveugle = un
|
||||
risque). Prudence par conception.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| AppArmor | SELinux · les *security modules* Linux |
|
||||
| fail2ban / auditd / sysctl | outils **standards** de tout durcissement Linux |
|
||||
| démarche par couches | **CIS Benchmarks**, ANSSI, guides d'OS — mêmes principes |
|
||||
|
||||
Tu as appris **la défense en profondeur, le moindre privilège, MAC, l'audit** — pas « AppArmor ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Constate les couches** (sur n'importe quel nœud) :
|
||||
```bash
|
||||
aa-status | head # AppArmor : profils chargés
|
||||
systemctl is-active auditd fail2ban
|
||||
sysctl net.ipv4.conf.all.rp_filter # un durcissement noyau parmi d'autres
|
||||
```
|
||||
2. **Moindre privilège** : `PermitRootLogin` est à `no`, l'accès se fait par le compte `ansible` +
|
||||
clé SSH. Vérifie : `sshd -T | grep -E 'permitrootlogin|passwordauthentication'`.
|
||||
3. **Casse & répare (avec prudence, en lab).** Assouplis **un** réglage sysctl, observe, puis
|
||||
**remets-le**. Tu *sens* que chaque ligne de durcissement ferme une porte précise.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôles du socle durci : `roles/apparmor`, `auditd`, `fail2ban_ssh`, `sysctl_hardening`,
|
||||
`nftables_baseline`, `ssh_hardening`, `unattended_upgrades`…
|
||||
- Actions destructives (SSH, pare-feu) exigent une **confirmation explicite** : voir `CLAUDE.md`/`AGENTS.md`.
|
||||
69
Virtualisation-et-clonage.md
Normal file
69
Virtualisation-et-clonage.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Virtualisation & clonage
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
La **virtualisation** fait tourner plusieurs **machines virtuelles (VM)** — chacune avec son OS —
|
||||
sur un seul serveur physique (l'**hyperviseur**). Isolation, densité, souplesse.
|
||||
|
||||
**Image / golden template** : au lieu de réinstaller chaque VM, on prépare **une** image de
|
||||
référence, propre et durcie, puis on la **clone**. Rapide et **reproductible**.
|
||||
|
||||
**cloud-init** : au premier démarrage d'un clone, il lui donne son **identité initiale** (nom d'hôte,
|
||||
IP, clé SSH, agrandissement du disque). C'est *l'amorçage*, pas la configuration complète.
|
||||
|
||||
Idée-force : la VM devient **jetable/reconstructible**. Ce qui est précieux, c'est la **donnée**
|
||||
(voir *Sauvegardes*), pas la machine.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait
|
||||
|
||||
- **Proxmox** = l'hyperviseur (cluster).
|
||||
- Un **golden template** (`basiqueChezlepro`) : Debian minimal, durci, avec le compte technique
|
||||
`ansible`, qemu-guest-agent, cloud-init… — préparé **une fois**.
|
||||
- Chaque nœud = un **clone** du template. `cloud-init` pose l'identité (hostname, IP dérivée de la
|
||||
nomenclature, clé SSH).
|
||||
- **Puis** Set-OPS/Ansible fait la **vraie** configuration (les rôles).
|
||||
|
||||
Séparation nette, à retenir :
|
||||
```
|
||||
Proxmox + cloud-init ──> identité initiale de la VM
|
||||
Set-OPS + Ansible ──> configuration réelle du serveur
|
||||
```
|
||||
C'est *pour ça* que l'infra est reconstructible : cloner + reconfigurer = quelques minutes.
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| Proxmox (KVM) | VMware · Hyper-V · KVM/libvirt · nuage (EC2, GCE…) |
|
||||
| golden template | AMI, image cloud, **Packer** |
|
||||
| cloud-init | **standard** de toutes les images cloud |
|
||||
|
||||
Tu as appris **VM/hyperviseur, image de référence, cloud-init, l'infra jetable** — pas « Proxmox ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Regarde un clone.** Dans la GUI (`make inventaire-ui`), un serveur *actif* a été **cloné** du
|
||||
template (bouton « 🖥 Créer la VM »). Son VMID/IP sont **dérivés** de la nomenclature.
|
||||
2. **Vois l'identité cloud-init.** Sur un nœud : `cloud-init query hostname`, `hostname -f`, et
|
||||
l'agrandissement du disque racine (`df -h /`).
|
||||
3. **Sépare les deux couches.** cloud-init a posé *l'identité* ; tout le reste (paquets, services,
|
||||
durcissement) vient d'**Ansible**. Le template, lui, ne contient **aucune** donnée de clone.
|
||||
4. **Casse & répare (mentalement + lab).** Supprime un nœud non critique et **reclone-le** depuis le
|
||||
template, puis redéploie : il revient à l'identique. Tu *sens* que la machine est **reconstructible**.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Playbooks Proxmox : `playbooks/proxmox/` ; rôle `cloud_init` ; préparation du modèle : `playbooks/modeles_vm/`.
|
||||
- Golden template = actif central (jamais jetable, cloné pour chaque VM).
|
||||
- Ce qui est précieux = la **donnée** : unité **Sauvegardes**.
|
||||
28
_Sidebar.md
28
_Sidebar.md
|
|
@ -4,28 +4,28 @@
|
|||
**Unités d'apprentissage**
|
||||
|
||||
*Fondations*
|
||||
- [Identité & SSO](Identité-et-SSO) ✅
|
||||
- [PKI & confiance](PKI-et-confiance) ✅
|
||||
- [DNS & résolution de noms](DNS-et-résolution) ✅
|
||||
- [Identité & SSO](Identité-et-SSO)
|
||||
- [PKI & confiance](PKI-et-confiance)
|
||||
- [DNS & résolution de noms](DNS-et-résolution)
|
||||
|
||||
*Communication*
|
||||
- Reverse-proxy & TLS *(à venir)*
|
||||
- Courriel (SMTP/IMAP) *(à venir)*
|
||||
- [Reverse-proxy & TLS](Reverse-proxy-et-TLS)
|
||||
- [Courriel (SMTP/IMAP)](Courriel)
|
||||
|
||||
*Données*
|
||||
- Bases de données *(à venir)*
|
||||
- Cache *(à venir)*
|
||||
- [Sauvegardes (3-2-1)](Sauvegardes) ✅
|
||||
- [Bases de données](Bases-de-données)
|
||||
- [Cache](Cache)
|
||||
- [Sauvegardes (3-2-1)](Sauvegardes)
|
||||
|
||||
*Observabilité*
|
||||
- Métriques & journaux *(à venir)*
|
||||
- Supervision & impact *(à venir)*
|
||||
- [Métriques & journaux](Métriques-et-journaux)
|
||||
- [Supervision & impact](Supervision-et-impact)
|
||||
|
||||
*Socle & méthode*
|
||||
- Virtualisation & clonage *(à venir)*
|
||||
- Sécurité & durcissement *(à venir)*
|
||||
- Infra as Code & idempotence *(à venir)*
|
||||
- Liaisons (bindings) *(à venir)*
|
||||
- [Virtualisation & clonage](Virtualisation-et-clonage)
|
||||
- [Sécurité & durcissement](Sécurité-et-durcissement)
|
||||
- [Infra as Code & idempotence](Infra-as-Code-et-idempotence)
|
||||
- [Liaisons (bindings)](Liaisons-bindings)
|
||||
|
||||
**Opérations**
|
||||
- Runbooks *(à venir)*
|
||||
|
|
|
|||
Loading…
Reference in a new issue