Hinweis zum Integrationstest Verwenden von Jenkins unter Kubernetes

Guten Tag.


Fast unmittelbar nach der Installation und Konfiguration von CI / CD gemäß den Anweisungen aus dem vorherigen Beitrag hatte das Team die Frage, wie Integrationstests ordnungsgemäß durchgeführt werden können. Wir hatten bereits Erfahrung mit dem Ausführen von Testabhängigkeiten in Docker-Containern. Dies ist jedoch problematisch geworden, da die Assembly selbst jetzt im Container gestartet wurde. In diesem Artikel möchte ich zwei mögliche Methoden für Integrationstests innerhalb des Containers beschreiben, die zu meinem Team passen.


Anforderungen an Integrationstests


Integrationstests sind per Definition Tests, die den Betrieb einer Anwendung mit ihren abhängigen Komponenten testen. Beispiele hierfür sind Datenbanken, Warteschlangen und andere Dienste.


Im Rahmen der Tests wollten wir:


  • Führen Sie Tests gleichermaßen lokal und auf Jenkins durch
  • Vermeiden Sie die Vorinstallation und Konfiguration abhängiger Anwendungen
  • Deklarieren und Ausführen von Abhängigkeiten mithilfe von Dateien im Projekt-Repository
  • mehrere Baugruppen gleichzeitig ausführen können
  • Es ist ratsam, in Zukunft neue Abhängigkeiten hinzufügen zu können
  • Es ist ratsam, mit verschiedenen Versionen derselben Abhängigkeit testen zu können

Aufgrund dieser Anforderungen haben wir die Idee einer dauerhaften gemeinsamen Installation von Testdatenbanken und Warteschlangen aufgrund von Problemen bei der gemeinsamen Nutzung von Ressourcen zwischen Assemblys und der Schwierigkeit, diese Infrastruktur zu warten und zu ändern, sofort verworfen.


Option 1: Eingebettete Lösungen


Es gibt einige Bibliotheken im Java-Ökosystem, die eine Abhängigkeit für einen Test ausführen:



Dieser Ansatz ist so einfach wie möglich und erfüllt die meisten der zuvor beschriebenen Anforderungen, ist jedoch nicht universell in Bezug auf das Hinzufügen neuer Testabhängigkeiten (MySQL?) Oder die Verwendung spezifischer oder vieler Versionen von Abhängigkeiten.


Gut geeignet für einfache Dienste mit 1-2 Abhängigkeiten.


Option 2: Testcontainer


Docker ist ein logischer Weg, um die Mängel des vorherigen Ansatzes zu beheben: Sie können für jede Abhängigkeit mit jeder Version ein Docker-Image finden (oder erstellen). Wahrscheinlich werden einige der Abhängigkeiten in der Produktion mit denselben Bildern ausgeführt.


Wenn das lokale Starten des Images (oder mehrerer mit Docker-Compose) kein Problem darstellt, hat CI Schwierigkeiten, da die Assembly selbst im Container stattfindet. Obwohl es möglich ist, Docker in Docker auszuführen, wird dies vom Dind-Ersteller nicht empfohlen . Der bevorzugte Weg, um dieses Problem zu umgehen, besteht darin, den bereits ausgeführten Docker-Prozess wiederzuverwenden, der häufig als Geschwister-Docker bezeichnet wird. Dazu benötigen Sie den /var/run/docker.sock Docker-Prozess, um /var/run/docker.sock vom übergeordneten Docker zu verwenden. In einem früheren Beitrag wurde dies bereits verwendet, um Docker-Images mit einer kompilierten Anwendung zu veröffentlichen.


Es wurde beschlossen, die Testcontainer- Bibliothek zu verwenden, da:



Gut geeignet für komplexere Dienste oder für Dienste mit besonderen Abhängigkeitsanforderungen.


Ressourcenmanagement


Als Nächstes sollten Sie auf den Ressourcenverbrauch der Projektassembly achten (der nach dem Hinzufügen von Integrationstests erheblich zunehmen kann).


Derzeit gibt die Assembly nicht die erforderliche Menge an Speicher und CPU-Freigaben an, was zwei potenzielle Probleme sein könnte:


  • Das erste sind zu viele parallele Baugruppen auf derselben Maschine, was zu einem hohen Lastfaktor führt. Versammlungen werden wahrscheinlich vergehen, aber sie werden viel mehr Zeit damit verbringen.
  • Der zweite ist OOM töten. Kubernetis entscheidet möglicherweise, dass Sie zu viel Speicher verbrauchen, und beendet Assemblys einfach, bevor sie abgeschlossen sind.

Sie können die Ressourcen des Containers im Kamin mithilfe der folgenden Konstruktion begrenzen:


  resources: requests: cpu: 1 memory: 512Mi limits: cpu: 1 memory: 512Mi 

Jdk9 und höher unterstützen bereits das Arbeiten in einem Container (-XX: + UseContainerSupport (standardmäßig aktiviert), funktioniert in Kombination mit -XX: InitialRAMPercentage / -XX: MaxRAMPercentage)


Ein vollständiges Beispiel finden Sie hier .


Damit Jdk8 ordnungsgemäß funktioniert, ist entweder Update 131 oder höher mit den -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap erforderlich, mit -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap der verfügbare Speicher von cgroup und nicht vom Hostcomputer gelesen wird, oder jedes Mal wird die verfügbare Xmx manuell mit Xmx .
Ein Beispiel finden Sie hier .


Es ist erwähnenswert, dass kubernetes nichts über die Ressourcen weiß, die für Container ausgegeben werden, die mit Testcontainern oder Geschwister-Docker ausgeführt werden. Um in dieser Situation korrekt zu arbeiten, können Sie Ressourcen im Maven-Container unter Berücksichtigung aller Testabhängigkeiten reservieren.


Fazit


Integrationstests beim Starten eines Builds in einem Container sind möglich und keine schwierige Aufgabe.


Eine Beispielanwendung mit Integrationstests mit Testcontainern finden Sie hier und die Konfiguration zum Ausführen von Jenkins auf Kubernetes finden Sie hier .

Source: https://habr.com/ru/post/de451588/


All Articles