OpenShift Deployment mit dem fabric8-maven-plugin

18.12.2018

Das Thema DevOps ist allgegenwärtig und viele Entwicklerteams sehen sich mit der Tatsache konfrontiert, dass sie ihre Anwendungen nicht nur bauen, sondern auch selbst betreiben müssen. Äußerst beliebt ist dabei derzeit natürlich Kubernetes oder auch OpenShift als Plattform. Doch die händische Pflege von Deploymentkonfigurationen kann mühsam sein. Hier kommt fabric8 ins Spiel: mit dem fabric8-maven-plugin lässt sich das Deployment nahtlos in den Buildprozess integrieren.

Sinnvolle Basiswerte werden durch die bereits bestehenden Einstellungen aus der POM ergänzt und können bei Bedarf gezielt überschrieben werden. Aber auch schon vor dem Deployment hilft das Plugin, denn es unterstützt auch bei der Erstellung eines Docker-Images. Je nach Umgebung ist es aber bei OpenShift nicht möglich, direkt mit Docker zu kommunizieren. Stattdessen gibt es hier die Variante des Source2Image Builds, welcher ebenfalls von fabric8 unterstützt wird.

Da die Dokumentation (https://maven.fabric8.io/) nicht unbedingt den leichtesten Einstieg bietet, gibt es hier eine kleine Hilfestellung.

Vorbereitung

Zuerst binden wir das Plugin ein:

<build>
  <plugins>
    <plugin>
      <groupId>io.fabric8</groupId>
      <artifactId>fabric8-maven-plugin</artifactId> 
      <version>3.5.42</version>
    </plugin>
  </plugins>
</build>

Jetzt greift bereits der „Zero-Config“ Modus von fabric8. Mit den Voreinstellungen erarbeitet das Plugin selbstständig einen Plan für das zu bauende Image. Rufen wir also nun mvn package fabric8:build auf, wird unser Jarfile mit dem fabric8-Basisimage zu einem Dockerimage gebaut. Da wir aber davon ausgehen, keinen Zugriff auf Docker zu haben, müssen wir die erste Konfiguration vornehmen:

<properties>
  <fabric8.build.strategy>s2i</fabric8.build.strategy>
  <fabric8.mode>openshift</fabric8.mode>
</properties>


Image bauen

Mit diesen Properties wechselt fabric8 in den OpenShift-Modus. Diesmal führt der Aufruf von mvn package fabric8:build zu einem OpenShift Binary Build. Das bedingt, dass die OC Tools installiert und mit dem Zielcluster verbunden sind. Ist der Buildvorgang erfolgreich, dann existiert nun ein ImageStream mit der artifactId im gewählten Namespace (dieser lässt sich mit auch mit -Dfabric8.namespace beim Aufruf ändern). Als Basisimage wird bei der S2I-Strategy standardmäßig fabric8/s2i-java:latest verwendet. Möchte man das ändern, lässt sich das in der Pluginkonfiguration bewerkstelligen:

<plugin>
[...]
  <configuration>
    <images>
      <image> 
        <from>another/docker-image:latest</from> 
      </image>
    </images>
  </configuration>
[...]
</plugin>


Deployment

Im nächsten Schritt kümmern wir uns um die Deploymentkonfiguration. Mit mvn fabric8:resource generiert uns das Plugin eine Reihe von YAML Dateien unter target/classes/META-INF/fabric8/openshift für das Deployment, den Service und die externe Route.

Auch wenn viele der hinterlegten Werte eine gute Ausgangsbasis sind, wollen wir doch meistens die ein oder andere Anpassung vornehmen. Bei uns hat sich im Realfall die Kombination aus einzelnen Definitionen in einer YAML-Datei und dem maven-resources-plugin bewährt. Dabei legen wir beispielsweise folgende Anpassungen fest (unter src/main/fabric8/deployment.yaml):

spec:
  template:
    spec:
      containers:
      - resources:
          limits:
            memory: ${container.memory.limit}

Wir wollen also das Speicherlimit des Containers festlegen. Dank des maven-resources-plugin können wir dafür dann eigene Properties oder auch die bereits vorhandenen (wie z.B. artifactId) verwenden. Das schaffen wir mit folgender Anpassung der POM:

<properties>
  <container.memory.limit>512Mi</container.memory.limit>
</properties>
[...]
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
          <id>copy-fabric8-config</id>
          <phase>package</phase>
          <goals>
            <goal>copy-resources</goal>
          </goals>
          <configuration>
            <overwrite>true</overwrite>
            <outputDirectory>${basedir}/target/fabric8-source</outputDirectory>
            <resources>
              <resource>
                <directory>src/main/fabric8</directory>
                <filtering>true</filtering>
              </resource>
            </resources>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>io.fabric8</groupId>
      <artifactId>fabric8-maven-plugin</artifactId>
      <version>3.5.41</version>
      <configuration>
        <resourceDir>target/fabric8-source</resourceDir>
      </configuration>
    </plugin>
  </plugins>
</build>

Fabric8 fügt dann unsere konkreten Einstellungen und die Standardkonfiguration zum Endergebnis zusammen. Auf diese Weise lässt sich gezielt nach gewohntem Muster alles so konfigurieren, wie man möchte. Alternativ dazu bietet das Plugin auch viele Konfigurationsmöglichkeiten über die POM direkt an; dies stellte sich bei uns jedoch als zu unübersichtlich heraus.

Zu guter Letzt können wir nun mit mvn fabric8:apply die erstellten Ressourcen im Cluster anwenden und damit unsere Anwendung deployen.

Ausblick

Dank des Plugins lässt sich der Deploymentvorgang schnell vereinfachen. Wir kratzen dabei jedoch nur an der Oberfläche – fabric8 bietet noch sehr viel mehr. Wird die eigene Anwendung beispielsweise mit Spring bzw. Spring Boot entwickelt, erkennt fabric8 dies und passt die Konfiguration entsprechend an – inklusive Healthchecks für Spring Boot Actuator. Der klassische Weg mit dem Docker Daemon funktioniert natürlich auch und über mvn fabric8:watch bietet das Plugin sogar ein automatisches Redeployment bei Änderungen im Workspace.

Wer nun Interesse gefunden hat, dem sei trotz des etwas holprigen Einstiegs die ausführliche Dokumentation ans Herz gelegt, ergänzt durch das Handbuch des docker-maven-plugin, welches in das fabric8-maven-plugin integriert ist. Hier lassen sich manchmal ein paar ergänzende Informationen finden.

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*