Vue lecture

Vos sauvegardes Windows avec Plakar, et un backend S3

Bon, on va pas se mentir, j’étais pas parti pour l’écrire cet article. Mais faut dire que j’ai un peu merdé dans les grandes largeurs pour le live, donc bon, sachant qu’en plus je traite d’un angle particulier de l’usage de ce cher Plakar, autant en faire un billet, ça sera le premier (et j’espère pas le seul) de 2026. On y croit ?

Plakar est une solution développée en France par une petite équipe apparemment friande des jeux de mots, puisqu’au delà de son nom même, le site est hébergé par la société Kandbaz. Voilà voilà…

Des confrères blogueurs ont déjà fait quelques présentations de l’outil (exemple: Adrien), principalement pour s’en servir sous Linux. Il se trouve que j’ai une machine Windows qui a besoin d’être sauvegardée, en vue d’une mise à jour de firmware de SSD qui devrait bien se passer, mais on doit toujours faire une sauvegarde avant de faire ce genre de choses. Mieux vaut prévenir que guérir comme on dit. Et la présentation en live aurait du se passer plus ou moins tranquille, mais bon, j’ai pas percuté la micro-coupure pendant plus d’une heure (habitué à ne pas avoir d’activité dans le chat), donc, je vous remet le processus sur « papier numérique ».

Je ne redétaille pas l’installation de Garage parce qu’on l’a faite en live sans souci.

Petit rappel rapide des caractéristiques de l’outil

On a donc un outil principalement en ligne de commande, qui repose sur un concept voisin de celui de Borg, qui nécessite la configuration d’un dépôt et propose un chiffrement natif des sauvegardes. Ce dépôt, local ou distant, peut être contacté de différentes manières, natives (SFTP/SSH) ou via des intégrations supplémentaires à installer au besoin. C’est le cas notamment du support S3.

Le setup

En soit, c’est très bien documenté : une fois l’outil installé, vous ajoutez le package directement, mais vous tombez sur un mur que je n’aime pas : créer un compte Plakar pour accéder aux intégrations. J’ai une petite idée de pourquoi ça peut avoir du sens (les intégrations concernent en général des solutions d’entreprise), mais ça me gonfle plus que profondément quand ça concerne des particuliers, qui se font déjà violer en permanence, donc pas la peine d’en rajouter (on a la même avec  BitWarden, ou El Gato et son Stream Deck Marketplace pour l’intégration… d’OBS, qui est pourtant mis en avant comme native – c’est donc faux). Fort heureusement, l’outil propose de builder l’intégration depuis les sources qui sont disponibles sur Github, comme le reste des sources de l’outil, et ça sans création de compte. C’est facile… si on est sous Linux.

J’avoue que pour l’instant les installations sont un peu brutes de décoffrage, mais le support Windows est vraiment frais, donc je ne vais pas trop me formaliser là-dessus. Le fait que ça doit déjà proposé pour une version 1.0 est déjà assez cool. Par contre, concernant la compilation des intégrations, c’est plus ardu : il faut disposer de Go (dans la version qui est demandée par Plakar), de Make (à priori à part Chocolatey pas de moyen indépendant), et peut-être d’autres outils, mais je me suis heurté à un mur à cause de ça. La solution, comme d’hab’, aura demandé un pas de côté.

La cross compilation à la rescousse

Une des particularités de Go, c’est qu’on peut nativement compiler pour un autre système d’exploitation que celui sur lequel on se trouve. Et la chaine de compilation nécessaire est plus facile à déployer sous Linux; ça tombe bien, WSL est là pour ça. Après l’installation de la même version de Plakar que sous Windows, j’ai donc installé build-essential (pour être sûr d’avoir un max d’outils, donc Make), installé la version 1.24.12 de Go via asdf-vm (je vous renvoie vers la doc de Stéphane Robert qui a tout expliqué au sujet de cet outil trop pratique). Et pour la compilation d’un autre OS, c’est simple : on configure une variable d’environnement, GOOS, éventuellement l’architecture (oui, parce que c’est aussi possible), l’extension de fichier dans la variable EXT (parce que sous Windows, il faut un .exe pour qu’il soit exécutable – oui c’est débile en 2026, mais que voulez-vous, l’IA c’est plus intéressant à intégrer que moderniser un OS don personne ne voulait à la base) et on lance la compilation de l’intégration via la commande plakar ad-hoc. Vraiment, c’est aussi simple que ça :

$ export GOOS=windows
$ export EXT=.exe
$ plakar pkg build s3
info: fetching https://plugins.plakar.io/kloset/recipe/v1.0.0/s3.yaml
/usr/bin/make -C /tmp/build-s3-v1.0.7-161840773 EXT=.exe
3fe849cb: OK ✓ /manifest.yaml
3fe849cb: OK ✓ /s3Importer.exe
3fe849cb: OK ✓ /s3Exporter.exe
3fe849cb: OK ✓ /s3Storage.exe
3fe849cb: OK ✓ /
Plugin created successfully: s3_v1.0.7_windows_amd64.ptar
$ ls -l
.rw------- 1 42M seboss666 16 Jan 22:29  s3_v1.0.7_windows_amd64.ptar

On peut donc désormais copier le fichier ptar sous Windows (il faudra que je creuse ce format qui semble un peu maison), et on peut l’installer avec la bonne commande :

> .\plakar.exe pkg add ./s3_v1.0.7_windows_amd64.ptar
> .\plakar.exe pkg list
s3@v1.0.7

La sauvegarde ? Ben ça fonctionne

On peut donc attaquer le dur. J’ai juste suivi la doc de l’intégration, à savoir créer le kloset l’initialiser, et lancer le backup d’un dossier vers ce kloset là :

.\plakar.exe store add garage s3://192.168.1.201:3900/backup-pc access_key=<accesskey> secret_access_key=<secret_key> use_tls=false
.\plakar.exe at "@garage" create
repository passphrase:
repository passphrase (confirm):
.\plakar.exe at "@garage" ls
repository passphrase:
.\plakar.exe at "@garage" backup C:\\Users\\Seboss666\\Pictures\\blog
repository passphrase:
e363f7fa: OK ✓ /C:/Users/Seboss666/Pictures/blog/Firefox_groupe_onglets.png
e363f7fa: OK ✓ /C:/Users/Seboss666/Pictures/blog/Firefox_profils.png
e363f7fa: OK ✓ /C:/Users/Seboss666/Pictures/blog/docker-docker-everywhere.jpg
e363f7fa: OK ✓ /C:/Users/Seboss666/Pictures/blog/418-error-page.png
e363f7fa: OK ✓ /C:/Users/Seboss666/Pictures/blog/cross.svg
(...)
.\plakar.exe at "@garage" ls
repository passphrase:
2026-01-16T21:40:31Z e363f7fa 42 MiB 0s /C:/Users/Seboss666/Pictures/blog

Bonus, on peut vérifier l’état du backup depuis un autre PC, ou un autre OS, donc je suis retourné sur WSL, j’ai viré les variables d’environnement pour builder l’intégration pour Linux cette fois, et rebuildé/ajouté l’intégration. On reprend ensuite la même commande pour ajouter le Kloset, mais pas besoin de l’initialiser, on peut directement lister son contenu en fournissant la bonne passphrase :

$ plakar store add garage s3://192.168.1.201:3900/backup-pc access_key=<access_key> secret_access_key=<secret_key>
$ plakar at "@garage" ls
repository passphrase:
2026-01-16T21:40:31Z e363f7fa 42 MiB 0s /C:/Users/Seboss666/Pictures/blog

On peut donc faire à peu près ce qu’on veut dès lors : restauration complète ou partielle, création de nouveaux backups, etc.

Verdict

Donc oui, tout a fonctionné pratiquement du premier coup. J’ai quand même tâtonné au départ concernant le build de l’intégration, à vouloir « make » direct à partir du dépôt git. Mais dans ce cas, on se retrouve avec les trois binaires, sans infos sur la construction du fameux ptar (on est là encore dans le simili-jeu de mots, vraiment…), ce qui est plutôt dommage. Il m’aura fallu quelques minutes pour me résigner à utiliser plakar directement. Il faudrait aussi un peu plus de retour sur les commandes qui se déroulent bien (sans erreur). Autant quand on se plante, on le sait, mais quand on se plante pas, voir juste un retour à la ligne est un peu frustrant et déroutant.

Il y a question aussi sur les performances de la sauvegarde testée. j’ai testé sur un dossier de 108 images, et un des développeurs s’est étonné sur BlueSky du temps que ça a pris. J’avoue que pour l’instant, je n’ai pas creusé le sujet, il y a des chances que ça soit dû aux performances S3 elle-mêmes, à NTFS, une combinaison de tout ça. Garage est censé être performant, mais bon, on est sur un processeur ARM assez poussif quand même, qui doit déjà gérer le transfert réseau, donc on est pas à l’abri que ça soit un problème purement chez moi.

En tout cas, pour un jeune logiciel, la qualité de la documentation et l’implémentation Windows déjà opérationnelle (même si encore un peu buggée chez certains, en lien notamment avec les différences slash/antislash à cause de Windows), en bonus une interface web pour parcourir les backups, il m’a très agréablement surpris. On ne peut souhaiter que ça mature comme il faut et que l’entreprise trouve son équilibre (la stabilité financière et l’open-source, hein…). Et moi que je regarde d’un peu plus près le statut du live la prochaine fois (ou que je configure l’enregistrement en plus du stream)…

  •  

Microsoft débranche enfin MDT - Comment déployer Windows sans se ruiner (et sans le cloud) ?

Snif, snif sniiiif, c'est la fin d'une époque pour tous les admins système qui ont les mains dans le cambouis depuis plus de deux décennies.

Hé oui les amis, Microsoft vient de décider de débrancher la prise de son vénérable Microsoft Deployment Toolkit (MDT). Adios ce outil né en 2003 (sous le nom de BDD à l'époque) qui nous a sauvés la mise pendant plus de 20 ans pour installer des parcs entiers de bécanes sans y passer la nuit !

Alors pourquoi ce revirement ?

Bon, alors officiellement, c'est pour nous faire passer à des solutions "modernes" mais officieusement, beaucoup y voient une manœuvre pour nous pousser vers le passage à la caisse cloud avec Windows Autopilot et Intune. Forcément, un outil gratuit, local, qui ne remonte quasiment aucune télémétrie (contrairement aux usines à gaz actuelles) et qui permet de faire des masters aux petits oignons sans dépendre d'Azure, ça commençait à faire tache dans le catalogue de Redmond. (oooh yeah !)

Le problème, c'est que pour pas mal de boîtes, Autopilot nécessite des licences spécifiques (M365 Business Premium ou Intune Plan 1) et une connexion internet béton. Hé oui, tout le monde n'a pas envie de dépendre du cloud pour provisionner un poste.

Ça tombe bien, vous me connaissez, je ne vais pas vous laisser tomber. Alors si vous faites partie de ceux qui se retrouvent le cul entre deux chaises, sachez qu'il existe des alternatives sérieuses et surtout gratuites ou open source.

Pour l'imagerie pure et dure (le bare-metal), mon chouchou reste FOG Project . C'est une bête de course open source qui remplace avantageusement la partie imagerie de WDS. Ça gère le boot réseau (PXE), le multicast pour arroser des dizaines de PC d'un coup, et ça permet de capturer et déployer vos images Windows 10 ou 11. Et pour ceux qui veulent du plus classique, Rescuezilla (le clone graphique de Clonezilla) fait aussi un boulot béton pour cloner des disques.

Mais là où ça devient vraiment chouette, c'est pour la configuration post-installation car plutôt que de s'enquiquiner avec des task sequences complexes, je vous conseille de regarder du côté d'Ansible. Oui, ça marche aussi pour Windows via WinRM (le mode standard) ou SSH ! Vous lancez un petit playbook YAML et hop, vos softs sont installés, vos paramètres de sécurité sont appliqués et votre machine est prête à l'emploi. C'est propre, reproductible et ça évite les erreurs humaines.

Pour ceux qui veulent bidouiller leur serveur de boot, n'oubliez pas non plus d'aller voir mon article sur Netboot.xyz qui est une mine d'or pour booter un grand nombre d'OS par le réseau.

Bref, même si Microsoft tente de nous enfermer dans sa cage dorée avec Autopilot, la communauté a déjà tout ce qu'il faut pour qu'on reste maîtres de notre infrastructure. Alors courage les admins !!! Une page se tourne mais les outils qui déchirent sont toujours là !

Source

  •  

Des vacances au clair de lune (ou comment faire son Geforce Now privé)

Il aura fallu beaucoup trop de temps pour que ça se produise, et je l’aurai travaillé au corps une paire de fois le gaillard, mais voilà, ceci est le premier billet invité de l’unique, l’irremplaçable Pierre-Marie ! Parce que c’était à la fois trop con comme cible de jeu, mais surtout trop rigolo vu le mix de technos abordées, parce qu’on va parler de Pokemon, de Sunshine/Moonlight (le titre ne ment pas), de wakeonlan, de Kubernetes, de Fission. Oui, tout ça en même temps. Vous comprenez mon enthousiasme ?

La puissance des algorithmes de ciblage

Au détour de mon scrolling sur X, je suis tombé sur un post parlant de jeux vidéos (l’algorithme est bien foutu) et sur une injonction à s’inscrire sur PokeMMO.
Pas fan hardcore de Pokémon, j’ai quand même bien poncé les deux premières gen et me suis tenté à la troisième.
Je fais partie des gens qui n’attendent plus grand chose de Game Freak qui, selon moi, ressort en boucle les mêmes jeux sans vraiment d’innovation.
Au contraire, côté développement non officiel, on retrouve des jeux dérivés comme Pokémon Showdown, qui malgré que ce ne soit pas mon style de jeu, attire une grande communauté et qui aurait pu donner des idées à Nintendo pour renouveler la licence.
J’ai, par exemple, plus apprécié le rom hack Pokémon Adventures Red Chapter basé sur l’excellent manga Pokémon La Grande Aventure que le remake Let’s Go Evoli.
Bref, je suis donc allé voir ce qu’était ce PokeMMO, et me suis motivé pour me lancer dessus. Ça tombe bien, je pars 2 semaines en vacances et il faudra bien occuper mes soirées au coin de la clim. (article commencé au mois de Juillet). PokeMMO propose un installer pour Windows, Linux, iOS, Android et même un package pour OS alternatif (j’ai vu pas mal de gens qui installaient ça sur une console portable de type Retroid).
Personnellement, j’ai à ma disposition une PsVita et une Switch, toutes deux libérées et qui me servent lors de mes sessions retrogaming. L’option téléphone/tablette est pour moi rédhibitoire ne possédant pas de manette compatible et aimant beaucoup trop les boutons physiques pour jouer au tactile.
Installer Android sur Switch me semblant trop fastidieux, j’ai décidé de partir sur une autre voie. Étant obligé d’être connecté pour jouer quoi qu’il arrive (le O de MMO, hein), je me penche sur Moonlight, que j’avais déjà testé il y presque 10 ans. Il y a des clients pour Switch et PsVita (et pour beaucoup d’autres OS/appareils) donc ça pourrait correspondre à mes besoins.

Installation de Sunshine/Moonlight

Moonlight, pour vulgariser, c’est un client non-officiel pour le protocole Nvidia Gamestream qui vient se connecter à un ordinateur distant pour le contrôler à distance. Il a la force de supporter les contrôleurs locaux et de transmettre au PC distant à la manière d’un Steam Link. Pour pouvoir streamer vers un client Moonlight, il faut un serveur sur la machine cible. Le logiciel Nvidia GeForce Experience permet cela mais la « nouveauté » par rapport à mon essai d’il y a 10 ans, c’est le serveur Sunshine qui permet de s’affranchir du logiciel de Nvidia.

L’installation de Sunshine se fait via l’installateur dédié à la distribution cible en quelques secondes. Une fois installé, Sushine se configure via une interface web accessible en local. Elle permet de gérer les différents clients (appairage, suppression…), les différentes applications et les options de streaming (encodage, bitrate…).

Le première étape est de créer un couple utilisateur/motdepasse pour protéger l’accès à cette interface.

Interface de configuration de Sunshine: Creation du mot de passe

Par défaut, Sunshine propose deux applications: Bureau et Steam Big Picture (même si Steam n’est pas installé sur le système)

Interface de configuration de Sunshine: Applications

J’installe donc PokeMMO et le configure comme Application dans Sunshine. Je reprends simplement les valeurs trouvées dans le raccourci Bureau qui a été crée lors de l’installation. Il détecte même la miniature automatiquement.

Interface de configuration de Sunshine: Création de l’application PokeMMO

J’installe le client Moonlight sur les deux appareils. Le client détecte automatiquement le PC supportant Sunshine et affiche un code d’appairage à entrer dans Sunshine.

Interface de Moonlight: Détection

Interface de configuration de Moonlight: Appairage

Interface de Sunshine: appairage

L’appairage se déroule sans problème et je peux tester le stream en local.

Interface de Moonlight: Écran d’accueil

Je lance l’application Bureau et ça me permet de confirmer qu’il est bien possible d’ouvrir une session Windows à distance.

Interface de Moonlight: Bureau

Pour le stream distant, il faut juste s’assurer que Upnp est activé sur le routeur et cocher une case dans la configuration de Sunshine.

Interface de configuration de Sunshine: Activation de l’Upnp

(ndr: sinon il faut définir les ports et ouvrir manuellement/créer les redirections de port; l’IP fixe pour le PC de jeu est fortement recommandée dans ce cas)

Fini ?

On aurait pu s’arrêter là, mais bon, je suis pas fan de laisser tourner le PC H24 pendant 2 semaines juste pour l’utiliser quelques heures. Moonlight propose une fonctionnalité bien pratique de Wake On LAN pour démarrer un ordinateur à distance, mais voilà, ça ne fonctionne qu’en réseau local (en même temps c’est dans le nom).
Il faut donc trouver le moyen de le faire fonctionner à distance. J’ai plusieurs dispositifs à ma disposition.
Mon routeur PfSense permet de d’envoyer des paquets WoL mais uniquement via l’interface, pas d’API disponible. Il faudrait se connecter à l’interface via VPN pour lancer la commande. C’est trop lourd et pas assez flexible.
Solution suivante, utiliser le cluster k3s qui tourne à la maison.

Utilisation de k3s

On teste la faisabilité du process en lançant un pod temporaire contenant la commande wakeonlan mais ça ne fonctionne pas car l’appareil ciblé n’est pas sur le LAN du cluster k3s comme l’est le pod.
En cherchant un peu, on trouve qu’il faut configurer le pod pour qu’il tourne dans le réseau hôte, le réseau des nœuds.

kubectl run tmp --rm -it --image nixery.dev/shell/wakeonlan -it --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"hostNetwork":\ntrue}}' -- wakeonlan a1:b2:c3:d4:e5:f6

Et ça marche !!

Reste à trouver le moyen de lancer ça simplement, via un appel HTTP par exemple. Je viens justement de déployer un système de micro-services : Fission.
Fission permet de déployer des fonctions de micro-services à la manière d’un système Serverless comme Lambda. Ça me permettrait de recevoir une requête HTTP avec en paramètre l’adresse MAC cible et d’envoyer la requête WoL avec un simple code python.

Installation de Fission

L’installation de Fission est simple si on passe par leur chart Helm. On a juste à surcharger quelques valeurs grâce au fichier values.yml suivant.

## Fission chart configuration
##

## routerServiceType to consider while creating Fission Router service.
## For minikube, set this to NodePort, elsewhere use LoadBalancer or ClusterIP.
##
routerServiceType: ClusterIP

## defaultNamespace represents the namespace in which Fission custom resources will be created by the Fission user.
## This is different from the release namespace.
## Please consider setting `additionalFissionNamespaces` if you want more than one namespace to be used for Fission custom resources.
##
defaultNamespace: fission

# Add Fission helm repo
helm repo add fission-charts https://fission.github.io/fission-charts
# Install CRDs 
kubectl create -k "github.com/fission/fission/crds/v1?ref=v1.21.0"
# Install Fission
helm install fission fission-charts/fission-all -f values.yml -n fission --create-namespace
# Install Fission CLI binary
curl -Lo fission https://github.com/fission/fission/releases/download/v1.21.0/fission-v1.21.0-linux-amd64 && chmod +x fission && sudo mv fission /usr/local/bin/

Configuration de Fission

La documentation fission nous apprend qu’on peut modifier les spécifications des pods. Il y a même un tutoriel pour déployer un exemple.

# On créé un dossier dédié
mkdir wol-fn
cd wol-fn
# On initialise le dossier specs
fission spec init
# On créé l'environnement qui fera touner le code python
fission -n fission env create --spec --name python-wol --image ghcr.io/fission/python-env --builder ghcr.io/fission/python-builder
# On créé le dossier de la fonction
mkdir wol
# On créé un fichier requirements.txt avec le module python dont nous avons besoin
echo "wakeonlan" > wol/requirements.txt
# On créé le fichier contenant le code python à exécuter
touch wol/wol.py

from flask import request
from wakeonlan import send_magic_packet
import re

def main():
    mac = request.args.get('mac')
    if mac is None:
        return "Please send a MAC address"
    else:
        if re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", mac.lower()):
            send_magic_packet(mac)
            return "Sending magic packet to 255.255.255.255 with broadcast 255.255.255.255 MAC %s port 9" % (mac)
        else:
            return "%s is not a valid MAC format" % (mac)

On créé la spécification pour la fonction qui décrit quel code doit être exécuté et le trigger HTTP qui détermine quelle URL déclenche son exécution.

# On créé la spécification pour la fonction
fission -n fission function create --spec --name wol-fn --env python-wol --src "wol/*" --entrypoint wol.main
# On créé la spécification pour la route.
# Avec les annotations permettant de créer l'ingress rule sur Traefik
fission -n fission route create --spec --name wol-fn-get --method GET --url /wake --function wol-fn --createingress --ingressrule "test.domain.tld=/wake" --ingressannotation "kubernetes.io/ingress.class=traefik" --ingressannotation "traefik.ingress.kubernetes.io/router.entrypoints=websecure" --ingressannotation 'traefik.ingress.kubernetes.io/router.tls="true"' --ingressannotation "traefik.ingress.kubernetes.io/router.tls.certresolver=letsencrypt"

On a maintenant un dossier contenant la fonction et son environnement standard.

wol-fn
├── specs
│   ├── README
│   ├── env-python-wol.yaml
│   ├── fission-deployment-config.yaml
│   ├── function-wol-fn.yaml
│   └── route-wol-fn-get.yaml
└── wol
    ├── requirements.txt
    └── wol.py

On va modifier le fichier env-python-wol.yaml pour ajouter notre configuration spécifique.

---
apiVersion: fission.io/v1
kind: Environment
metadata:
  creationTimestamp: null
  name: python-wol
spec:
  builder:
    command: build
    container:
      name: builder
      resources: {}
    image: ghcr.io/fission/python-builder
    podspec:
      containers:
      - name: builder
        resources: {}
  imagepullsecret: ""
  keeparchive: false
  poolsize: 3
  resources: {}
  runtime:
    container:
      name: python-wol
      resources: {}
    image: ghcr.io/fission/python-env
    podspec:
      containers:
      - name: python-wol
        resources: {}
+     hostNetwork: true
+     dnsPolicy: ClusterFirstWithHostNet
  version: 3

La directive hostNetwork permet comme vu plus haut de faire tourner le pod sur le réseau hôte.
Avec juste cette modification, on a une erreur à l’exécution du code parce que le pod n’arrive pas à aller chercher l’archive contenant le code de la fonction sur le stockage partagé de Fission.

{
    "level": "error",
    "ts": "2025-08-22T15:55:03.884Z",
    "logger": "generic_pool_manager.generic_pool.fetcher_client",
    "caller": "client/client.go:114",
    "msg": "error specializing/fetching/uploading package, retrying",
    "error": "Internal error - error fetching deploy package: failed to download url : Get \"http://storagesvc.fission/v1/archive?id=%2Ffission%2Ffission-functions%2Ffc6798a9-95c3-47cb-8797-28f842162f83\": dial tcp: lookup storagesvc.fission on 9.9.9.9:53: no such host",
    "url": "http://X.X.X.X:8000/specialize",
    "stacktrace": "github.com/fission/fission/pkg/fetcher/client.sendRequest\n\tpkg/fetcher/client/client.go:114\ngithub.com/fission/fission/pkg/fetcher/client.(*client).Specialize\n\tpkg/fetcher/client/client.go:56\ngithub.com/fission/fission/pkg/executor/executortype/poolmgr.(*GenericPool).specializePod\n\tpkg/executor/executortype/poolmgr/gp.go:467\ngithub.com/fission/fission/pkg/executor/executortype/poolmgr.(*GenericPool).getFuncSvc\n\tpkg/executor/executortype/poolmgr/gp.go:553\ngithub.com/fission/fission/pkg/executor/executortype/poolmgr.(*GenericPoolManager).GetFuncSvc\n\tpkg/executor/executortype/poolmgr/gpm.go:242\ngithub.com/fission/fission/pkg/executor.(*Executor).createServiceForFunction\n\tpkg/executor/executor.go:239\ngithub.com/fission/fission/pkg/executor.(*Executor).serveCreateFuncServices.func1\n\tpkg/executor/executor.go:143"
}

On voit qu’il cherche à contacter storagesvc.fission et qu’il n’arrive pas à résoudre ce hostname, ce qui est normal étant donné qu’il s’agit d’un nom interne au cluster et que le pod tourne désormais sur le hostNetwork. La directive dnsPolicy: ClusterFirstWithHostNet permet de forcer d’essayer la résolution en interne au cluster avant de tenter en externe sur le hostNetwork et résout ce problème.

Il ne reste qu’à déployer.

# On vérifie la syntaxe
fission spec validate
# On déploie
fission spec apply --wait
# On test via Fission CLI
fission -n fission function test --name wol-fn --method GET -q "mac=a1:b2:c3:d4:e5:f6"
# On test via HTTP depuis l'extérieur
curl "https://test/domain.tld/wake?mac=a1:b2:c3:d4:e5:f6"

Pour faire simple, ajouter l’URL en raccourci sur le téléphone et en un clic, le PC est démarré. Personnellement, je l’ai intégré dans mon Home Assistant avec un bouton dédié.

Home Assistant Dashboard

Finalisation de la configuration

Celui qu’on adore détester

Il reste deux ou trois détails à régler. Par défaut, depuis Windows 10, quand on arrête le système, il se place en réalité dans un mode de veille prolongée pour permettre un démarrage plus rapide. Hors le *Wake On LAN* ne fonctionne pas sur ce mode de sommeil. Microsoft documente ça très bien ici. Il y est également expliqué comment désactiver ce mode pour pouvoir rétablir un mode d’extinction « normal ».

Je vous les remets à l’identique:

  • Dans Panneau de configuration, ouvrez l’élément Options d’alimentation
  • Sélectionnez le lien Choisir ce que les boutons d’alimentation font
  • Désactivez la case à cocher Activer le démarrage rapide (recommandé)
  • Sélectionnez Enregistrez les paramètres.

Une fois cette modification effectuée, le Wake On LAN est complètement fonctionnel.

La fin

Et donc, puisqu’on a abordé le sujet, comment se passe l’extinction ? Vous vous rappelez ? le but de tout ce foutoir, c’était d’éviter de garder le PC allumé pendant deux semaines. On a parlé du démarrage, mais quid de l’arrêt ?

Le plus simple est de lancer une session Bureau dans Moonlight et d’aller cliquer sur le menu Démarrer puis le bouton Arrêter comme à la maison. Mais on peut aussi déclarer des applications dans Sunshine et il exécutera la commande associée à cette application.

J’ai donc créer une application nommée Shutdown qui lance la commande suivante shutdown /s /f /t 0.

Interface de configuration de Sunshine: Shutdown Application

Quand elle est lancée depuis le client Moonlight, elle éteint le PC distant.

Feedback et Conclusion

Puisque je suis rentré depuis, je peux débriefer ces 2 semaines d’utilisation, ça fonctionne super, le seul défaut que j’ai eu est qu’une fois le Shutdown n’a pas fonctionné et je ne l’ai pas vu tout de suite. Les fois suivantes, j’ai juste eu à bien vérifier le status dans le menu.

Interface de Moonlight: PC démarré

Interface de Moonlight: PC éteint

À part ça, super expérience ! Bien sur je n’ai pas cherché à jouer à des jeux très performants, mais ça a suffi à mes besoins, même en 4G. Je n’ai pas non plus poussé jusqu’à tenter de jouer sur la 4G en voiture, mais je pense que ça aurait pu marcher.
Je continue à l’utiliser, même à la maison, pour jouer dans le canapé plutôt que devant le PC.

Interface de Moonlight: PokeMMO


Alors, avouez que c’est pas mal en termes de bricolages inutiles donc indispensables, il était donc nécessaire de partager ça avec le plus grand nombre ? (enfin au moins les lecteurs de ce blog)

  •  

Par où commencer Kubernetes ?

Réflexion issue d’une discussion sur le Discord de Cuistops concernant le fait que Talos pourrait ne pas être le meilleur point de départ pour s’attaquer à cette technologie d’infrastructure qui a balayé le monde de l’orchestration de containers en une petite dizaine d’années. Pour illustrer pourquoi il n’y a pas de réponse absolue à cette question, je me suis dit que vous décrire mon parcours concernant l’univers des containers et Kubernetes en particulier (aussi bien au niveau perso que pro) serait éclairant sur certains points.

Aux origines : Docker

Le moins qu’on puisse dire, c’est que mon entrée dans l’univers des containers, en particulier via docker, n’était pas brillante. Je conserve avec malice le premier billet que j’ai consacré à ce sujet en 2016 pour illustrer à quel point je me trompais sur la technologie, que je n’avais jusque là pas vraiment vu, encore moins au niveau professionnel. J’ai heureusement rattrapé cette erreur depuis, aussi bien à la faveur de formations au travail (merci Thomas Perelle 🙂 ) qu’au niveau perso, où mes propres expérimentations m’ont conduit à partager ma découverte et mon utilisation de Docker Swarm. J’ai bien rattrapé le coup, hein ?

D’ailleurs, Swarm a été pour moi la découverte de la notion d’orchestration. Que j’ai pu creuser cette fois au niveau pro en 2018 après un premier tout petit pas vers l’univers Kubernetes par la porte OpenShift à la faveur d’un workshop de deux jours par un collègue qui sera réellement un mentor pour les années suivantes, Julien Francoz. Je n’ai malheureusement pas gardé grand chose de ce workshop, étant donné que je n’avais aucune plateforme de ce type dans mon pôle client, encore moins de Kubernetes. Tout juste on commençait à avoir des clients qui cherchaient à déployer leurs applis en mode container sur des serveurs classiques, avec Docker. Sans pratique, la théorie s’efface vite, d’autant qu’en 2018, les usages « domestiques » n’étaient pas légion, donc les articles de blog non plus, encore moins autour d’Openshift. C’est en 2019 que tout change.

2019 : La découverte de Kube, de la containerisation d’applications, d’Azure, de terraform (tout en même temps)

Je vous passe le contexte de comment j’en suis arrivé à cette situation intense qui aura duré 5 mois, mais oui, j’ai découvert Kubernetes d’une façon un peu particulière : service cloud managé, sur Azure, el famoso « AKS« , à devoir migrer des applications précédemment hébergées sur des serveurs virtuels Debian dépassés, avec un cluster déployé manuellement qu’on a tenté de « terraformer » après-coup, avec toute la « qualité » de l’API d’Azure d’alors. Et je remercie encore Julien d’avoir pris autant de temps à me soutenir dans cet apprentissage express (la notion de mentor n’était pas galvaudée, clairement).

Moi pendant la migration du client sur Kubernetes

Service cloud Managé veut dire qu’on ne gère pas certains aspects importants de la vie d’un cluster : tout le control plane est masqué, vous ne voyez que les nœuds, vous ne vous occupez pas trop de certains aspects comme la rotation des certificats, les mises à jour sont automatisées (vous indiquez une version cible, le service s’occupe de la montée de version du control plane, puis des nœuds un par un), et vous bénéficiez d’intégrations avec le reste de l’infra du fournisseur, au niveau du réseau, du stockage, des capacités comme l’autoscaling (vous augmentez et réduisez automatiquement le nombre de nœuds en fonction de la charge ou des réservations de ressources des pods à déployer). L’installation se fait en trois/quatre clics via l’interface web, une ligne de commande avec l’utilitaire maison, ou un peu plus de lignes de code si on le fait via un outil d’infrastructure as code.

Bref, c’est cool, ça permet de se concentrer sur les aspects opérationnels des applications déployées, mais même comme ça, je vous avoue que AKS tel que Microsoft le proposait n’était pas toujours une sinécure. Azure lui-même était pénible, avec des VMs qui mettaient plusieurs minutes à démarrer (quand les concurrents tournaient autour de la minute). Et comme on ne gère pas le control plane, on rate tout un pan de l’architecture et de la gestion de Kubernetes et de ses composants sous-jacents. En plus à l’époque, l’image de l’OS utilisé pour les nœuds était basée sur Ubuntu, pas le plus léger et le « gaspillage » de ressources était réel, au-delà de Kubernetes lui-même.

J’aurais l’occasion de passer encore quelques années, pratiquement trois, à déployer d’autres projets AKS pour d’autres clients, ce qui m’a permis de constater, il faut savoir aussi le reconnaitre, comment Microsoft a cravaché pour amener un niveau de qualité sur le service bien plus en phase avec ce qu’on attend d’un tel fournisseur. Rotation automatique des certificats via les mises à jour (c’était pas le cas, la commande de rotation était à lancer à la main), amélioration générale d’Azure sur les temps de démarrage des nœuds, efficacité des mises à jour, intégrations avancées au niveau réseau (Calico, Istio, etc)… Ce qui n’empêche pas certains pains avec entre autres une API qui accepte certaines valeurs pourtant non supportées et qui m’ont forcé à redéployer des clusters from scratch parce que la communication entre les nœuds étaient devenue impossible (réponse du support : « on va mettre à jour la doc pour indiquer les valeurs supportées »; bravo…). Par la suite, j’ai découvert et encore plus adoré exploiter et déployer du GKE, le service équivalent de Google Cloud; il m’aura permis au passage d’apprendre comment fonctionnait ce fournisseur et tout ce qu’il fait de mieux que Microsoft (et parfois d’AWS). Au point de passer la certification « Professional Architect » au bout de 4 mois seulement de pratiques.

Kube à la maison

Cette expérience en particulier avec Azure ne m’aura pas empêché pas de tomber amoureux de la technologie, au point de remiser Docker Swarm, et de migrer sur K3S. Là aussi un choix particulier, conçu pour les machines très légères, puisque ciblant les Raspberry Pi, j’ai malgré tout fait le déploiement du flemmard, même si j’ai privilégié un déploiement semi-automatisé avec un playbook/role Ansible, et un seul nœud comme control plane (qui était le seul mode de déploiement supporté alors).

Particularité de k3s, regrouper tous les composants « core » de Kubernetes dans un seul binaire, une petite prouesse à la base de son empreinte mémoire réduite, mais pas que : un des éléments les plus critiques d’un cluster, la base de données ETCD, la « mémoire » du cluster, est remplacée par SQlite, bien plus léger, mais évidemment limité à une seul nœud, et moins enclin aux problèmes des bases de données plus complexe. Bien que le mode « multi-master » ait été implémenté par la suite, au passage à mes Raspberry Pi 4, j’ai quand même conservé le même mode de fonctionnement. J’ai eu l’occasion de détailler pas mal de choses concernant K3S sur ce blog, je ne vais donc pas m’étendre beaucoup plus.

Reste qu’à l’occasion d’une volonté de refonte, accélérée par la mort successive des cartes SD des Raspi après 4 ans de bons et loyaux services, j’ai décidé de revenir à un Kubernetes un peu moins simplifié, en partant sur un autre choix particulier, Talos Linux, qui aura fini en machine virtuelle suite à une déconvenue de matériel et de limitations électriques, que je me suis pris en pleine poire en plein live Twitch. Talos propose un déploiement Kubernetes beaucoup plus standardisé dans ses composants de base, mais dont la gestion des nœuds est très particulière : pas d’OS à proprement parler, juste le noyau et une API qui permet de pratiquer toutes les opérations sur la gestion de ces nœuds : pas de SSH, pas de CLI directe, l’utilitaire talosctl est là pour configurer les nœuds à l’envi, permettant de les ajouter/retirer d’un cluster en un clin d’œil, un aspect très important dans une gestion d’infrastructure au sens large (comprendre, en entreprise). Toute la configuration de base se fait au travers de fichiers de configuration YAML, à l’instar de Kubernetes lui-même, permettant une approche « intégration continue » et un versionnement via git.

Actuellement, je me débats avec certains paramétrages par défaut orientés sécurité entre autres qui peuvent limiter/bloquer certains usages sans attention particulière. Il est vrai que par défaut, Kubernetes est une plateforme particulièrement ouverte avec peu de gardes-fous, et c’est à chacun d’adapter cet aspect en fonction de son propre contexte, ce qui amène à devoir exploiter nombre d’extensions et contrôleurs additionnels pour y parvenir. Et comme souvent, la sécurité à un prix…

Et la question de départ ?

On le voit, au final je n’ai que peu choisi comment j’ai découvert et abordé la technologie et son déploiement « dans le monde réel », et j’ai démarré par certaines abstractions qui font que si je m’étais retrouvé face à un cluster « vanilla » (kubeadm, kubespray), et un problème lié au control plane, j’aurais été plus en peine que quelqu’un ayant directement attaqué « the hard way » (z’avez la ref ?). Et d’un certain côté c’est certainement encore le cas encore aujourd’hui, ce qui me vaudrait d’être recalé au recrutement chez Lucca ou Enix. Le livre à venir teasé par Denis Germain (qui ne s’appellera pas 50 Nuances de Kubernetes, ce qui aurait été bien trop cool comme titre) montre bien la diversité d’approches qui ont chacune leurs spécificités, avec la plupart des services dit « managés » abstrayant une bonne partie des composants et concepts de bas-niveau pour vous concentrer sur vos applications ou celles de vos clients.

Est-ce que l’une d’elles est meilleure qu’une autre ? Je considère toujours que la théorie est importante, jusqu’à un certain point, dans la mesure où si on n’a pas de le contrôle sur les éléments, ne pas savoir comment ils fonctionnent de manière sous-jacente n’est pas toujours une grosse tare : ce n’est pas de notre ressort que d’y mettre les mains. Imaginez une corruption de base ETCD sur un service managé. Ma seule préoccupation sera d’être capable éventuellement de restaurer tout ce que j’y ai mis au départ – mes déploiements d’applications, mes secrets, mes CRDs, etc- , là où la préoccupation du provider, sera de réparer cette corruption; dans le pire des cas, s’il n’aura pas été capable de restaurer le service avec un minimum de pertes, il s’agira de restaurer tout ça sur un nouveau cluster.

Nous vivons également dans un monde connecté à la plus grande base de connaissances du monde : Le Web. Je n’ai pas besoin de connaitre l’intégralité des arcanes du moindre bout de logiciel, quelque soit son niveau dans l’environnement où j’évolue, pour être capable de l’exploiter au quotidien, voire de le réparer. Les connaissances déjà acquises sont évidemment importantes, parce qu’elles permettent de définir un état d’esprit, un mode de réflexion, qui est la plupart du temps applicable aux autres technologies que vous rencontrerez. Mais si je rencontre un problème que je n’ai pas déjà vu par le passé, une recherche sur le web m’amène généralement soit à la solution, soit à une piste à creuser pour déterminer la cause. Dès lors, il n’y a pas de réponses simples à apporter à la question « par où démarrer », parce qu’elle peut dépendre aussi de la « fin ».

Par où on attaque ? 😀

Faire un cluster à la mano avec tous les composants en mode « the hard way » ne sert pratiquement à rien si après on évolue dans un contexte de service managé. À l’inverse, un service managé est intéressant en ce sens qu’il permet de gérer les interactions avec d’autres services du fournisseur, et donc le mode de fonctionnement de celui-ci. Sur Kube lui-même vous manquez des choses, mais vous avez quand même pas mal de concepts à intégrer. Est-ce moins pertinent ? Pas forcément si c’est ce que vous manipulez tous les jours. Dans le même esprit, « the hard way » est probablement la pire méthode pour gérer le quotidien sur de l’infra qu’on gère, même si pour le coup on a toutes les tripes du cluster sur la table. On privilégiera donc très vite d’autres outils plus automatisés pour la gestion habituelle. N’est-ce pas tout aussi pertinent de démarrer directement avec ces solutions pour intégrer plus rapidement leurs concepts ?

Par où commencer Kubernetes ? J’ai envie de dire, par la solution qui vous rendra curieux. C’est tout le sel de l’apprentissage, comme de la recherche scientifique, où chaque réponse qu’on trouve amène d’autres questions, tout aussi passionnantes. D’autant plus que quand on démarre, on est amené à faire, défaire, refaire, à comparer. Notre univers informatique au sens large bouge tout le temps, la « galaxie » Kubernetes n’est pas en reste, il y a toujours des dizaines d’angles d’attaque possible, et à de très rares exceptions près, il n’y en a pas nécessairement une qui est plus mauvaise qu’une autre. Et d’autres apparaitront régulièrement, ce qui représente de nouvelles réponses possibles à cette question. Il ne faut pas avoir peur de se faire plaisir de différentes manières 🙂

  •  

Certificat « SSL » : petites bricoles autour des courbes elliptiques

Les courbes elliptiques, c’est la promesse de la robustesse des communications chiffrées de TLS sans la lourdeur des tailles de clés utilisées avec l’algorithme RSA. Il ne sera pas question de mathématiques aujourd’hui (je suis trop mauvais pour ça, vous avez qu’à voir Wikipedia pour ça), juste de quelques notes sur leur utilisation, pour du certificat autosigné, de la vérification, et un micro rappel de Let’s Encrypt.

Faites une petite recherche rapide, et 99,9% des tutos pour générer un certificat, que ça soit pour de l’auto-signé, ou dans le cadre de la commande chez une autorité « classique », et vous aurez du RSA avec un panel de 2048 à 4096 bits de taille de clé. Sans faire de benchmark, je peux vous assurer que si 2048bits est assez classique, 4096 ça commence à être assez lourd à gérer. Les courbes elliptiques sont des objets mathématiques qui promettent de garder la complexité mathématique, clé de la robustesse en matière de cryptographie, mais avec une taille de clé beaucoup plus réduite, ce qui permet d’améliorer la consommation de ressources et la performance du chiffrement des communications, parce que c’est le contexte dans lequel elles ont été envisagées et déployées.

Le certificat auto-signé

Typiquement, pour déployer un virtualhost « par défaut » sur mon serveur web Nginx, j’ai voulu générer un certificat auto-signé certes, mais avec les courbes elliptiques comme base cryptographique. C’est plutôt simple au final, ça se joue en à peine plus de temps, ça repose sur l’incontournable OpenSSL, malgré les problèmes qu’il pose ces dernières années, surtout en tant que bibliothèque applicative. On commence par lister les courbes disponibles :

openssl ecparam -list_curves

Vous choisissez ce que vous voulez, pour des raisons de compatibilité, j’ai sélectionné secp384r1 qui est la plus utilisée derrière sa petite sœur en 256bits et qui est nommée prime256v1 (parce que nique la cohérence, hein). C’est au passage celle que j’utilise sur le blog 😉

Ensuite, on fait les étapes classiques pour un autosigné :

openssl ecparam -genkey -name secp384r1 -out key.pem
openssl req -new -sha256 -key key.pem -out csr.csr
openssl req -x509 -sha256 -days 365 -in csr.csr -out certificate.pem

Pendant la phase de création du CSR, vous répondez comme vous le souhaitez aux questions, comme on est sur de l’autosigné vous pouvez être créatif si ça vous chante 🙂

Et voilà, vous n’avez plus qu’à renseigner la clé et le certificat dans votre Virtualhost par défaut, comme ça, si vous interrogez l’IP de votre serveur web, c’est ce certificat « placeholder » qui apparaitra (autosigné certes, mais certificat quand même) et ça masquera le reste de vos virtualhosts, parce que sinon le serveur web présente le premier chargé dans les configurations incluses (je me demande si j’en ferai pas une démo en live tiens…).

Vérifier la correspondance clé/certificat

Oui je sais ça parait con, mais ça m’est déjà arrivé une quantité beaucoup trop importante de fois de ne pas être certain qu’un nouveau certificat à installer correspond encore à la clé qui est déjà déployée, ou si une nouvelle clé à été générée pour l’occasion. La joie de l’infogérance et des tickets traités par plusieurs admins successivement.

Idem, quand on cherche les manipulations à effectuer, on trouve quasi systématiquement la méthode basée sur le modulus. Sauf que cette méthode est propre à l’algorithme RSA, et n’est donc pas applicable pour des courbes elliptiques. Malgré tout, on peut s’en sortir. L’astuce consiste cette fois à comparer la clé publique entre la clé et le certificat. D’abord pour la clé :

openssl ec -in key.pem -pubout |openssl md5

openssl x509 -in certificate.pem -noout -pubkey |openssl md5

Si les deux résultats sont identiques, vous pouvez les charger dans le serveur web (ou dans l’interface de votre fournisseur d’infrastructure, si vous êtes dans le claude).

La génération pour Let’s Encrypt via acme.sh

Let’s Encrypt (et certainement d’autres fournisseurs) supporte les courbes elliptiques depuis un moment déjà. Personnellement, je préfère utiliser le léger acme.sh plutôt que l’officiel certbot, que je trouve particulièrement lourd. La génération est plutôt simple :

acme.sh --issue --ecc -k ec-384 -d www.domain.tld -w /var/www/ --debug

Évidemment c’est à adapter au domaine, et au dossier par lequel il va bosser le challenge. Perso je préfère ensuite faire une installation dans un dossier dédié pour inclure la commande de rechargement du serveur web derrière :

acme.sh --install-cert -d domain.tld --fullchain-file /etc/nginx/ssl/domain.tld.crt --key-file /etc/nginx/ssl/domain.tld.key --reloadcmd "systemctl reload nginx"


Voilà, comme on le voit, il ne faut pas grand chose pour passer à cette méthode cryptographique, et investiguer à son sujet est à peu près aussi simple qu’avant. Juste je trouve qu’il y a vraiment peu d’articles qui incluent les courbes dans les manipulations. Bon ben voilà 😀

  •  
❌