01 novembre 2014

Retour sur le Docker Global Hack Day Rennais

J'ai lancé l'idée d'organiser une édition locale du Docker Global Hack Day. Ca a eu lieu jeudi soir, dans les locaux de SII, que je remercie pour leur soutien. Pour l'événement, Rackspace et DigitalOcean fournissaient des voucher pour tester leur infra Cloud, ainsi qu'OVH à titre local. Même pour des novices il y avait donc de quoi s'occuper.

La soirée n'a cependant pas tourné comme je l'espérais, aussi voici un petit éclaircissement sur mes commentaires sans doute un peu amers sur le meetup :

Il s'agissait explicitement d'un Hackathon : tu viens, tu code. A la fin, on présente ce qu'on a fait, Docker.com offrait même une place à la DockerCon au plus méritant.

Nous avions un trello avec des propositions de sujets. Plusieurs propositions de la plus simple à la plus hacky.

Sur 27 inscrits, 16 présents - ça je m'y attendais, c'est toujours comme ça, et 27 hackers c'était illusoire.

2 personnes m'ont contacté pour avouer leur manque de compétence sur Docker. Je leur ai indiqué que ça pouvait être accessible à tous mais qu'il fallait être prêt à s'impliquer.

Sur 16 présents, 4 n'ont pas de portable. Bon, on peut toujours binomer, mais on sent qu'il y a un loupé.

Après la présentation d'introduction, qui faisait un appel du pied pour binômer à poursuivre le sujet présenter (mise au point d'un Dockerfile, sujet accessible à un novice), je rappelle l'objectif de la soirée, chacun se présente, certains présentent le sujet proposé dans le trello, mais ... nous ne sommes que 4 à ouvrir le portable pour envisager de faire quelque chose de concret, 10 personnes réunies en cercle passent en mode "café du commerce" à discuter Docker.

22h, tout le monde rembale....


Je n'ai rien dit sur le coup, car malgré ma profonde déception plusieurs personnes étaient ravies de leur soirée et m'ont remercié pour le bon moment. Ca m'a coupé les jambes, je me voyais mal les renvoyer dans les cordes - après tout eux au moins ont pu profiter de l'événement.

Donc en résumé, si on avait organisé un BarCamp Docker ça aurait été un grand succès. Sauf que c'était un Hackathon, c'était marqué dans le titre et bien précisé dans la description de l'événement. J'ai du chercher un local accessible tard, me synchroniser avec l'équipe Docker pour faire livrer des T-Shirts Docker en urgence, pour avoir une édition Rennaise du Hacker Day, et je me retrouve avec un gros "rien" à présenter.

Je ne pense pas que le public Rennais soit moins enclin au hackathon que les autres. L'atelier java 8 au BreizhJUG en septembre a été un franc succès, certes en laissant moins chaque participant livré à lui même, mais tout de même du "mains dans le cambouis". Accessoirement je ne vois pas quelle spécificité locale ferait du Rennais une personne inadaptée à coder en dehors de son boulot quotidien en SSII...

Bref, vous l'aurez compris, je suis déçu et quelques peu déboussolé. S'il faut mettre des barrières à l'inscription pour n'avoir que des participants actifs c'est vraiment dommage. Je m'interroge sur la forme à donner à ce type d'événement pour éviter la dérive "je m'assoie au fond et je regarde". Si vous avez des idées...




26 octobre 2014

Docker network performances

I've ran some basic tests on Docker container network performances. I had discussions with KVM fan-boys on Docker network abstraction vs KVM para-virtualization network VirtIO, and they explained me virtio let KVM offer near-native network performances without the huge impact of a virtualized network stack.

Docker doesn't actual virtualize network, but use Linux Ethernet Bridge  so it can offer some basic SDN facilities. Anyway I wanted to check impact. 

Disclaimer : I'm not a network engineer, the few commands I've used for this micro-benchmark, I've learned them few hours before I publish this article.

I've used iperf with default settings for this benchmark. I ran my benchmark on a MacBook running Ubuntu 14.04 - natively, not as a VM (never use a VM for benchmarks) - graphic card bug on this machine crash OSX, but is fine to run Ubuntu so children can play MineCraft and I can run some native Linux tests :P

nicolas@MacBookLinux:~$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

Host to host network do offer 26Gb/s

nicolas@MacBookLinux:~$ iperf -c 192.168.1.23
------------------------------------------------------------
Client connecting to 192.168.1.23, TCP port 5001
TCP window size: 2.50 MByte (default)
------------------------------------------------------------
[  3] local 192.168.1.23 port 38470 connected with 192.168.1.23 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  30.8 GBytes  26.5 Gbits/sec


I've used an ubuntu:14.04 (same as Host OS) container, installed iperf on tagged as "iperf" for further usage.

I first used the default (bridge) network settings for my docker container. As a result, I get 13Gb/s, so a significant 50% degradation in network performances.

nicolas@MacBookLinux:~$ docker run -it iperf bash
root@7256f0f1da2b:/# iperf -c 192.168.1.23
------------------------------------------------------------
Client connecting to 192.168.1.23, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[  3] local 172.17.0.5 port 45568 connected with 192.168.1.23 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  15.6 GBytes  13.4 Gbits/sec

Switching to host network mode I get 22Gb/s, so small impact on performance but a reasonable one, offering near-native network performances with benefit for binary container image deployment.

nicolas@MacBookLinux:~$ docker run --net=host -it iperf bash
root@MacBookLinux:/# iperf -c 192.168.1.23
------------------------------------------------------------
Client connecting to 192.168.1.23, TCP port 5001
TCP window size: 2.50 MByte (default)
------------------------------------------------------------
[  3] local 192.168.1.23 port 38478 connected with 192.168.1.23 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  26.0 GBytes  22.4 Gbits/sec 


I also tried to run some tests with boot2docker VM, but VirtualBox degrades the network performances in a horrible way. I have an ubuntu VM running, configured to use a virtio para-virtualized network, here is iperf result accessing host :

nicolas@ubuntu:~$ iperf -c 192.168.1.13
------------------------------------------------------------
Client connecting to 192.168.1.13, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[  3] local 10.0.2.15 port 57202 connected with 192.168.1.13 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.1 sec  84.8 MBytes  69.6 Mbits/sec 

Please note this later test is ran on my OSX MacBook, so might have distinct settings that can affect results, anyway this seems to demonstrate VirtualBox do offer 300x slower network performances compared to native host-to-host. So don't rely on boot2docker for benchmarks. I got some better but still bad metrics using VMWare Fusion, but I don't know much this environment so not sure if this is relevant.

Update : I have no idea how Docker network perfs compare to a well set VM isolation layer, based on KVM with virtio. Just wanted to check Docker impact on network perfs.

Update : I just noticed on docker dev list discussions on using Open vSwitch with Docker, that is comparable to (legacy ?) linux bridge device but with a modern design. There were also discussions on using macvlan (register one MAC address per container on same network physical device IIUC).

18 octobre 2014

Upgrade to Docker 1.3.0

Après une chouette journée passé à bdx.io (je laisse le soin à d'autres de vous faire un résumé, parce que je suis  une grosse faignasse), retour à Rennes avec 6h de transport en TGV.

Pendant que Laurent bricole son nouveau jouet je récupère l'installer de Docker 1.3.0 tout juste publié (merci la 4G en gare de Bordeaux).

Parmi les nouveautés de Docker 1.3.0, la sécurisation de la communication entre un client et le démon docker est un point majeur. 

Jusqu'ici, pour parler à un démon distant on avait une simple interface HTTP, sans aucune sécurisation pas même un login/password. Pratique sur un poste de développement mais un peu léger pour vos serveurs de production :P

Docker 1.3.0 corrige ce défaut en utilisant une authentification par certificat client sur SSL.


Au passage, le port par défaut du démon docker change en 2376 (jusqu'ici 2375). Si vous installez cette version pensez donc à mettre à jour votre .bash_profile avec les variables d'environnement :

DOCKER_HOST=tcp://boot2docker:2376
DOCKER_TLS_VERIFY=1
FORWARD_DOCKER_PORTS=1
DOCKER_CERT_PATH=/Users/nicolas/.boot2docker/certs/boot2docker-vm

boot2docker up vous l'indique également, mais si vous êtes comme moi vous ne faites pas trop attention à ce genre de message :-\

J'ai ensuite voulu faire mumuse avec l'API client, sans passer par le client docker natif. 

J'ai rapidement renoncé à mettre à niveau docker-java car je n'y connais rien en jersey ni à sa configuration avancée pour assurer ce type d'authentification sur https (et sans Net entre Bordeaux et Paris c'est pas facile à deviner)

La documentation officielle suggère une commande curl utilisant les clés générées automatiquement pour nous par l'installateur boot2docker. Et là "oups". 

➜ ~ curl --insecure --cert ~/.boot2docker/certs/boot2docker-vm/cert.pem --key ~/.boot2docker/certs/boot2docker-vm/key.pem https://boot2docker:2376/images/json
curl: (35) Unknown SSL protocol error in connection to boot2docker:-9825

Comme la version OSX de curl est ancienne est un peu customisée à la sauce Apple, j'ai aussi essayé avec la version homebrew ... qui ne marche pas non plus mais par pour la même raison !

➜ ~ /usr/local/Cellar/curl/7.38.0/bin/curl --insecure --cert ~/.boot2docker/certs/boot2docker-vm/cert.pem --key ~/.boot2docker/certs/boot2docker-vm/key.pem https://boot2docker:2376/images/json
curl: (58) SSL: Can't load the certificate "/Users/nicolas/.boot2docker/certs/boot2docker-vm/cert.pem" and its private key: OSStatus -25299

J'ai pu vérifier que les certificats sont corrects, car wget - lui - s'en sort sans soucis

➜ ~ wget --no-check-certificate --certificate=~/.boot2docker/certs/boot2docker-vm/cert.pem --private-key=~/.boot2docker/certs/boot2docker-vm/key.pem https://boot2docker:2376/images/json -O - -q
[{"Created":1413235207,"Id":"9cbaf023786cd79dfba46f49d9a04b2fe9f18017db1257094d1d4cbe7ccb00f1","ParentId":"03db2b23cf0332af20d600e1e0306a629235f4d3b2cfcab2cad0bc3d3443b2b7","RepoTags":["ubuntu:14.04"],"Size":0,"VirtualSize":192754576}


J'ai poussé une pull-request pour documenter cette commande alternative, au cas où je ne serais pas un cas isolé.

Si vous voulez passer en Docker 1.3.0 vous risquez de tomber sur des soucis de ce type. Et surtout si vous utilisez des librairies cliente docker dans vos outils (typiquement, le plugin jenkins docker qui est une aberration mais ça c'est un autre débat) vous êtes cuits. Ce qui m'encourage dans mon plugin à moi (qui lui est une merveille, qui en douterait) à continuer à utiliser le client docker officiel.




16 octobre 2014

Du docker dans Windows ?

L'annonce n'a pas du vous échapper, Microsoft ne laisse pas le buzz Docker lui échapper et annonce un partenariat pour porter la technologies sur Windows.

Petit décryptage.

Microsoft ne veut évidemment pas laisser passer le train, et l'équipe Docker sait pertinemment que Docker ne peut pas éternellement se contenter du monde Linux. Le rapprochement est donc logique. Par contre ne vous y trompez pas, il ne s'agit pas de faire tourner un conteneur Linux en natif sur votre Windows, ou l'inverse - pour le développeur, boot2docker a encore de beaux jours devant lui.

Rappelons que le principe même des conteneurs est que le noyau OS est commun entre l'hôte et l'environnement virtuel ("conteneur") contrairement à une machine virtuelle. Il s'agit bien de faire tourner un (on N) process windows dans un conteneur, sur un système windows.


On va donc avoir des images Docker pour des conteneurs Windows d'une part, et les images Linux qu'on connait déjà de l'autre - séparation qu'on a déjà par exemple pour les images Docker visant les architectures ARM (bon bien sur y'en a pas des masses).



Ce qu'on nous annonce :

  • A Microsoft led initiative to add container capabilities (e.g. the equivalent of namespaces and cgroups) to Windows
En gros ici il ne s'agit que d'une annonce d'intention. On aura donc peut être un concept d'isolation équivalent aux namespaces dans Windows Server 2020. Le développement de cette fonctionnalité sous Linux a tout de même pris 10 ans. Evidemment Microsoft peut aller beaucoup plus vite, mais ce ne sera pas pour noël prochain.

  • A new Docker Windows Daemon, which will be built in open source under the aegis and governance of the Docker project, with input from Microsoft, Docker, Inc, and the broader Docker community
Il s'agit globalement de développer dans le cadre du projet Docker OSS un portage de libContainer sous Windows, le genre de chose sur lequel travaillent également les personnes de FreeBSD ou d'IBM. Le démon Docker Windows sera donc compatible avec l'API Docker, ce qui est une bonne nouvelle : tout votre outillage sera alors 100% utilisable.

  • The overall Docker platform, which will also be extended (in the open) to support both the Docker Windows Daemon and the Docker Linux Daemon.
Plus précisément, Microsoft va investir sur la librairie LibSwarm pour permettre l'orchestration de containers sur son OS.

Bref, Microsoft adopte la technologie qui monte et le fait en bonne entente avec la communauté, ce qui est une bonne nouvelle pour tout le monde.

Reste à savoir si Apple suivra la même démarche...

15 octobre 2014

docker exec preview

A new feature to come in docker 1.3 I'm waiting for is docker exec command. This one will make docker-enter hack an official command. This command will let you attach a new process to an existing container, for diagnostic or monitoring purpose (for sample) or some more advanced hacks I have in mind :-D

As I wanted to test it before official release, I had to check how to build Docker from latest sources.

Docker build system is based on Docker. Don't ask me how debian folks can follow their "build from source" principle, anyway it makes our life easier.

On my Ubuntu box, I just had to clone docker git repository and run make binary to get the latest an greatest docker binary and give it a try, but I wanted also to get it on my good old MacBook.

make cross is designed to build alternate docker binaries for non linux/x64 systems (i386, arm, darwin, freebsd). It works well, but then I need to retrieve the generated binary from the build container.

I'm using boot2docker with VirtualBox guest additions, waiting for 1.3 to offer this by default. But when ran remotely (in boot2docker VM) the Makefile require to setup a BIND directory for docker working copy to be mounted in the container at expected location. I wasn't able to make it work, for some odd reason the dind script fail to start.

Anyway, David gave me to find a workaround.

make build gives me the container image ID for an environment ready to build docker from sources. I can then run a (privileged) container, equivalent to the one ran by make binary,  as a shell and run the hack/make.sh cross command by myself. As a result, this container has all the cross-compiled binaries build in bundles folder.

I then run another docker command from OSX to retrieve the built OSX binary form the (still running) build container : 
docker cp 987654321:/go/src/github.com/docker/docker/bundles/1.2.0-dev/cross/darwin/amd64/docker-1.2.0-dev/docker ./docker-osx

So I now have docker client 1.2.0-dev (a java developer would name it "1.3.0-SNAPSHOT") available on my OS.

I have to do the same on my boot2docker VM so it run 1.2.0-dev daemon. Just need to stop the docker daemon and replace /usr/local/bin/docker. Please note this change won't be persisted if you restart the boot2docker VM. Would need to build a custom iso, but I'm lazy here :-P

Anyway, I now can play with the new docker exec command

➜  docker-1.2.0-dev ./docker version
Client version: 1.2.0-dev
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): dc243c8
OS/Arch (client): darwin/amd64
Server version: 1.2.0-dev
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): dc243c8
➜  docker-1.2.0-dev ./docker run -d ubuntu sleep 1000
fc17ce405dba8417d7995218bd142041877cadcf49751f2233aecf01a7c25114
➜  docker-1.2.0-dev ./docker exec -it fc17 bash
root@fc17ce405dba:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 13:44 ?        00:00:00 sleep 1000
root         7     0  4 13:44 ?        00:00:00 bash
root        21     7  0 13:44 ?        00:00:00 ps -ef
root@fc17ce405dba:/# 

I organize a local edition of Docker Global Hack Day on october 30th. Hacking with such a new command is an option to experiment with new usages and design some crazy tool. Join ! 

26 septembre 2014

Bye Bye RUN@Cloud

Vous êtes nombreux à me contacter pour connaître les tenants et aboutissant de l'arrêt de l'offre RUN@Cloud de CloudBees. Certains s'inquiètent même de me voir pointer aux Assedic. Explications

Disclaimer: ce billet n'engage évidement pas mon employeur, il n'exprime que ma perception des choses, bla, bla, bla 


Donc voilà, jusqu'à cet été, CloudBees était connu pour 3 offres, certains d'entre vous n'ayant d'ailleurs jamais entendu parler de l'une voir de deux d'entre elles :
  • RUN@Cloud, la "Plateform as-a Service" qui justifiant le sous-titre "CloudBees, the Enterprise Java PaaS"
  • DEV@Cloud, le "Software as-a Service" de continuous deployment basé sur Jenkins et la virtualization de l'infrastructure de build.
  • Jenkins Enterprise, une offre plus "traditionnelle" avec une souscription support et une version "entreprise" de Jenkins (plugins spécifiques, etc...)

L'activité sur RUN est (était) en croissance régulière, donc le marché existe, par contre nous avons toujours été confronté à plusieurs freins, tantôt techniques - ceux là encore c'est facile - tantôt politiques ("mes données ne sont pas en sécurité"), tantôt liès à la maturité du milieu. 

En particulier, nombreuses sont les entreprises qui préparent un "Private Cloud" qui n'est parfois qu'un IaaS à base de VMWare ou d'OpenStack, et dont les APIs sont remplacées par un formulaire rose. D'autres ont un peu mieux compris l'idée d'un PaaS mais ne voient pas ce qui différencie l'offre d'un CloudBees/Heroku/Google comparée à installer Dokku ou un truc de ce genre. Bref, de longues heures d'avant-vente, pour grignoter des parts d'un marché qui existe bien, mais fortement concurrentiel et en croissance finalement assez lente, ou plus précisément LINEAIRE.

A côté de ça, DEV@Cloud progresse lui aussi avec les mêmes contraintes (concurrences de divers services *-ci.io, craintes diverses "mon code n'est pas en sécurité", etc), mais surtout le marché Jenkins Enterprise explose. 

Jenkins devient un élément stratégique dans de nombreuses entreprises, et l'équipe ventes de CloudBees a du sensiblement grossir pour adresser la demande. La continuous integration passe progressivement dans le monde du continuous delivery, autrement dit l'outil de l'équipe de DEV devient l'outil de la DSI, avec ne nouvelles ambitions et un tout autre niveau d'exigences. Par ailleurs, l'annonce de Jenkins Operation Center laisse entrevoir un "DEV@cloud privé" qui plait à beaucoup de nos clients. Le marché ici est EXPONENTIEL

Par ailleurs, Jenkins Enterprise tend à fusionner avec DEV@Cloud. Nous pouvons associer des machines on-premises à un master DEV@Cloud, nous pourrons bientôt décharger un jenkins on-premises en allouant nos esclaves de build, l'infrastructure de DEV@Cloud profite des développements sur Jenkins Enterprise et Operation Center (vous avez une ferme de 10.000 Jenkins ? non ? nous si !). Bref, ces deux offres vont évoluer ensemble et profiter l'une de l'autre, effaçant progressivement la barrière "Cloud / pas Cloud".

RUN@Cloud dans l'équation est donc le mouton noir. Le projet est passionnant mais nécessiterait une équipe dédiée pour le faire évoluer rapidement et suivre le marché, sans permettre aux autres offres CloudBees de profiter de l'effort investit. D'où la décision un peu abrupte pour nos clients d'arrêter le service. L'offre PaaS est riche, aussi déménager leurs applis ne devrait pas être un soucis. Cela nous libère aussi pour établir des partenariats plus clairs avec des fournisseurs PaaS comme Pivotal (annoncé au même moment)

DotCloud a eu le même problème avec le succès de Docker. Investir à 200% sur un projet qui croit en puissances de 10, ou maintenir en tâche de fond un PaaS juste pour être sur de ne pas louper un marché à venir ? 

Voilà, donc pas de panique, j'ai encore du boulot pour un bon moment (mais bon, si vous avez une offre avec 6 zéros à me faire ... :P)

22 septembre 2014

Docker on Raspberry

Docker is such a lightweight virtualization solution that it make sense even running on a raspberry.

BreizhCamp's voting machine "LikeBox" uses such a device, and our embedded software is modularized into subsystems. Was a cool challenge to run them inside docker containers, don't you think so ?

Raspberry default OS "raspbian" don't offer a docker system package. As we are more familiar with Debian/Ubuntu I wish I could find one, or maybe use some cross-compilation (docker uses docker to build, so no-way to built it from sources on the target platform). Anyway, as a Proof-of-Concept I'm relying on ArchLinux, as this one has a Docker package !

So first step is to download the system image and copy it into a SD card (when you type such a command, double check the target device ID - also double check the SD card isn't the one with last summer holidays pictures... :-\)

sudo dd bs=1m if=ArchLinuxARM-2014.06-rpi.img of=/dev/disk5

this takes some time ...

new installing Docker is just trivial thing : Arch's package manager PacMan will handle it for you

[root@alarmpi ~]# pacman -S docker
resolving dependencies...
looking for inter-conflicts...

Packages (2): sqlite-3.8.6-1  docker-1:1.2.0-1

Total Download Size:    3.07 MiB
Total Installed Size:   15.02 MiB

:: Proceed with installation? [Y/n] Y


et voilà, I now can start a raspbian container on my Arch Linux :

[root@alarmpi ~]# docker run -ti --rm resin/rpi-raspbian /bin/bash
root@b088dc9a7e31:/#

Have now to test how to enable docker container to access raspberry GPIO and I2C bus, so I can actually package the apps into a container.

What's the benefit for this ?

During development, we use some mock library to emulate the i2c connected 2 line display and the GPIOs capturing user input (i.e. red / green voting buttons). I wonder I could make the application fully agnostic, and encapsulate those technical implementation details into containers, I would link at runtime to application code, resulting in some micro-micro-service architecture :-D

The other reason is ... fun :)

16 septembre 2014

Boot2docker (eventually) includes Virtualbox guest addition

First try you gives Docker a try,  you get excited how easily the target environment can be reproduced and how fat you can start a "container" compared to virtual-machines.

Then you start considering using Docker for your own development (as it might be hard to convince production guys to adopt a tool that was just released as 1.0 few month ago). As you use a Windows or Apple computer, you will rely on boot2docker. That sounds good ... until you start building non trivial applications.



Running 'docker build' from your computer will send all local directory to the docker vm so the Dockerfile can access project resources, this can take some time but this works. If you use the "code, build, restart" approach, things will be mostly ok, as you just change the commands to be used.

But if your software stack only require to update source code, for sample as you develop an Angular frontend, or rely on modern stack with hot-reload capabilities, thinks become crazy : developing with Docker make you far slower than local development.

The "live-reload" approach is possible with Docker, but require direct connection from your IDE to the folder used by your application container. Docker volume option can mount a directory from host into container, but you're not working on the host - that is your boot2docker VM. 

Request to include VirtualBox guest additions in boot2docker, so the VM can share your $HOME directory, and let you get local file accessed from container using a volume is a long running issue on boot2docker issue tracker. There's lot's of reason to explain this has been rejected :

  1. boot2docker hasn't been designed as a development helper, but as a minimal OS to run docker containers. So it's not tied to Virtualbox
  2. a better option would be for windows/osx docker client --volume option to support remote mount, using some client-daemon communication as transport. But that's not trivial :)
Some experimented with a Samba server running in boot2docker VM, so you can access it from your development environment as a (actually local) remote directory. I didn't tested it but this just looks like a hack, and is a huge entry barrier for newbies.

This morning I had the surprise to see this pull-request being merged :


You can read the discussion there for more details, but the main point is 
"boot2docker" currently is essentially the "Docker daemon for Mac OS / Windows"

That's a major point, and nice to see the boot2docker team consider the way the project is actually used in docker community. Docker ecosystem is full of talented developers, with impressive skills and knowledge on low level system stuff and virtualization constraints. But Docker topic is to make this simple and offer a common interface to all underlying technologies. Docker main benefit is that a developer - even a junior Java EE developer - can use it to run his application on a Windows workstation then reproduce this stupid "UTF-8 Invalid Byte Sequences" bug.


This ended up with docker CTO Salomon Hykes escalating this issue as a major Docker-wide one. There have been an active debate, but we eventually get it fixed. Thank you guy to take care of your community !





14 septembre 2014

is Docker ready for Production ?

This article is a response to IS DOCKER READY FOR PRODUCTION

"You embed a distro in a distro (or multiple distros in a distro)"

Sure, that's the reason dedicated Docker Linux distro have been created, like Boot2docker or CoreOS. Those are designed to be lightweight (~ 100Mb) and focus on production systems : stability and maintenance. Not even do they provide a package manager.

"your container will most likely weight more than 1GB" not really. The base image might weight few hundreds Mb, but you'll only download it once, and most companies will anyway try to standardize distro they use for applications, not just let developer creativity give esoteric distributions a try.

Initial setup for a Docker host will require to download base image and application image layers. The application download in most case is pretty quick, but the base image(s) might take some time. For this reason docker host should be provisioned with most commons base images (in company) pre-installed. On AWS this is a common perf improvement to (re)create AMI image, not just rely on a base AMI and run configuration manager to fully setup the box (at least, we do this way at CloudBees).


"Dreaming of a statically build binary"

Building from scratch image is a bit crazy, interesting exercise, but I'd recommend to rely on Busybox if you want to reduce image size. See David's java8 Dockerfile for sample. A bit hack-ish as Busybox wget don't have https support to download JDK 8 from Oracle web site, but anyway result in a minimalist image.

Complexity to build statically linked binaries depends on target environment. For ruby this seems to be painfull, with lots of dependencies, resulting on a 450Mb install. I guess the Dockerfile did install some build tools, compile, then delete build tools, but not within the same RUN command, resulting in layers in docker image to contain file that get actually deleted in union filesystem.

That's just an assumption. Could flatten image running :
run docker export containerId | docker import - name:latest

For such a setup, should either use David's approach to create a one-liner RUN command, or search for some solution to build the binaries (in a Dockerfile) and only include the actual result in another one (see feature request 7992).

"Logging"

"There’s no easy way logging with Docker" - there is one actually : just dump to stdout. Docker log can be used to retrieve logs, so can the daemon API and you can then plug various management tools. Read for sample this typical usage scenario for libswarm : http://blog.docker.com/2014/07/libswarm-demo-logging/.

For people to prefer syslog approach,  this doesn't break the "1 container, 1 process" philosophy ... until you try to package syslogd in your container. Read http://jpetazzo.github.io/2014/08/24/syslog-docker/ for a description about using Docker with syslog, the later being yet another container-ized service. I don't get the argument against container isolation. application and syslog communicate using a unix socket, what' wrong letting them talk ? 

"admin nightmare" ? yes, you need your sysadmin to understand and manage docker container and how to orchestrate them. Did someone told you docker will replace all of them ? They anyway had to manage apps to communicate with various services and resources with classic deployment setup, that's not a new challenge.

"Network management"

Docker networking is actually complicated, and the documentation first don't help to make you confident with it - but is useful once you understood it to get further. Sorry guy to have a detailed documentation :) http://blog.thestateofme.com/2014/09/12/docker-networking/ has very explicit schemas to explain docker networking, then cryptic iptable configuration samples ... 

Virtual network never has been a simple topic, and Docker way is only for simpler uses cases. Weave or Pipework can cover most complex scenarios. Discussing with some Network engineer about OpenStack capabilities this is definitively a topic that require some advanced skills. Anyway, most human being will only need the --link option for their Docker application, and that's pretty cool.

"Provisioning is not perfect at all"

I agree Dockerfiles are level 0 of software management. But nobody said you need all your process to rely on a Dockerfile. It's 100% valid to use a classic build system then just package application binaries with a Dockerfile to produce deployable application. It's better if all elements can be managed with Dockerfile, but you can combine few of them.

People who are used with Puppet/Chef/Ansible power will just create a base image with those tools setup and inherit from this one for every application, Dockerfile just importing the cookbooks and running chef-solo. This is a nice way to migrate existing infrastructure to Docker. As a result, the Docker image is create with Chef DSL power, but chef will only run once during image creation, the image then is immutable.

Packer is an alternative, and I guess we will se more to emerge in Docker ecosystem to offer a higher level of abstraction and more flexibility to build Docker images. Also you can build a Docker image with just plain old docker commit command, and can integrate it with you build tools, as long as you make it automated some way. Dockerfile is just the common denominator that allows DockerHub to build any image from sources and distributed to any developer.

"Process monitoring? Don’t even think about it

Containers require a new generation of monitoring agents. cAdvisor is one of them. For sure, migrating your existing monitoring system so it embrace Docker container is not trivial. For nagios integration, there's few nagios-docker plugins to be developed, I didn't experimented with any of them so can't tell maturity, but the metrics are available from docker daemon and cgroups API, read http://jpetazzo.github.io/2013/10/08/docker-containers-metrics/ to see how to use them. 

Right, this will require some effort to migrate your existing setup. Never had the promise Docker would feet your existing tools without any effort. libSwarm is especially focussing on this issue : it provides a neutral integration API, so you can plug your custom orchestration / audit / monitoring / whatever tools into a Docker environment. Right, this is just a prototype at this time.

"Porting your application to Docker increases complexity. Really."

Applying the "1 container, 1 process" at early beginning is hard. Consider it an opportunity to rethink your architecture. First use Docker as "lightwight virtual machines" and drop your application with dozen processes and deamons in a Dockerfile. Docker benefits (ability to run production equivalent system locally) and available orchestration tools (start with Fig, then consider alternatives for larger/complex setup) will let you refactor your application and related Docker containers into smaller, focussed service to collaborate together.

Right, I don't know anything about Botify infrastructure, and related constraints. Reading Frédéric's blog my feeling was they experimented with Docker (just for 2 weeks ?) as a major transition, trying to apply it far too strictly, then were hurt by actual constraints. I'd be very happy if I have the opportunity to meet him (he's French like me, so seems feasible) to discuss in details the issue they had.

With a customer of mine (as part of my Freelance activity) we are considering a baby-step migration to Docker, so that we could learn about Docker and actual constraints using it on a production infrastructure, as well as discover it's benefits for development and continuous delivery. This is not a trivial transition, and for sure there's lot's of points we will only discover with real-life usage.




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).