Thématiques principales

lundi 31 décembre 2018

Docker - Plugin Maven

Un petit écart dans la liste des articles qui devaient être publiés prochainement en abordant le sujet du packaging de nos builds maven dans des images Docker.

On parle d'écart mais en fait pas tant que ca car nous verrons que OSGI se prête bien à une intégration dans docker. Bref ca c’est une autre histoire.

Tout le monde connaît Docker, au moins de nom. Il s’agit d’une solution de conteneurisation [docker-pub], assimilable à de la “virtualisation allégé” (ok le raccourci est rapide) permettant de construire des architectures scalables [scala] de type [microservice] (nous en reparlerons).

L’approche classique pour construire une image docker et d’utiliser la commande “docker build”, si vous êtes un habitué de l’outil, sera de construire un Dockerfile. Je vous laisse pour cela aller consulter l’article [docker-base].

Cependant cette approche en ligne de commande, bien que pratique car universelle n’est pas forcément immédiate dans le cadre d’une industrialisation comme d’un build maven qui aurait pour résultat non pas un artifact java classique [integ-java] mais une image docker prête à l’emploi pour les tests ou la production (vous le voyez poindre le concept de Déploiement Continu?).

Heureusement pour répondre à ce problème il existe deux plugins maven [compar]:
  • spotify/maven-docker-plugin [spotify], et sa nouvelle version [spotify-2] spotify/dokerfile-maven-plugin
  • fabric8io/maven-docker-plugin [fabric8io]

Spotify

Ce plugin maven est celui ci qui collera le plus avec la logique d’utilisation de docker.

En effet, ce plugin s’utilise de façon assez simple soit par configuration xml sur les éléments basiques qu’un dockerfile pourrait contenir où en spécifiant directement un répertoire où se trouvera un dockerfile.

Ainsi ce plugin va permettre de réaliser la phase de build de la commande docker mais aussi en complément la phase de push pour livrer l’image ainsi construite dans un repository comme le docker hub [DocHub].

On pourra regretter que ce plugin ne permet pas de lancer lui même des conteneurs, chose qui aurait pu être intéressant pour la réalisation de phase de tests.

Dans le cadre de cet article, comme dans celui de [compar], nous ne nous attarderons pas sur ce plugin qui finalement fait bien son taff mais ne fournira pas en dehors du cadre de l'intégration à maven beaucoup plus de fonctionnalité que de faire son Dockerfile nous même.

Fabric8io

Le plugin fabric8io sort quand à lui plus des sentier battu en ne s’appuyant pas du tout sur un dockerfile mais sur une approche plus classique dans un environnement maven. En effet, ce plugin propose d’utiliser un descriptif xml du Dockerfile [doc-fabric] ainsi que le mécanisme des assembly [assembly-maven].

A cela, il permet aussi de gérer le cycle de vie des conteneurs en activité (start/stop/kill etc...) ainsi que de publier les images sur un repository (comme le DockerHub [DocHub])

Le plus simple pour présenter le plugin est d’en faire la démonstration.

Ainsi considérons un projet java construit forcément avec un process maven. L’idée d’un build est de généralement construire jar. Dans une approche standard de packaging, le process maven appliquera une phase d’assemblage dans laquelle, le jar, sa conf et ses éventuellement dépendances seront mis dans un targz, un paquet debian où tout autre format de livraison.

Avec docker, le concept permettant d'exécuter un conteneur à partir d’une image quelque soit la plateforme permet d’imaginer une rationalisation du moyen de livraison et d'exécution.

Ainsi, parce que nous utilisons maven, nous allons enrichir un pom parent avec une configuration pluginManagement du plugin fabric8io. L’idée est alors de permettre à tout pom héritant de celui-ci de construire une image docker de packaging et d'exécution.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<profiles>
    <profile>
        <id>DOCKER</id>
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>docker-maven-plugin</artifactId>
                        <version>0.27.2</version>
                        <configuration>
                            <images>
                                <image>
                                    <name>${docker.login}/${project.artifactId}:%l</name>
                                    <alias>${project.artifactId}</alias>
                                    <build>
                                        <maintainer>Collonville Thomas collonville.thomas@gmail.com</maintainer>
                                        <!-- <dockerFile>Dockerfile</dockerFile> -->
                                        <assembly>
                                            <mode>dir</mode>
                                            <permissions>auto</permissions>
                                            <targetDir>/</targetDir>
                                            <descriptor>../assembly/assembly-docker.xml</descriptor>
                                        </assembly>
                                    </build>
                                </image>
                            </images>
                        </configuration>
                        <executions>
                            <execution>
                                <id>start</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </profile>
    <profile>
        <id>PUSH</id>
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>docker-maven-plugin</artifactId>
                        <version>0.27.2</version>
                        <executions>
                            <execution>
                                <id>start</id>
                                <phase>verify</phase>
                                <goals>
                                    <goal>build</goal>
                                    <goal>push</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </profile>
</profiles>

Ainsi la pré configuration maven du plugin permet de façon générale de donner un nom à l’image et spécifier ses informations générales (nom, mainteneur) dans la section “image”.

Ensuite dans une section build on va préciser le contenu de l’image en utilisant les mécanismes d’assembly maven que l’on devra préciser dans le fichier “assembly/assembly-docker.xml”

Enfin en coherence avec la logique des plugins maven se constituant d’une partie configuration et d’une partie exécution, dans cette dernière, on va préciser quelle commande docker nous allons appliquer.

Ici on notera qu’il y a deux profiles maven, l’un DOCKER de base qui apporte la configuration et la construction de l’image et un second PUSH dans lequel on appliquera la commande “push” de docker (cela nécessitera l’utilisation de la propriété docker.login précisant le compte du DockerHub associé et présent dans le nom de l’image)

L’utilisation de ce pom parent passe ensuite par la surcharge du profile DOCKER dans une section plugin (le profile PUSH étant directement hérité).

La surcharge est rapide bien qu’un peu verbeuse à cause du profile maven. (à noter que dans un process complet et générique on pourra in fine s’en passer)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<profiles>
    <profile>
        <id>DOCKER</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>io.fabric8</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <configuration>
                        <images>
                            <image>
                                <build>
                                    <from>openjdk:8-jre-alpine</from>
                                    <cmd>/opt/equinox-loader/docker.sh</cmd>
                                    <ports>
                                        <port>${jmx.port}</port>
                                    </ports>
                                </build>
                            </image>
                        </images>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Dans ce pom, il s’agira juste de completer les parties manquantes c’est à dire:

  • l’image source utilisé
  • une commande de lancement
  • les ports et les volumes à déclarer
  • pour finir le contenu de l’assembly, faisant office de commande ADD et COPY d’un Dockerfile

Ici nous utiliserons l’image openjdk:8-jre-alpine comme image source que nous allons configurer le port JMX de la JVM et que nous lancerons l’application via un script sh.

Pour ce qui concerne l’assembly, il s’agit à ce niveau d’une assembly standard utilisant des section “dependencySets” et “fileSets”. Je vous invite à consulter la documentation du plugin [plugass] et/ou de lire l’article [assem].

Voilà avec ce plugin, du coup il est possible de construire des images docker contenant directement notre build prêt à l’emploi nous facilitant d’une part la diffusion du livrable mais aussi l’exploitation dans des tests et surtout l’exploitation en production.

Références

[docker-pub] https://un-est-tout-et-tout-est-un.blogspot.com/2017/10/docker-publier.html
[docker-base] https://un-est-tout-et-tout-est-un.blogspot.com/2017/09/docker-construire-son-image.html
[scala] https://fr.wikipedia.org/wiki/Scalability
[integ-java] https://runnable.com/docker/java/dockerize-your-java-application
[microservice] https://fr.wikipedia.org/wiki/Microservices
[spotify] https://github.com/spotify/docker-maven-plugin
[spotify-2] https://github.com/spotify/dockerfile-maven
[fabric8io] https://github.com/fabric8io/docker-maven-plugin
[doc-fabric] http://dmp.fabric8.io/
[compar] https://dzone.com/articles/meet-the-docker-maven-plugin
[assembly-maven] http://maven.apache.org/plugins/maven-assembly-plugin/
[DocHub] https://hub.docker.com/
[assem] https://un-est-tout-et-tout-est-un.blogspot.com/2018/03/maven-assembly-targz-et-jdeb.html
[plugass] https://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html

Aucun commentaire:

Enregistrer un commentaire