Skip to main content

Java-Container-Images mit Jib erstellen

Artikel von
Java engineering

17. August 2021

0 Min. Lesezeit

Wenn Sie schon länger als eine Minute mit Container-Images arbeiten, kennen Sie wahrscheinlich die allgegenwärtigen Dokumente, die Schritt für Schritt beschreiben, wie ein Image erstellt wird: Dockerfiles. Wussten Sie, dass es immer mehr Tools gibt, mit denen sich OCI-konforme Images ohne Dockerfiles erstellen lassen? In diesem Artikel sehen wir uns Jib an, ein zu 100 % Java-basiertes Tool, mit dem sich hochoptimierte Images erstellen lassen, ohne dass Sie sich um ein korrekt aufgebautes Dockerfile kümmern müssen.

Ich gehe davon aus, dass Sie bereits verstehen, wie Images erstellt werden, und zumindest Grundkenntnisse zu Dockerfiles haben. Falls Sie neu damit sind, lesen Sie vielleicht meinen Beitrag zu developer-driven workflows, in dem ich ausführlich auf das Erstellen von Container-Images eingehe.

Die Herausforderung

Als Java-Entwickler kümmern Sie sich neben Ihrer Anwendungs-Codebasis und den Bibliotheksabhängigkeiten wahrscheinlich auch darum, welche JDK- und JVM-Versionen Sie verwenden. Dazu gehören möglicherweise die Version des Web-App-Servers, auf dem Sie aufbauen, sowie Laufzeitkonfigurationen wie die Abstimmung des Garbage Collectors und Datenbankverbindungen. Womit Sie sich nicht unbedingt befassen mussten, sind Aspekte auf Betriebssystemebene wie die Installation von Paketen, Dateisystemberechtigungen, die zur Laufzeit verwendete UID/GID und andere Konfigurationsdetails. Historisch wurden diese von den Betriebs- und Sicherheitsteams verwaltet, die Ihnen Plattformen bereitstellen.

Mit der Einführung von Container-Runtimes und den darauf aufbauenden Orchestrierungssystemen fallen viele dieser tiefer liegenden Aspekte zunehmend in den Zuständigkeitsbereich der Entwicklungsteams. Sie werden in Form von Infrastructure-as-Code-Konfigurationsdateien (IaC) verwaltet, die Teil der Code-Repositories für Anwendungen und Services sind. Diese Dateien können verschiedene Formen haben, etwa Kubernetes-YAML, Terraform-HCL, CloudFormation-JSON und natürlich Dockerfiles, die die Struktur des Container-Images festlegen, in dem Ihre Anwendung ausgeführt wird.

Ihre Anwendung in ein Image zu packen und in einem Container auszuführen, ist normalerweise keine besonders schwierige Aufgabe. Sicherzustellen, dass das Image korrekt aufgebaut, optimiert und sicher ist und den Standards Ihres Unternehmens entspricht, kann dagegen eine Herausforderung sein. Von Entwicklern wird heute erwartet, dass sie sich mit Tools für Betriebssystem-Scans auskennen, Image-Kennzeichnungsstandards einhalten, die aktuellen Dockerfile-Best Practices kennen und noch vieles mehr übernehmen. Linting- und Scan-Tools wie Hadolint, Dockle und unser Angebot Snyk Container können Sie dabei unterstützen. Aber was wäre, wenn sich die meisten – oder sogar alle – dieser neuen Anforderungen und Boilerplate-Inhalte automatisieren ließen?

Jib: ein zu 100 % Java-basiertes Tool zum Erstellen von Container-Images

Jib ist ein Open-Source-Tool, das vollständig in Java geschrieben ist und OCI-konforme (Docker v2) Container-Images erstellt – ganz ohne Dockerfile oder installierte Container-Runtime. Jib lässt sich als eigenständiges CLI-Tool verwenden, wird aber meist als Plugin in einen Maven- oder Gradle-Build-Schritt eingebunden. Mit dem Plugin führen Sie einfach denselben Build-Befehl mvn oder gradle aus, den Sie bereits zum Erstellen Ihrer .jar-, .war- und anderer Artefakte verwenden. Damit erstellen Sie zusätzlich ein OCI-Image, das Ihre Anwendung in einem Container ausführen kann, und können es bei Bedarf auch bereitstellen.

Ausgehend von einer Spring-Boot-Anwendung lässt sich Jib ganz einfach hinzufügen: Fügen Sie diesen XML-Code in Ihre Maven-Datei pom.xml ein (die vollständige Dokumentation finden Sie hier) und führen Sie den Befehl mvn package erneut aus. Hier können Sie festlegen, wo der Container abgelegt werden soll. Der Einfachheit halber stellt dieses Beispiel das Image in einer Image-Registry bereit, die wir später zum Ausführen verwenden. Sie können das Image aber auch in eine lokale **.**tar-Datei schreiben lassen oder – sofern ein Docker-Daemon ausgeführt wird und zugänglich ist – im lokalen Docker-Image-Cache ablegen lassen (genau wie bei einem Docker-Build).

<build>
<plugins>
...
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<to>
<image>reg.mycorp.com/smalls/spring-goof</image>
</to>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
$mvn package
...
[INFO] --- jib-maven-plugin:3.1.1:build (default) @ spring-goof ---
[WARNING] 'mainClass' configured in 'maven-jar-plugin' is not a valid Java class: ${start-class}
[INFO] 
[INFO] Containerizing application to localhost:5000/spring-goof...
[WARNING] Base image 'adoptopenjdk:8-jre' does not use a specific image digest - build may not be reproducible
[WARNING] The credential helper (docker-credential-desktop) has nothing for server URL: localhost:5000
[WARNING] 
Got output:

credentials not found in native keychain

[WARNING] Cannot verify server at https://localhost:5000/v2/. Attempting again with no TLS verification.
[WARNING] Failed to connect to https://localhost:5000/v2/ over HTTPS. Attempting again with HTTP.
[INFO] The base image requires auth. Trying again for adoptopenjdk:8-jre...
[WARNING] The credential helper (docker-credential-desktop) has nothing for server URL: registry-1.docker.io
[WARNING] 
Got output:

credentials not found in native keychain

[WARNING] The credential helper (docker-credential-desktop) has nothing for server URL: registry.hub.docker.com
[WARNING] 
Got output:

credentials not found in native keychain

[INFO] Using credentials from Docker config (/Users/eric/.docker/config.json) for adoptopenjdk:8-jre
[INFO] Using base image with digest: sha256:117fae95422c19f1c1ddfb0f869913c1d934547e8eb903738a9fd2c3ad11a207
[INFO] 
[INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, org.snyk.groceries.SpringGoofApplication]
[INFO] 
[INFO] Built and pushed image as localhost:5000/spring-goof
[INFO] Executing tasks:
[INFO] [==============================] 100.0% complete
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11.169 s
[INFO] Finished at: 2021-06-28T14:43:49-05:00
[INFO] ------------------------------------------------------------------------

Hinweis: In der obigen Ausgabe sehen Sie einige interessante „Warnungen“, auf die wir später noch eingehen.

Führen Sie jetzt auf einem Rechner mit installierter Container-Runtime einfach den Container aus: docker run --rm -it -p 8080:8080 myimage:tag

$ docker run --rm -it -p8080:8080 reg.mycorp.com/smalls/spring-goof
Unable to find image reg.mycorp.com/smalls/spring-goof:latest' locally
latest: Pulling from spring-goof
c549ccf8d472: Pull complete 
bd7766c75e8f: Pull complete 
7e80a3d8823a: Pull complete 
a7321fbff05c: Pull complete 
05d4865ff251: Pull complete 
e8d1ce8a5389: Pull complete 
bc56aad8a781: Pull complete 
Digest: sha256:74710d3c27ad84cb594b84a519c111a2b04a611ca52ac81f644e3ab5e15d0063
Status: Downloaded newer image for reg.mycorp.com/smalls/spring-goof:latest

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.5.RELEASE)

2021-06-28 19:54:51.550  INFO 1 --- [           main] o.snyk.groceries.SpringGoofApplication   : Starting SpringGoofApplication on beaa3641ca38 with PID 1 (/app/classes started by root in /)

Wenn Sie Gradle verwenden, finden Sie in der offiziellen Dokumentation alle Informationen dazu, wie Sie dasselbe in Ihrer Datei build.gradle umsetzen.

Das ist schon alles. Zum Erstellen von Images sind weder Dockerfile noch zusätzliche Tools erforderlich – Sie verwenden einfach dieselben Build-Tools, mit denen Sie bereits Ihre Java-Artefakte erstellen. Das vereinfacht nicht nur den Alltag von Entwicklern, sondern erleichtert auch die Unterstützung von CI-Build-Agents erheblich, da weder der Docker-Socket freigegeben noch andere Build-Tools verwaltet werden müssen.

Ein genauerer Blick auf das Image

Der Image-Build-Prozess ist also vielleicht einfacher. Wenn es Ihnen aber wie mir beim ersten Anblick geht, haben Sie wahrscheinlich Fragen wie diese …

Wie erstellt Jib Images?

Wie jedes Tool zum Erstellen von Images erzeugt Jib mehrere Dateisystem-Layer. Sie enthalten die Java-Runtime, Ihre Anwendung und alle zugehörigen Abhängigkeiten sowie Metadaten, anhand derer die Container-Engine weiß, wie die JVM gestartet werden soll.

Hier sehen Sie die Layer-Informationen für dieses Beispiel, ausgegeben mit dem Befehl docker image history:

$ docker image history localhost:5000/spring-goof:latest 
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
4c125b59f147   51 years ago   jib-maven-plugin:3.1.1                          79B       jvm arg files
<missing>      51 years ago   jib-maven-plugin:3.1.1                          6.36kB    classes
<missing>      51 years ago   jib-maven-plugin:3.1.1                          0B        resources
<missing>      51 years ago   jib-maven-plugin:3.1.1                          30MB      dependencies
<missing>      10 days ago    /bin/sh -c #(nop)  ENV JAVA_HOME=/opt/java/o…   0B        
<missing>      10 days ago    /bin/sh -c set -eux;     ARCH="$(dpkg --prin…   108MB     
<missing>      10 days ago    /bin/sh -c #(nop)  ENV JAVA_VERSION=jdk8u292…   0B        
<missing>      10 days ago    /bin/sh -c apt-get update     && apt-get ins…   43.2MB    
<missing>      10 days ago    /bin/sh -c #(nop)  ENV LANG=en_US.UTF-8 LANG…   0B        
<missing>      10 days ago    /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      10 days ago    /bin/sh -c #(nop) ADD file:920cf788d1ba88f76…   72.7MB    

Beachten Sie, dass bei den ersten vier Layern unter CREATED jeweils „vor 51 Jahren“ steht. Das ist ein Nebeneffekt der wiederholbaren Build-Strategie von Jib, mit der bei Builds derselben Codebasis exakt dieselben Layer-Hashes entstehen sollen. Weitere Informationen dazu finden Sie in den häufig gestellten Fragen.

Wie die Layer-Kommentare zeigen, stammen einige Layer aus dem standardmäßigen AdoptOpenJDK-Basis-Image – mehr dazu weiter unten. Danach folgen der Reihe nach:

  • Bibliotheksabhängigkeiten, die in Ihren Maven-/Gradle-Dateien definiert sind

  • Ressourcendateien

  • Klassendateien aus Ihrem kompilierten Anwendungscode

  • Argumentdateien für die Java-JVM.

Sehen wir uns mit dem Open-Source-Tool dive noch genauer an, welche Dateien in diesen vier Layern enthalten sind:

Abhängigkeiten

Dieser Layer fügt alle .jar-Dateien zum Ordner /app/libs hinzu.

│ Layers ├──────────────────────────────────────────────────────────────────── ┃ ● Current Layer Contents ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Cmp   Size  Command                                                            Permission     UID:GID       Size  Filetree
     73 MB  FROM 679f8666b5733b3                                               drwxr-xr-x         0:0      30 MB  └── app
     43 MB  apt-get update     && apt-get install -y --no-install-recommends t drwxr-xr-x         0:0      30 MB      └── libs
    108 MB  set -eux;     ARCH="$(dpkg --print-architecture)";     case "${ARC -rw-r--r--         0:0     445 kB          ├── antlr-2.7.7.jar
     30 MB  jib-maven-plugin:3.1.1                                             -rw-r--r--         0:0     1.9 MB          ├── aspectjweaver-1.8.10.jar
       0 B  jib-maven-plugin:3.1.1                                             -rw-r--r--         0:0      65 kB          ├── classmate-1.3.3.jar
    6.4 kB  jib-maven-plugin:3.1.1                                             -rw-r--r--         0:0     314 kB          ├── dom4j-1.6.1.jar
      79 B  jib-maven-plugin:3.1.1                                             -rw-r--r--         0:0      13 kB          ├── evo-inflector-1.2.2.jar
                                                                               -rw-r--r--         0:0     1.8 MB          ├── h2-1.4.196.jar
│ Layer Details ├───────────────────────────────────────────────────────────── -rw-r--r--         0:0      75 kB          ├── hibernate-commons-annotations-5
                                                                               -rw-r--r--         0:0     5.6 MB          ├── hibernate-core-5.0.12.Final.jar
Tags:   (unavailable)                                                          -rw-r--r--         0:0     612 kB          ├── hibernate-entitymanager-5.0.12.
Id:     da844eca910f44e825c72121f4ec9700b3c9eec8d4c2407f926cdad0799b33e8       -rw-r--r--         0:0     113 kB          ├── hibernate-jpa-2.1-api-1.0.0.Fin
Digest: sha256:0862e7d5215a0ec2cf7d5a8864a5a0439d9c70c39b14cdc6c38f41487ca8f23 -rw-r--r--         0:0     726 kB          ├── hibernate-validator-5.3.5.Final
Command:                                                                       -rw-r--r--         0:0      56 kB          ├── jackson-annotations-2.8.0.jar
jib-maven-plugin:3.1.1                                                         -rw-r--r--         0:0     283 kB          ├── jackson-core-2.8.9.jar

Ressourcen

Hier sehen wir /app/resources und alle zugehörigen Dateien aus unseren Ressourcenordnern.

┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────────────────────────────────────
Cmp   Size  Command                                                            Permission     UID:GID       Size  Filetree
     73 MB  FROM 679f8666b5733b3                                               drwxr-xr-x         0:0        0 B  └── app
     43 MB  apt-get update     && apt-get install -y --no-install-recommends t drwxr-xr-x         0:0        0 B      └── resources
    108 MB  set -eux;     ARCH="$(dpkg --print-architecture)";     case "${ARC -rw-r--r--         0:0        0 B          ├── application.properties
     30 MB  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0        0 B          └── org                     
       0 B  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0        0 B              └── snyk           
    6.4 kB  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0        0 B                  └── groceries
      79 B  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0        0 B                      ├── domain     
                                                                               drwxr-xr-x         0:0        0 B                      └── repository
│ Layer Details ├─────────────────────────────────────────────────────────────                                                                               

Tags:   (unavailable)                                                                                                                                        
Id:     7891783fbddf2ac3f624ecdea6fd7d51efa476bf87b82a3a1da2517167a7812a                                                                                     
Digest: sha256:bc7cee3aeb381d0b453212f345eaf34f55613c2dbb988af22f626877f4ecc89                                                                               
Command:                                                                                                                                                   
jib-maven-plugin:3.1.1                                              

Klassen

Dieser Layer enthält unter /app/classes die .class-Dateien aus der Kompilierungsphase des Builds.

┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────────────────────────────────────
Cmp   Size  Command                                                            Permission     UID:GID       Size  Filetree
     73 MB  FROM 679f8666b5733b3                                               drwxr-xr-x         0:0     6.4 kB  └── app
     43 MB  apt-get update     && apt-get install -y --no-install-recommends t drwxr-xr-x         0:0     6.4 kB      └── classes  
    108 MB  set -eux;     ARCH="$(dpkg --print-architecture)";     case "${ARC drwxr-xr-x         0:0     6.4 kB          └── org                   
     30 MB  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0     6.4 kB              └── snyk                
       0 B  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0     6.4 kB                  └── groceries  
    6.4 kB  jib-maven-plugin:3.1.1                                             -rw-r--r--         0:0     3.3 kB                      ├── SpringGoofApplicati
      79 B  jib-maven-plugin:3.1.1                                             drwxr-xr-x         0:0     1.7 kB                      ├── domain     
                                                                               -rw-r--r--         0:0     1.7 kB                      │   └── Item.class
│ Layer Details ├───────────────────────────────────────────────────────────── drwxr-xr-x         0:0     1.3 kB                      └── repository         
                                                                               -rw-r--r--         0:0     1.3 kB                          └── ItemRepository.
Tags:   (unavailable)                                                                                                                                        
Id:     5d4509a5f5856f5d6de92ed621d301861fccf414f9088d0c81e47572f48e4194                                                                                     
Digest: sha256:778c99f6b1c637ab73e3fff99e933d6d6a8d247f9849d2695066c4f2e823ee7                                                                               
Command:                                                                                                                                                   
jib-maven-plugin:3.1.1  

JVM-Argumentdateien

┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────────────────────────────────────
Cmp   Size  Command                                                            Permission     UID:GID       Size  Filetree
     73 MB  FROM 679f8666b5733b3                                               drwxr-xr-x         0:0       79 B  └── app
     43 MB  apt-get update     && apt-get install -y --no-install-recommends t -rw-r--r--         0:0       39 B      ├── jib-classpath-file
    108 MB  set -eux;     ARCH="$(dpkg --print-architecture)";     case "${ARC -rw-r--r--         0:0       40 B      └── jib-main-class-file       
     30 MB  jib-maven-plugin:3.1.1                                                                                                                    
       0 B  jib-maven-plugin:3.1.1                                                                                                               
    6.4 kB  jib-maven-plugin:3.1.1                                                                                                                           
      79 B  jib-maven-plugin:3.1.1                                                                                                                   

│ Layer Details ├─────────────────────────────────────────────────────────────                                                                               

Tags:   (unavailable)                                                                                                                                        
Id:     22877091a2de894cac9070c121b116e5d3247b3a4f81774032c0698bf6a2de2f                                                                                     
Digest: sha256:d8a8afa0a3d1efdb00b38b28e3dd075342c0dc65e52977e56dd3f21c277ae94                                                                               
Command:                                                                                                                                                   
jib-maven-plugin:3.1.1             

Schließlich enthält der Ordner /app im obersten Verzeichnis einige Dateien mit Argumenten, die beim Starten der JVM im Container verwendet werden. In diesem Beispiel würden Sie beim Prüfen dieser beiden Dateien den Runtime-Classpath und Informationen zur Main-Class finden.

# cat jib-classpath-file
/app/resources:/app/classes:/app/libs/*

# cat jib-main-class-file
org.snyk.groceries.SpringGoofApplication

Hinweis: Je nach Struktur Ihres Maven-/Gradle-Builds können Ihre mit Jib erstellten Images weitere Layer enthalten. Weitere Informationen zu den anderen möglichen Layern finden Sie in den häufig gestellten Fragen zu Jib.

Welches Basis-Image verwendet Jib, und was ist, wenn ich ein eigenes Image verwenden möchte?

Standardmäßig verwendet Jib für JAR-Builds das offizielle Docker-Hub-Basis-Image adoptopenjdk:jre-8 und für WAR-Builds das offizielle Docker-Hub-Basis-Image jetty. Das lässt sich über die Plugin-Konfiguration anpassen. Einzelheiten dazu finden Sie in der offiziellen Dokumentation, einschließlich der Konfiguration eigener Deklarationen wie ENTRYPOINT, USER oder weiterer Werte. Die Dokumentation erklärt auch, warum es sinnvoll ist, ein eigenes Basis-Image festzulegen und einen bestimmten Hash zu verwenden, um reproduzierbare Builds zu gewährleisten. Viele Unternehmen haben intern freigegebene Basis-Images, die Entwicklungsteams verwenden müssen und die von Sicherheits- und Betriebsteams geprüft und gehärtet wurden. Hier sehen Sie ein Beispiel dafür, wie Sie die Maven-Datei pom.xml anpassen, um ein solches Image zu verwenden.

<build>
<plugins>
...
<plugin>
...
<configuration>
<from>
<image>reg.mycorp.com/smalls-base/openjdk:8u292-2021.7.4</image>
</from>
...
</configuration>
...
</plugin>
...
</plugins>
</build>

Auch zusätzliche Einstellungen wie eine standardisierte Image-Kennzeichnung werden unterstützt. Angenommen, Ihr Unternehmen verlangt beispielsweise, dass alle Images die folgenden Labels enthalten:

  • Git-URL des Quellcodes

  • Git-Commit-ID/-Hash

  • Build-Version des Maven-Projekts

Wenn die pom.xml bereits auf diese Daten zugreifen kann, ist die Konfiguration des Jib-Plugins zum Hinzufügen der Labels ganz einfach:

<build>
<plugins>
...
<plugin>
...
<configuration>
...
<container>
<labels>
<git.remote.origin.url>${git.remote.origin.url}</git.remote.origin.url>
<git.commit.id>${git.commit.id}</git.commit.id>
<mvn.build.version>${project.version}</mvn.build.version>
</labels>
</container>
...
</configuration>
...
</plugin>
...
</plugins>
</build>

Wenn wir das erstellte Image prüfen, sehen wir, dass die Labels angewendet wurden – genau so, als wären sie über LABELS-Zeilen im Dockerfile hinzugefügt worden. (Hier verwende ich das großartige Kommandozeilen-Tool jq, um nur dieses Array aus der Antwort herauszufiltern.)

$ docker image inspect reg.mycorp.com/smalls/spring-goof:latest | jq .[].Config.Labels
{
  "git.commit.id": "960d768e9739ffb8e9a503c9ad3f6dad86ac68b1",
  "git.remote.origin.url": "git@github.com:mycorp-dev/spring-goof.git",
  "mvn.build.version": "0.0.1-SNAPSHOT"
}

Stellen Sie sich nun vor, all diese komplexen standardisierten Konfigurationen wären über <pluginManagement> und andere übliche Maven-Konfigurationen in einem übergeordneten POM definiert. Entwickler müssten sich dann weder um dieses Boilerplate-XML kümmern noch es überhaupt ansehen. Und Architekten könnten die Standards unternehmensweit durchsetzen und aktualisieren, ohne die Teams damit zu belasten!

Wie kann ich sicher sein, dass alles sicher ist?

Eine der Herausforderungen bei allgemeineren Tools zum Erstellen von Images wie Dockerfiles ist, dass Sie beim Build praktisch alles tun können: Pakete installieren, mit ADD Dateien von beliebigen Webservern herunterladen und viele weitere Schritte ausführen, die überprüft und genau unter die Lupe genommen werden müssen. Bei Jib werden viele dieser Entscheidungen automatisch getroffen. Um sie zu überschreiben, müssen Sie die Maven-/Gradle-Konfiguration explizit ändern. Diese Änderungen sind bei einer Code-Review klar erkennbar – genau wie Änderungen an Abhängigkeiten oder anderen Build-Konfigurationen.

Für Sicherheits-Scans bietet Snyk Container eine großartige Funktion: Empfehlungen für verschiedene Basis-Images mit weniger Schwachstellen. Ab sofort funktioniert diese Funktion auch ohne Dockerfile, aus dem hervorgeht, welches Basis-Image Ihr Image verwendet. So können Sie die Empfehlungen auch für mit Jib oder einem anderen Tool ohne Dockerfile erstellte Images nutzen.

Wenn Sie Ihre eigenen Java-Container prüfen möchten, erstellen Sie ein kostenloses Konto und erhalten Sie Anweisungen zur Installation des Snyk-Scan-Tools.

Für dieses Beispiel habe ich als Basis-Image openjdk:8u121-jre festgelegt, mvn package ausgeführt und das Image auf meinen Laptop heruntergeladen. Jetzt führe ich einfach den Befehl snyk container test dafür aus.

$ snyk container test localhost:5000/spring-goof:latest

Testing localhost:5000/spring-goof:latest...

... (a bunch of scan results removed here) ...

Organization:      mycorp-snyk-org
Package manager:   deb
Project name:      docker-image|reg.mycorp.com/smalls/spring-goof:latest
Docker image:      reg.mycorp.com/smalls/spring-goof:latest
Platform:          linux/amd64
Base image:        openjdk:8u181-jre-stretch
Licenses:          enabled

Tested 261 dependencies for known issues, found 410 issues.

Base Image                 Vulnerabilities  Severity
openjdk:8u181-jre-stretch  410              149 high, 91 medium, 170 low

Recommendations for base image upgrade:

Minor upgrades
Base Image             Vulnerabilities  Severity
openjdk:8-jre-stretch  205              71 high, 36 medium, 98 low

Major upgrades
Base Image                  Vulnerabilities  Severity
openjdk:11.0.5-jre-stretch  178              66 high, 28 medium, 84 low

Alternative image types
Base Image                         Vulnerabilities  Severity
openjdk:17-ea-22-oraclelinux8      0                0 high, 0 medium, 0 low
openjdk:16-jdk-oraclelinux7        0                0 high, 0 medium, 0 low
openjdk:17-ea-27-jdk-oraclelinux7  0                0 high, 0 medium, 0 low
openjdk:16-ea-29-jdk-oraclelinux8  0                0 high, 0 medium, 0 low

Wie Sie sehen, hat der Scan automatisch openjdk:8u181-jre-stretch als Basis-Image erkannt (dies ist ein Alias-Tag für openjdk:8u181-jre) und 410 Schwachstellen gemeldet. Außerdem wurden alternative Basis-Images empfohlen: von einem Upgrade auf eine kleinere Versionsstufe bis zum neuesten Tag openjdk:8-jre, der etwa halb so viele Probleme aufweist, bis hin zu neueren JVMs ohne bekannte Schwachstellen.

Sie sehen also: Wir können nicht nur feststellen, welche Schwachstellen in unserem Image vorhanden sind, sondern erhalten auch Empfehlungen, wie sie sich mit einem neueren Basis-Image beheben lassen – ganz ohne eine einzige Zeile Dockerfile-Code zu schreiben.

Zusammenfassung

Wie Sie sehen, kann Jib Entwicklern die Containerisierung ihrer Java-Anwendungen erheblich erleichtern, da sie weder die Dockerfile-Syntax erlernen noch unbekannte Tools installieren müssen. Außerdem unterstützt es Architekten dabei, Standards mithilfe der vertrauten Projekt-Hierarchien von Maven oder Gradle zu verwalten. Da Jib OCI-konforme Images erstellt, können Sie außerdem Industriestandard-Tools wie den Snyk-Container-Scanner verwenden, um Ihre Anwendung zu prüfen, bereitzustellen und auszuführen.

Wenn Sie auch ein Nicht-Java-Projekt unterstützen, kommen andere Tools in diesem Bereich infrage, etwa Buildah, Bazel, Earthly und verschiedene BuildKit-bezogene Projekte. Außerdem hat mein Kollege Pas Apicella kürzlich einen Artikel über Cloud Native Build Packs veröffentlicht, den Sie unbedingt lesen sollten.

Vergessen Sie nicht, ein kostenloses Konto zu erstellen und noch heute mit dem Testen Ihrer Container, Open-Source-Abhängigkeiten und Ihres IaC-Codes zu beginnen!

Sichern Sie Ihre Infrastruktur an der Quelle

Snyk automatisiert die IaC-Sicherheit und Compliance in Workflows und erkennt abweichende sowie fehlende Ressourcen.