13 septembre 2014

Construction d'un tourniquet (2/?)

Seconde étape de mon projet "construction d'un tourniquet", le support de rotation du jeu de plein air. 

Le moyeu va se retrouver en position verticale. Son arbre sera planté dans le sol, pris dans un socle de béton qui assurera la stabilité de l'ensemble. Pour assurer la liaison, j'ai soudé (ce qui restait de) l'arbre du moyeu au second moyeu, en mauvais état celui-ci mais en bon acier bien lourd et avec 5 perçages qui feront une parfaite fixation au sol.


J'ai justement profité d'une occasion "le bon coin" pour m'offrir un poste à souder à l'arc, 50€ c'est pas la peine de se priver. Bon, c'est pas du grand art, clairement j'ai bien fait de choisir "informatique" et pas "métallurgie, mais ça tiendra ;-)

Reste plus qu'à remplir la bétonnière pour réaliser le socle. 4 sacs de béton prêt à gâcher et 5 tiges filetées prises dedans pour la fixation, et roule ma poule. Je suis aussi passé chez Rubion acheter un bout de tube, mon "poteau" étant vraiment trop trop moche. J'arrive à un résultat solide et propre, malgré mes soudures dégueulasses (que je cacherais sous une petite couche de mastic)


Histoire d'amortir l'achat du poste à souder, je fais aussi un support digne de ce nom à la plaque qui viendra couvrir le tourniquet, sur base de jante (celle de la charrette d'origine). Ca commence à ressembler à quelque chose, et les gamins on déjà validé le prototype.


Prochaine étape : d'une part mastic et peinture, de l'autre réalisation et fixation du plateau.

11 septembre 2014

Docker : Build vs Run

Dockerfile allows to build a Docker image using a pure text approach, for sure not comparable to Puppet/Chef recipes power, but anyway a major topic in Docker adoption.

Lot's of developers first use Docker to reproduce target environment on local machine, as a simpler and lightweight alternative to vagrant/virualbox. They can test application on local workstation using a Dockerfile that looks like :

FROM centos

RUN apt-get -y install tomcat7
COPY target/foo.war /home/tomcat/webapps

CMD catalina run


For them, Docker is used to run application in an environment that is mostly equivalent to production server, not to prepare deployment to a Docker production environment (some do, but most team are just running prototype, not actual docker production).


Others use Docker to get a strictly reproducible and self contained build system. Dockerfile is used to declare and setup all build and test tools involved in the build process. No need anymore to document the "how to build the project". docker build then replace the mvn install command as first command a developer will use when he joins a project.

They will use a Dockerfile that looks like :

FROM ubuntu:14.04

RUN apt-get -y install openjdk-7
ADD http://.../apache-maven-3.2.3-bin.tar.gz /opt
ENV PATH /opt/maven/bin
ADD ....

CMD mvn install


When you want to use both approach on same project, you hit a Docker limitation (so far, work in progress). You can't use a single Dockerfile to first build the application binaries from source, then create a separated docker image as production delivery to include it. I'm not sure what are Docker plan on this topic, maybe nested Dockerfiles ?

Anyway, here is a possible approach : your build system will have 3 sequential steps

  1. build the "build from sources" Docker image
  2. run this image
  3. build the "create application delivery" Docker image


the idea is to design the "build from source" Dockerfile so a docker run will export the built artifact. Simplest option is for it to just cat the binaries to stdout, so you run

docker build -t build-from-source . 
docker run build-from-source > app.war

Another option is to use docker cp command, to extract built artifact from the image. But this require the "build from source" docker image to be ran at least once as a container (can be a stopped container). That's probably due to the way "cp" command is implemented, attaching to the container.

Just like I can add a file from a ftp or http server hosting my binaries, I'd like the ADD Dockerfile command to support getting file from another image, maybe using a docker protocol scheme :

ADD docker://build-from-source:latest/build/target/app.war


I've created https://github.com/docker/docker/issues/7992 for this purpose. Comments and alternative ideas are welcome.

04 septembre 2014

Pas de javax.enterprise.configuration

Anatole Tresch a annoncé que la société qui l'emploie et soutien son activité au sein du JSR, Crédit Suisse, ne désire pas soutenir le développer du TCK et de l'implémentation de référence de la spec "java configuration", coupant l'herbe sous le pied à cette proposition.

Faut il pleurer ? Je ne pense pas. Cette spec vise à formaliser une API d'accès à des données de configuration des applications JavaEE, avec évidemment de nombreuses interrogations sur l'impact avec CDI et les diverses specs/frameworks qui proposent déjà ce genre de choses.

Pour ce qui me concerne, une spec limitée à Java EE sur un thème aussi fondamental n'a aucun intérêt. Par ailleurs, comme je l'ai déjà indiqué sur ce blog, la spec se concentre sur l'interaction du code de l'application avec la configuration, et non sur la gestion de la configuration des applications. Choisir de standardiser apache commons-configuration ou spring-truc n'a pas un grand intérêt amha, par contre définir comment déclarer de manière standard la conf de mon appli sur mes instances de production, là j'y vois une valeur ajoutée.

A ce jour, j'utilise tout simplement des System properties, qui suffisent très largement à tout ce dont j'ai besoin. Une petite couche utilitaire pour convertir ou injecter ces données ne serait pas de refus, mais pas indispensable. Les plateformes Cloud fournissent toutes un moyen de définir ces propriétés système pour une application, permettant à l'application d'être vierge au moment de son packaging, et non de se coltiner un N-ième deployment descriptor.

Bref, bye bye Java EE Configuration, tu ne me manquera pas.

02 septembre 2014

Construction d'un tourniquet (1/?)

C'est la rentrée des classes, et donc le jour où je pense très fort à mes gamins, à tel point que j'ai eu l'idée de leur construire un tourniquet (oui je sais, ça aurait été plus utile AVANT l'été).

En fait je vais bientôt avoir un voisin (sic) dans ma campagne profonde, car la ferme en ruine un peu plus bas est en rénovation. En déblayant le "jardin", le futur propriétaire a trouvé sous les ronces une vielle remorque pourrie, dont il m'a offert l'essieu à moitié carbonisé.

Après démontage, l'un des moyeux s'avère bien grippé, mais l'autre encore en bon état. Planté verticalement il servira d'axe de rotation au tourniquet. Un petit passage par 123roulements.com pour commander de nouveaux joints et ça devrait faire l'affaire.


Prochaine étape : le socle - mais en attendant, fin de la pause, j'ai aussi un "vrai" boulot dans la vie...


La question qui tue : vais-je exploser le record de fréquentation de ce blog, jusqu'ici détenu par mon article "comment creuser un puit", loin devant les sujets Docker, Maven et compagnie ? 

31 août 2014

Maven release hell

As my daily work I contribute few bug fixes to jenkins plugins and officially maintain some of them, so have to run the release process so a new version is available in Jenkins update-center and my customer can get the fix.

maven-release-plugin rely on maven scm adaptor fir git command line client, and there's some odd incompatibility with recent git releases, so if you don't run "latest" you end up with some broken release. What I used to see is release tag created and pushed to origin, but no release commit.



The option I used to apply to fix this with the plugins I maintain was to force the release plugin version in pom.xml. Anyway this doesn't make much sense imho to pollute the pom with such a local issue.

Took me a while, but I re-discovered I can just force the plugin version to be used by passing the full GAV to maven command line :

mvn org.apache.maven.plugins:maven-release-plugin:2.5:release:prepare
mvn org.apache.maven.plugins:maven-release-plugin:2.5:release:perform

This is a tip I should include in my book ...

27 août 2014

Docker "official" images

DockerHub aim to host all Docker images and be Github equivalent for binaries. The immediate side effect is anyone can push a docker image and give it a name within his namespace. For sample, I have my own ndeloof/jenkins and ndeloof/java images on DockerHub.

Most users get confused with this and expect some way to filter them and only use some mature/stable images. Docker answer is the "official" certification for docker repositories, only letting mysql developers push the mysql image (without a user namespace prefix). Sounds good ... so far.

I just discovered the official java image : https://registry.hub.docker.com/_/java/
Who is owning Java ? Oracle would probably be the only one who would claim for this unique name as an official docker image provider, due to trademark ownership. Also, there's no description set for this official image - bad practice, a description should be a requirement to be an "official" image. Looking further at the Dockerfile for this image I notice this is actually an openJDK image, unrelated to Oracle, without any reason for this one to own the "java" name.

There's also an official jenkins image, created by my colleague Michael. Dockerfile is hosted on CloudBees github. For sure it's open to contributions, but not managed by jenkins-ci.org community, so I wonder how "official" this one is versus any other jenkins image and why it has been approved (according to this, based on face-to-face discussion).

Makes me thing Docker team is doing it wrong, letting arbitrary user claim for official ownership, without enough guarantees. As Maven central was growing, the process asked user to prove ownership on domain name, before they were able to publish under a specific groupId. I think Docker should adopt a comparable rule : you should not be able to publish an "official", namespace-less docker image for a product you don't own - easy for trademarks, not so simple for open-source projects.

Without stronger rules, I'm afraid Docker repository will become a mess of some-way-official-but-not-really Docker images, as well organize as my office :



25 août 2014

Deux mois avec la google watch

Les participants de Google IO ont reçu une Google Watch. J'ai choisi la Samsung plutôt que la LG, car elle dispose d'un capteur cardiaque, ce qui ouvre la porte a des applications orientées "wearable".



Je ne la porte pas systématiquement, mais suffisamment pour vous offrir un retour d'expérience :

TLDR; la google watch est un gadget rigolo, mais amha pas suffisamment réfléchi dans un esprit wearable.

Prise en main

L'utilisation de la Google Watch est basée sur un écran tactile. On fait glisser des "cartes" depuis l'affichage du cadran horloge en fonction des notifications et des actions demandées. Ceci a un effet pervers immédiat : il faut avoir les deux mains libres ! De ce point de vue le téléphone dans la poche et les applis android bien conçues (actions accessibles avec le pouce) sont plus pratiques.
-1

Utilisation

Le téléphone transmet les notifications sur la montre. Un petit vibreur attire l'attention, une nouvelle carte est disponible et s'affiche en base du cadran. Un glisser permet de la consulter ou de l'archiver. C'est très pratique lorsqu'on reçoit un SMS, mail prioritaire, rappel de rendez-vous, rappel de billet de train, etc : on peut consulter rapidement et le portable reste dans le sac.
+5

Google Now est intégré pour une commande vocale. Personnellement je n'ai jamais réussi à envoyer un SMS de cette manière. Pour la recherche web c'est équivalent au téléphone, avec bien évidemment un affichage micro pour les résultats de recherche.
-1

Autonomie

L'autonomie est suffisante pour tenir une journée, mais guère plus. Pour la recharger il faut un socle spécifique, et pas juste un micro-usb standard. Autant dire que le socle reste donc à l'hotel, et qu'on ne peut donc pas s'offrir une recharge en cours de journée, et bien sur qu'on risque de le perdre. Sans doute un problème spécifique à la Samsung. Bonne surprise par contre, l'activation du BlueTooth (low energy) ne pompe pas excessivement la batterie du téléphone, qui garde une bonne autonomie.
0

Confort

La luminosité de l'affichage a beau s'adapter à l'environnement, par temps lumineux on n'y voit rien, de nuit on se retrouve avec un phare accroché au poignet. S'il convient à un téléphone qu'on ne sort que lorsqu'on en a besoin, ce type d'écran est totalement inadapté amha à une montre.
-1

Autres

C'est très geek, le contrôleur SNCF est un peu désemparé lorsqu'on lui présente le code barre du billet sur la watch. Mais ils vont vite se lasser :P Bravo au passage à capitainetrain pour l'idée :D
+0

Le capteur cardiaque est un gadget inutile, pas fiable du tout (deux mesures consécutives donnent 50% d'écart). S'il indique clairement ne pas être adapté aux données médicales, ne comptez pas non plus dessus pour votre application d'entrainement sportif.
-0

Applications

Les applications que j'ai vues jusqu'ici ne sont pas réellement pensées pour la watch. On a un écran déporté, plus petit, mais globalement ça reste un écran tactile comme sur un smartphone. J'aurais aimé y trouver la recherche d'une ergonomie différente (hey, facile à dire, pas vrai ?)
-0

Bon, jusqu'ici pas grand chose de positif, mais le pire est à venir :

Avis général

La montre, comme toute montre (sic) se porte sur le plat de l'avant bras. Or cette montre là vous notifie de vos messages, rendez-vous, etc. On a donc assez régulièrement des bzzz dans le bras, et possibilité d'avoir un aperçu sur le cadran. Fonctionnement c'est très pratique, ça permet de laisser le téléphone dans le sac plutôt que d'encombrer les poches. Par contre, si vous regardez votre bras, vous constaterez que vous le voyez naturellement par son trois quart profil. Autrement dit, la réception d'une notification se traduit pas un coup d'oeil accompagné d'un mouvement de rotation du poignet, pas du tout discrète et très perturbatrice pour votre interlocuteur du moment.

D'un point de vue ergonomie, vis à vis de cette fonction de notification qui est amha la seule valeur ajoutée actuelle de la watch, l'écran devrait être arrondi et légèrement déporté sur le côté du bras, sous forme de bracelet, pour être systématiquement dans l'axe du regard, un peu comme la Nexd :



En conclusion, je ne suis pas convaincu que ce gadget, sous sa forme actuelle et sans applications plus finement adaptées, ai un grand succès. Je porte la mienne de temps à autre, sans plus de conviction, en supposant que j'ai pensé à la mettre en charge, et plus pour me la jouer que pour son utilité. Elle sera rapidement remisée avec mes anciens téléphones.

03 juillet 2014

NFC, le retour

Après diverses recherches, j'approfondis la question du paiement sans contact et de la sécurisation associée.



Je me base entre autre sur cet article qui explique en détail les différentes sécurités utilisées sur une carte bancaire.

Donc la bande magnétique d'une CB comporte vos infos bancaires, plus un code de contrôle qui est le résultat d'un DES(numéro, expiration, code service, clé secrète banque).

Ce code est lu par tout les lecteurs de piste CB, et peut être rejoué tel quel - sécurité 0 contre la copie, mais aujourd'hui les paiements sur le Net ne sont plus possible sans le code de contrôle visuel.

Le "code de contrôle visuel" est issu du même principe avec un code de service différent. Il permet de vérifier que vous êtes bien en possession de la carte bleue. Il n'est pas en relief et est (sauf chez Amex) imprimé au dos, donc relativement à l'abris. Si vous êtes parano vous pouvez le gratter, comme ça pas de risque en cas de vol.

La puce NFC utilise un code généré dynamiquement (dCVV) ce qui évite de rejouer le même échange NFC comme on pourrait copier une piste magnétique. Ce code n'est donc pas identique à celui qu'on trouve sur la piste magnétique, et ne permet pas de reconstituer une fausse carte bleue sans effort.

Sauf que ... la compatibilité ascendante est nécessaire au niveau des terminaux de paiement, aussi vous pouvez utiliser les données issue d'un échange NFC pour forger une piste magnétique valide (voir cet article - le lien vers la replay demonstration est malheureusement mort). La sécurité est alors basée sur le bon comportement du terminal de paiement (y compris l'appli reliée au dongle Square) qui va rejeté la piste pour code service inattendu. Ou bien la banque qui va savoir que le commerçant X a un lecteur n'acceptant pas le NFC. Bref on voit qu'il y a de possibles failles en choisissant bien chez qui tenter l'escroquerie.

Autre sécurité, la piste magnétique ainsi créé ne pourra servir qu'une seule fois et avant que l'utilisateur de la carte n'ai fait un paiement avec en NFC. Ça doit laisser un peu de temps tout de même pour s'en servir et faire un gros achat, genre envoyer les données collectées frauduleusement à un cousin aux US qui imprime illico un bande magnétique (facile, la clé de votre hotel est faite comme ça) pour s'en servir dans l'heure qui suit ... oui je vois le mal partout :)


Bref, tout n'est pas tout noir, mais c'est tout de même loin d'être tout blanc.


02 juillet 2014

maven/docker jungle

Docker office in San Francisco looks like a Jungle. I'm not sure that's the sole reason to explain profusion of maven-docker plugins in the wild.


Just searching github (I assume nobody uses google code anymore) gives a dozen candidates, some of them being just empty repositories.

So, here is a quick exploration for available plugins. All of them let you run and stop containers for integration test phase.

Alex Collins (https://github.com/alexec/docker-maven-plugin com.alexecollins.docker). 
Let you build a set of containers as part of a maven build (overriding the docker "build" terminology to follow maven "package" one). Uses a proprietary yaml descriptor, and rely on a custom fork (sic) docker-java client library, that doesn't support unix socket (default docker daemon protocol on localhost). 

Wouter Dance (https://github.com/wouterd/docker-maven-plugin net.wouterdanes.docker)
Comparable to Alex plugin but based on it's own REST client library to talk with docker daemon. So require you to choose between local or remote docker - same issue with unix socket.

Eduardo de Vera Toquero (https://github.com/etux/docker-maven-plugin es.devera.maven.plugins)
Just a maven wrapper to Docker commands

Can create a data container with built artifacts, as define by a (mostly standard) maven assembly descriptor, and then mounted into containers. Uses a custom REST client - still no support for unix socket.

Bilgin Ibryam (https://github.com/bibryam/docker-maven-plugin com.ofbizian)
A wrapper to start and stop existing docker images as part of a maven build. No support for unix socket.

Let you add artifact built by maven to an existing base image, and set entrypoint. Typical use-case is you have a generic base image with your app-server runtime, just need to add the application WAR. Can also use a full Dockerfile. Relies on spotify docker client (not sure about unix socket support, seems not implemented).

Vojtěch Juránek is also working on some plugin, but not released yet.

Imaginate Labs (https://github.com/imaginatelabs/docker-maven-plugin) develop an alpha-stage docker/vagrant plugin. Not sure I like such a combination of a VM manager + Docker within a build.


Most of those plugin are just wrappers to run docker, could just be replaced with maven-exec plugin to run equivalent docker commands, and without restriction on docker daemon unix socket. I don't think it's "cleaner" to write such a docker execution as xml in a pom versus just get the right tool executed as-is. This just introduce expectation to get the same result, but actual differences, like lack of unix socket support and/or docker API mismatch.
So, as a resume, none of those plugins make me feel I need one to use docker within my maven project. Spotify and RHuss plugins are the sole one to hack the docker build process and provide some added value: They both try to concile an actual maven packaging workflow with a docker image build.

Make me also think jenkins way to encourage people to contribute on same github organization and contribute vs re-create existing plugin on their own is a good model. Codehaus Mojo was initially designed for this purpose but clearly isn't attractive/flexible enough to embrace developer enthusiasm.

01 juillet 2014

Carte bleue NFC

Après renouvellement de ma carte bleue j'ai découvert qu'elle était équipée d'une antenne NFC, qui permet le payement sans contact. Première surprise, ce paiement se fait sans que je valide quoi que ce soit, ce qui ne m'a pas tellement plu. Mais je suis rassuré en lisant http://www.cartes-bancaires.com/spip.php?rubrique81 :


Puis-je faire une transaction sans contact sans m’en rendre compte ?
Non, il est impossible d’effectuer un paiement sans contact sans le vouloir. En effet, c’est vous qui déclenchez le paiement en approchant votre carte à moins de 3 à 4 cm du terminal du commerçant pour valider le montant inscrit. Au-delà de cette distance votre carte sans contact ne peut-être activée. Vous restez donc maître de vos paiements sans contact. En outre, toute transaction sans contact se conclue par l’émission d’un ticket de 
caisse.
Ah ben s'il y a un ticket de caisse, alors tout va bien.

Seconde surprise, après quelques recherche : les données de ma carte sont envoyées en clair via le protocole sans fil, sans aucune forme de sécurisation. Un peu comme quand le stagiaire vous dit que le mot de passe est sécurisé par encodage Base64, mais en pire.

Donc en gros, les infos de la bande magnétique de la carte sont exposées sans contact a quiconque passe à proximité. Car si le protocole NFC est limité à quelques cm avec une antenne compacte - comme celle intégrée dans la carte bleue - un récepteur bien pensé et bien amplifié doit permettre de capter sans problème depuis le fond d'une poche ou d'un sac à main en profitant de la promiscuité d'un métro à l'heure de pointe. Vous pouvez lire ici une explication détaillée sur les limites techniques de distance en NFC.

On me répond que le débit est limité à 20€, mais là n'est pas le problème (encore que...). En laissant ainsi mes coordonnées bancaires exposées, je permet à un malveillant mais ingénieux bricoleur (avec un tonton dans la mafia) de collecter des données valides pour fabriquer de vraies-fausses cartes.

Et non, tout le monde n'utilise pas la puce de la carte bleue et la validation par code PIN. Allez faire un tour aux USA pour vous en convaincre - ils sont en avance sur pas mal de sujets, mais clairement sur le payement par carte c'est la préhistoire. En 4 jours à San Francisco pendant Google IO, j'ai effectué une dizaine de paiements par carte par seule lecture de la bande magnétique, et même un avec le "fer à repasser" que les moins de 30 ans n'ont sans doute jamais vu.

Une seule fois (sic) on a noté le code de vérification (les fameux trois derniers chiffres au dos). Par ailleurs, le succès de Square qui se base aussi sur la seule bande magnétique est révélateur.

J'ai adopté une solution un peu radicale pour "désactiver" l'antenne NFC (on peut faire plus propre), sinon il parait qu'on peut demander à sa banque un échange contre une carte sans NFC - avec des frais bien évidemment.

Mais bon rassurez-vous, votre forfait de services bancaires inclut une assurance contre utilisation frauduleuse de votre moyen de payement, bien plus utile que de mettre en place une solution techniquement fiable...





30 juin 2014

Debugging a Docker container

So you can run your (put your favorite language/framework here) application within a Docker container, that's cool. Now, how do you debug it ?

This is feedback I got from my colleague Cyrile, trying to port his Tomcat 8 runtime from RUN@Cloud to a Docker-based environment. He use to integrate the tomcat appserver with syslog and capture thread dumps at runtime with a kill -3 signal sent to the JVM.

Few days ago I'd have suggested him to instrument his Docker image with tons of additional diagnostic tools and extra ports, but I've read Jerôme's blog in the meantime.

So, application is running inside a Docker container :

➜ ~  docker run -d dgageot/helloworld
1cbe9740baa45279eb775d2e0df5a12e5807c112ec382b3bdb20695df429854e

I'll use nsenter and Jerôme docker-enter to add a new diagnostic process to my container. Please remember a container is not a classic Virtual Machine, but "just" a group of process sharing a common Linux kernel namespace. nsenter let you add another process to the group, so can be used to attach a new shell session to the running container.

As I'm running boot2docker and this one don't have nsenter pre-installed (it should imho), I'm installing it directly from Jerôme Docker image :

➜  ~ docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
Unable to find image 'jpetazzo/nsenter' locally
Pulling repository jpetazzo/nsenter
...
Installing nsenter to /target
Installing docker-enter to /target

docker-enter script makes it even easier to use nsenter in a docker context, just need to know the docker image ID. So let's ssh into boot2docker and use this script to access the running container.

➜  ~ boot2docker ssh
Warning: Permanently added '[localhost]:2022' (RSA) to the list of known hosts.
                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \______ o          __/
             \    \        __/
              \____\______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
boot2docker: 1.0.0
             master : 16013ee - Mon Jun  9 16:33:25 UTC 2014


docker@boot2docker:~$ sudo docker-enter 1cbe9740baa45279
# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:12 ?        00:00:04 java -jar target/hello.jar
root        22     0  0 14:19 ?        00:00:00 -sh
root        25    22  0 14:19 ?        00:00:00 ps -ef

I now can use my favorite diagnostic tools to check application health.
# jstack 1
2014-06-30 14:20:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.5-b02 mixed mode):

"Attach Listener" #15 daemon prio=9 os_prio=0 tid=0x00007fbfa0001000 nid=0x25 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

Cool, isn't it ?
As you maybe noticed, this require to be root on host, so for your production server you might consider reading Jerôme's article carefully and consider using the ssh command= option with a dedicated ssh key for production diagnostic.

I'm considering using this exact same mechanism in a Jenkins plugin so user can provide arbitrary image for build environment, without requirement for a sshd server (like docker plugin does).


13 juin 2014

Ce gars est un grand malade - et il n'est pas le seul

Quand on vous dit que les choses vont très vite dans l'écosystème Docker ...

Il y a quelques heures, David publiait son fiboid à base de docker imbriqués, il n'a pas fallu attendre bien longtemps pour voir les premiers commentaires, et en particulier celui de Solomon Hykes, fondateur de Docker...

Imbriquer des conteneurs Docker c'est possible mais évidemment on send que ce n'est pas une solution très "naturelle".

Docker étant basé sur un démon, auquel parle un client (la ligne de commande docker, ou tout autre client via une API REST), il est plus simple d'expose le démon de l'infrastructure aux containers qui ont besoin de lancer d'autres containers.

L'idée est simple : monter dans le container le socket exposé par le démon.
-v /var/run/docker.sock:/var/run/docker.sock

Du coup, quand dans un container qui a été outillé de cette façon on lance une command "docker run ..." c'est le démon de l'hôte qui va répondre, et lancer un nouveau container, non plus imbriqué, mais côte à côte. Plus besoin de bricoler pour pourvoir faire tourner un démon docker dans le container, exposer les cgroups, etc. C'est tout de même un peu moins "hack-ish" :P


Deux petits schémas pour résumer ça :

Lancer un container DANS un container - possible, mais on sent comme un truc pas net

Lancer un container DEPUIS un container - clean, et plus besoin de --priviledge





Fiboid - ce gars est un grand malade

Lors de notre session au Ch'tiJug, expliquant entre deux anecdotes que Docker peut même être lancé à l'intérieur d'un autre container Docker, on (amis, j'ai oublié ton nom) nous a suggéré de faire un calcul récursif de suite de Fibonacci via des containers Docker.

Il n'en fallait pas autant pour lancer David sur la piste d'un projet aussi inutile qu'indispensable, dont il a publié le résultat : https://github.com/dgageot/fiboid "Fibo Inside Docker". Ce gars ne dors jamais, ou bien il est vraiment cinglé, ou peut être les deux, en tout cas svp ne l'encouragez pas.

A quoi ça sert ?

Sur l'exemple de David : a rien - enfin si, à tester la capacité de Docker à fonctionner en mode "poupée russe" et voir jusqu'où il peut aller.

Dans l'absolu, je suis longtemps resté perplexe, mais j'ai depuis vu passer plusieurs usages.


1. Builder des images Docker.

eBay a adopté Mesos et Docker, et a publié un papier dessus. Depuis Jenkins, un container Docker est donc lancé sur le cluster Mesos pour héberger chaque build. Jusque là, c'est simple, sauf que ce build veut lui même construire et tester des images Docker, et va donc lancer Docker dans l'image Docker. On a donc un premier niveau d'imbrication.

2. Packager un environnement multi-noeud.

Tester rapidement un project composé de N containers, ça signifie aujourd'hui fournir N images Docker et le script de lancement qui va bien (voir aussi le format containers.yml de Google). Une autre façon de faire, c'est de définir un Dockerfile qui lance les N conteneurs Docker de l'application. A nouveau, imbrication de containers

Je suppose qu'il y a plein d'autres cas intéressant à inventer.

Là ou fiboid est intéressant, c'est qu'il montre COMMENT imbriquer les containers. Car l'approche naïve que j'ai moi aussi testée dans le TGV qui me ramenais à Rennes, coincé entre deux valises d'un wagon bondé, c'est de lancer sans plus de scrupules "docker run" dans mon Dockerfile - sauf que ça ne marche pas. Sans 3G et avec les cuisses qui cuisent, je n'ai pas insisté :'(



Il y a en effet une petite manip pas triviale, résumée dans l'exemple de David par le script startdocker

Le premier truc à savoir c'est qu'il faut que le container tourne en mode "privilégié" pour pouvoir exploiter les containers (auxquels il est lui-même soumis), à savoir les API cgroup, les restrictions AppArmor, etc (je ne détaille pas car je n'y connais rien).

Ensuite, exploiter les cgroups depuis un container nécessite un minimum de collaboration avec l'hôte qui porte le container courant. Il faut donc synchroniser les cgroups du container avec ceux de l'hôte. Le reste du script est lié a divers raffinements et contournements, pour finalement lancer un démon Docker dans le container, qui permettra de lancer la commande "docker run" comme prévu.

Le principe d'imbrication des containers a été démontré initialement (afaik) par Jerôme Petazzoni, dont David a repris la recette. Le script wrapdocker ayant 3 mois, soit une éternité dans le contexte de Docker, il est possible que certains hacks ne soient plus nécessaires. Si quelqu'un en maitrise les détails, faites lui une pull-request :)





12 juin 2014

Docker Security

A moins de vivre dans une grotte, vous n'avez pas pu rater l'annonce de Docker 1.0-FINAL production ready.

Il y a tout de même un petit bémol à prendre en considération sur ce "production ready".

Docker utilise les capacités du noyau Linux pour isoler et contrôler des groupes de process (respectivement : namespaces et cgroups). La promesse est donc que chaque container se comporte quasiment comme une VM, en beaucoup plus léger, assurant l'étanchéité et l'indépendance de chaque application par rapport à ses voisines qui sont au final co-locataires de la machine hôte.

Seulement dans la vraie vie, il reste une issue non encore résolue : pour lancer un container, il faut être root. Les process qui tournent dans le container sont root (le root du container) par défaut. On peut bien sur tourner dans le container avec un autre user, mais si on autorise à faire tourner n'importe quelle image, on doit partir du principe que l'utilisateur du container est root - ou peut le devenir en hackant son container en installant volontairement un soft dont il connait une faille de sécu, il ne suffit donc pas de forcer le USER.

Que se passe t-il si notre utilisateur dans le container, qui s'y connais bien et a des intentions indélicates, arrive à sortir du conteneur, exploitant la faille X de la version Y du noyau pas encore mis à jour sur l'infra ? Et bien notre petit malin va se retrouver root sur la machine hôte - et ça c'est pas glop. Tiens d'ailleurs, si quelqu'un connais une (vielle) version du noyau / distro qui aurait un bug de ce type ce serait sympa pour en faire une démo.



Cette contrainte, on peut vivre avec, surtout sur des environnements privés : dans votre DataCenter, le risque d'un hack de ce type est quasi nul vu que vous ne déployez que vos propres applis. Sur un environnement réellement multi-tenant comme un Cloud public par contre ...

Le noyau Linux fournit le mécanisme de user namespace, qui permet à l'utilisateur root du container (id=0) d'être en fait l'utilisateur tartempion avec des droits standard sur la machine hôte. Le jail-break, sans être complètement anodin, n'a alors plus du tout le même impact.

Docker pourrait utiliser ce namespace, qui nécessite "juste" un noyau très récent. Vous pouvez lire les commentaires sur cette issue par exemple, qui n'aborde qu'une partie d'un possible fix, pour comprendre que ce n'est pas si simple, et qu'écarter ce point pour une 1.0 avait du sens. Comme dit plus haut, cela n'interdit pas d'utiliser Docker dans un environnement privé et contrôlé.

Par contre c'est un gros frein pour son utilisation massive par les hébergeurs Cloud, sauf à y adjoindre un autre niveau de sécurité. Sans surprise, le support Docker proposé par Google utilise une VM par déploiement, ce qui en soit est une régression de la part de l'éditeur qui utilise des containers en interne depuis presque 10 ans.



Je m'interroge sur les solutions retenues par les autres hébergeurs qui proposent du Docker aujourd'hui. S'ils veulent bien me contacter pour en discuter en privé je serais ravi d'échanger sur le sujet.

Vous pouvez aussi lire http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/ pour en savoir plus sur ce thème.

Regardez aussi cette vidéo qui montre ce qui se passe lorsqu'on sort du container et qu'on rencontre la protection SELinux, qui évite à "root" de devenir "root" :-\


11 juin 2014

DockerCon

Pendant deux jours, Docker a été à l'honneur avec la première édition de la DockerCon, à laquelle participait mon collègue Michael Neale que je maudis pour avoir eu une place et pas moi.



Pendant notre petit tour des JUG avec David Gageot, nous abordons en fin de session un "what's next" avec un gros disclaimer, de circonstance lorsque de l'autre côté de l'atlantique ont lieu des annonces officielles. 

Nous ne nous sommes pas trop trompés jusqu'ici, car les annonces majeures ce sont :

  1. Docker production ready 1.0 - ok, ça fait conference-driven-development, et un 1.0.1 va évidemment suivre, ceci dit la version 0.12 qui a précédé était déjà super-stable, donc ce n'est pas que du marketing.
  2. Des témoignages d'acteurs majeurs. RackSpace, NewRelic, Ebay, Twitter ... autant d'innovateurs qui ont déjà commencé a adopter Docker dans leur boite à outil. J'espère que vous allez leur emboiter le pas :)
  3. Le re-vamping de l'index (build et hébergement des images Docker) en "DockerHub". Michael a discuté avec eux de l'intégration Jenkins, présentée en keynote de la conférence. L'idée est de "laisser faire Jenkins pour valider une image, chacun son taf" et j'ai donc préparé l'indispensable plugin qui va avec, n'allez pas voir pour l'instant il ne fait rien :) Je vais surtout bosser sur une intégration OAuth propre, la partie "validation d'une image" ayant par définition une signification différente pour chacun.
  4. Des annonces en tout genre, entre autre le positionnement très fort de Google sur Docker. Il faut dire que Google est à l'origine de cgroup donc fait partie de l'écosystème des containers depuis un moment.
  5. De nouvelles briques pour l'écosystème Docker. Si vous avez vu notre prez', Docker gère le container mais laisse aux outils tiers l'orchestration de l'infrastructure. CoreOs et Mesos sont les gros-mots qui reviennent souvent sur ce sujet, mais l'équipe Docker a aussi lancé libChan (communication entre containers) et libSwarm (composition de services à base de containers).
Bref, nous n'avions certes pas tout prévu, et tant mieux, mais nous n'étions pas complètement à côté de la plaque :)


10 juin 2014

Votre avis nous intéresse (aka "LikeBox")

En tant qu'organisateur du BreizhCamp, un stress particulier concerne la programmation de la conférence. Les thèmes choisis reflètent-ils les attentes ? Notre sélection de speakers a t-elle été la bonne ?

Obtenir du feedback du public est donc indispensable. Nous avons testé le tableau de post-it pour collecter votre avis général sur la conférence, mais cela ne nous informe pas sur les sujets eux-même.

En 2013 nous avions placé en sortie de salle des feuilles de vote proposant trois smileys, et vous demandant de cocher celui qui correspond à votre état d'esprit. Si d'un point de vue logistique cette solution est simple, elle ne rencontre pas un succès terrible, peu de personne prenant le temps de s'arrêter pour choper un stylo, cocher, remettre le bouchon. Certains ont également regretté l'absence d'un mode d'emploi pour expliquer clairement nos attentes face à une feuille vierge.

Très clairement, la facilité et la rapidité de vote est un facteur important.

Lors de DevoxxFrance, Xebia avait mis en place des boitiers de vote à la sortie de chaque salle :



J'ai vu peu de monde s'attarder pour voter, même si les données recueillies ont été très utiles pour les organisateurs. Un souci important était de mon point de vue la complexité excessive du système :

  • 5 boutons, donc un choix assez délicat. J'ai du mal à imaginer que le bouton "très mauvais" ai beaucoup été utilisé. Le median non plus d'ailleurs, pourquoi s'arrêter pour voter si on a pas un avis spécialement tranché ? Accessoirement, sans repère visuel sur les boutons, leur sens n'était pas évident. Résultat, passer au vote nécessitait une réflexion et donc un frein à l'expression spontanée.
  • Une identification NFC, destinée à éviter les votes multiples. Si vous avez déjà vécu la sortie d'une salle Devoxx vous savez qu'on a guère le temps de voter, alors voter 3 fois ... Sans parler de la question fatidique "mais heu, c'est vraiment anonyme du coup ?


Leçon #1 : ne pas laisser trop de choix, sous peine de perdre en compréhensibilité et donc en spontanéité du vote, et au final en nombre de votants.

Leçon #2 : ne pas mettre en place de barrières à l'expression des votants. Le vote doit être quasi instantané et ne pas ralentir la sortie de la salle.

Leçon #3 : utiliser comme Xebia des pieds d'enceinte sono, solides et pas cher. 

Devoxx.be a de longue date tenté de récolter les avis des participants à chaud. La formule retenue est basée sur ce qui a participé au succès de FaceBook, les "like".


Ici aussi, on identifie le participant par puce NFC, cependant il n'y a que deux états "content" / "pas content". En 2013 ils avait rajouté au centre un capteur pour ajouter la session dans votre compte parleys, afin que les déçus de la salle pleine à craquer puisse avoir une seconde change offline.

Le système est simple, de compréhension évidente (surtout ce modèle avec les pouces intégrés dans la forme du boitier, mieux qu'en 2011). Le NFC reste un léger frein à la fluidité de la sortie de salle, et maintien une certaine interrogation sur l'exploitation des données personnelles,mais globalement le système fonctionne bien.

Leçon #4 : proposer une user-interface aussi explicite que possible.

Leçon #5 : le côté Geek du matos apparaissant en transparence est un élément clé de l'intérêt du public à expérimenter les systèmes de vote. De ce point de vue le boitier en alu brossé utilisé par Xebia était contre-productif (sans même évoquer les problèmes de masse qui leur a plombé leur nuit pré-devoxx).


Pour JavaOne, les organisateurs avait mis en place des boitiers avec 4 boutons de vote, du vert au rouge avec un joli dégradé de smileys.



J'ai vu bien peu de personnes prendre le temps de voter sur ces boitiers, mais l'approche est simple, explicite, et saine sur la nature des "données" fournies au système. Ici je passe devant et j'ai juste à mettre un coup de poing sur le bouton de mon choix.

Pour le BreizhCamp, nous n'avions pas l'intention de faire des bracelets avec puce NFC, entre autre en raison du coût de ces gadgets. Une solution de ce type était donc clairement ce qui nous correspondait le mieux.

Comment éviter les votes multiples ? D'ailleurs, qu'est-ce qu'un vote multiple ?

Celui qui est super-super-content et va rester 3 minutes devant la machine pour exprimer son contentement en votant 10 fois, finalement fournit une information utile. Le tout est de savoir l'exploiter (problème de BigData :P). Evidemment il y a le cas du Aurelien qui durant toute sa pres' vient voter +1 chaque minute, mais ça reste un cas isolé et très facilement identifiable.

Nous avons donc défini notre cahier des charges :


  1. le boitier doit être d'utilisation limpide, sans aucune interrogation sur sa bonne utilisation. Deux boutons +1 / -1 suffisent, et obligent à se positionner plutôt qu'à voter "neutre".
  2. le vote doit être physique, par bouton, pour être rapide et implicitement anonyme. 
  3. le double vote involontaire (rebond du bouton) doit être évité, pas forcément le vote multiple absolu
  4. le boitier doit être geek, fun, donc transparent. L'idée est rapidement venu d'intégrer leds / bip / écran pour signaler la prise en compte du vote.
  5. le boitier doit être costaud. Bouton coup-de-poing industriel, plexi de 8mm, pied d'enceinte 50kg.
  6. le CPU dédié à enregistrer les votes ne risquant pas la surcharge, la sortie vidéo HDMI est exploitée pour afficher programme, tweetwall, etc
  7. l'accès réseau se fait en filaire. Nous savons tous ce que donne le Wifi en conférence.

Dans la pratique il s'agit du cahier des charges a posteriori, ce projet ayant été conçu entre deux emails de manière très informelle.

Pour la réalisation, je vous met entre les mains de Laurent qui explique ça mieux que moi. Ma contribution a surtout consisté à découper au dernier moment les plaques de Plexy (d'où une finition douteuse) avec l'aide de Julien (7 ans, d'où un alignement des perçages ... hasardeux)


Nous avons également réalisé un test grandeur nature en nous mettant à trois en file, imitant une sortie de salle, pour valider les timings anti-rebond, l'affichage du LCD, etc. 

Nous avons bien sur tout un tas d'idées pour améliorer ce produit, que nous avons nommé "LikeBox" :

  • Utiliser des cartes BeagleBone, plus puissantes que la RaspBerry, et plus classe (PCB noir, LED bleues) 
  • Donner à nos boitiers la forme de la box Internet de l'opérateur historique, ce qui suppose de cintrer du plexiglass de 8mm #challenge.
  • intégrer un port pour connecter rapidement une console de debug - nous avons eu quelques surprises
  • ...

Bref, encore quelques soirées bricolage en perspective...



Ce boitier, nous le mettons à dispositions des conférences amies contre un dédommagement symbolique et une entrée gratuite (:P) => likebox@breizhcamp.org


06 juin 2014

Windows Sucks

Un problème récurrent que les clients CloudBees reportent au support est l'utilisation de machines de build Windows. Nous recommandons clairement d'utiliser un Linux pour le master, mais bien sur il est nécessaire à de nombreux projets de faire tourner les diverses variantes de Windows comme "esclave" de build.

Jenkins offre de contrôler les slaves Windows via DCOM. Soucis, ce protocole historique a deux modes : "marche" et "marche pas". Autrement dit, une quelconque erreur de configuration se traduit systématiquement par un "Access is denied. [0x00000005]" sans plus d'explication.


Bien plus grave, les différentes astuces référencées sur le wiki et récemment mises au propre par Jesse nécessitent toutes de bricoler les droits système et le registre Windows, sans compréhension claire de l'impact de ces changements sur le système. Il n'est pas exclu qu'on ouvre par ce biais une énorme faille de sécurité. Bonus, il s'avère que les versions 64 bits de Windows se comportent assez différemment, et nous avons des retours assez étrange sur l'utilisation de Windows 8. Je ne vous parle même pas des versions "serveur" de Windows (dont je n'ai jamais compris ce qu'il a de "serveur" mais bon).

Nous décourageons donc à nos clients d'utiliser ce mécanisme. L'approche alternative utilise Java Web Start, autrement dit la création d'une connection à l'initiative de la machine Windows, ce qui coupe court aux problèmes de sécurité. Installé comme service windows, l'agent jenkins slave va donc se connecter au Jenkins master au démarrage. Dans de nombreux cas c'est très nettement mieux, cependant il s'avère que cette connection est parfois instable, pour des raisons encore inexpliquées, et bien difficile à diagnostiquer.



Une autre solution, qui s'avère plus stable, est de remplacer le slave Windows par un slave GNU/Linux. Pas de panique, je parle en fait d'installer Cygwin sur la machine Windows, pour la "GNU-ifier" et d'y faire tourner un service openSSH. La machine peut alors être contrôlée par Jenkins comme n'importe quel esclave Linux SSH, ce qui accessoirement unifie l'infrastructure de build.

Ce qui est triste dans l'affaire c'est de se dire qu'on aurait pas besoin de toute cette tambouille si Windows avait un server SSH natif :'(




05 juin 2014

Docker "Oignon" FileSystem

Pour présenter le mécanisme de fichiers 'en couches' utilisé par Docker (Union File System) David s'amuse à lancer un container ubuntu, faire un méchant rm -RF /, quitter le container et relancer la commande pour montrer que "de retour dans le containeur, le file système est clean".

L'effet attendu est atteint, à savoir faire prendre conscience au public, plus habitué à FAT32 qu'aux capacités des filesystems avancés de type ZFS, du mécanisme de copy-on-write et d'empilage de couches sur le filesystem en mode delta.

Pour ce qui me concerne, je présente souvent ce mécanisme comme du "oignon-filesystem" pour bien montrer ce concept de couches fines empilées, qu'on peut à volonté dépiler/empiler sous réserve de respecter le même ordre.


Nous jouons cependant un peu avec le feu en introduisant une fausse idée sur ce qui se passe. Histoire de rétablir un peu de rigueur, explication de texte :

Lorsque vous lancez docker run -i -t ubuntu /bin/bash, docker crée un container avec le filesystem ubuntu en read-only et active une "couche" AUFS en copy-on-write que vous allez modifier lors de vos actions dans le shell - par exemple via un rm -rf /.

Lorsque vous quittez le shell, le container s'arrête - mais il existe encore pour le démon docker, il est simplement à l'état stopped. Vos modifications sont bien là, stockées par AUFS, il n'y a juste plus aucun process qui y accède.

Lorsque vous relancez la commande docker run -i -t ubuntu /bin/bash vous créez un second container, strictement équivalent au précédent lorsqu'il a été lancé initialement. C'est d'ailleurs le point intéressant en termes de processus de développement / déploiement : la reproductibilité de votre livrable.

Cependant nous ne sommes pas à proprement parlé "revenus dans le conteneur". Nous pourrions par contre relancer le container initialement modifié avec la commande docker start  pour relancer le conteneur initial. Comme il n'est pas évident d'obtenir les ID des conteneurs ni de les mémoriser, si vous voulez jouer à ça je vous conseille de nommer vos containers.

Bon ceci dit, ceci est juste une petite mise au point théorique, dans la pratique relancer un conteneur arrêté n'a pas un intérêt énorme amha par rapport à la possibilité de relancer un conteneur tout propre, sachant que les données que l'on doit persister sont confiées à un volume, autrement dit un répertoire de l'hôte.

Le seul cas d'utilisation que je peux imaginer - qui est tout de même non négligeable - c'est le diagnostic post-mortem d'une appli que vous avez lancée via docker et qui s'est arrêtée. Docker start vous permettra alors de lancer un bash et d'aller inspecter le cadavre.



04 juin 2014

Containerization vs Virtualization

En accompagnant David Gageot pour un East-JUG-Docker-Tour nous avons pu discuter de nos approches de présentation respectives et de la difficulté de bien faire comprendre un concept fondamentaux qui est la clé de voute de Docker : les containers.

Tel que je le présentais jusqu'ici, vu les questions qui suivaient la présentation, il est clair que j'allais trop vite et que du coup le message passait mal. David a repris toute cette partie pour l'expliciter dans le détail avec démos d'illustration. Nous testerons le résultat sur le public Strasbourgeois ce soir ...

Une image m'a été suggérée par Guillaume pour illustrer la différence entre un container et l'approche "à la virtualbox". Je l'ai intégrée à la présentation, car c'est le genre d'image choc qui marque les esprits et aide donc à bien mémoriser le concept.



A propos d'image marquantes, une photo souvenir. Pour la petite histoire, dans le train qui nous transportait de Nancy au prochain JUG de ce East-Tour, scotchés à nos écrans à essayer de bosser un peu (tout de même) et entendant le haut parleur crachoter l'annonce "notre train va arriver en gare de S..a..bourg" nous sommes descendus sans broncher, même pas surpris par la taille très modeste de la gare. Le temps de réaliser notre erreur, le train était reparti. #Boulets




02 juin 2014

Docker-tour squatt

Suite au succès de la session "la révolution Docker" à Devoxx, je me suis proposé de faire un petit tour des JUGs sur ce thème. Après consultation des organisateurs, il s'est rapidement avéré que David Gageot avait eu la même idée (j'ai du rater un tweet ...). Je passe donc du statut de speaker à celui de ... squatteur.


Blague à part, cela devrait être enrichissant de comparer nos approches du sujet. Rendez-vous demain 4 juin à Nancy et mercredi 5 juin à Strasbourg.