Software Development

Wprowadzenie do JIB

25 maja, 2021 0
Podziel się:

Docker jest narzędziem na tyle powszechnym, że można się z nim spotkać w ogromnej liczbie projektów, co z kolei niejako wymusza na nas, programistach, zapoznanie się z ową technologią w mniej lub bardziej dokładny sposób – zależnie od potrzeb. Niektórzy z nas zatrzymali się na etapie uruchomienia aplikacji, inni zaś wczytali się głębiej w dokumentację, poznając zaawansowane zagadnienia Dockera. Niezależnie od tego, do której z grup należysz, Jib pomoże Ci znacznie zautomatyzować codzienną pracę z wyżej wymienionym narzędziem.

Czym jest Jib?

Jib jest opensource’owym, napisanym w języku JAVA, narzędziem dostępnym w postaci pluginu (zarówno Mavenowego jak i Gradle’owego), którego zadaniem jest uproszczenie procesu budowania obrazów dockerowych w możliwie największym stopniu. Dodając ten plugin do konfiguracji projektu, możemy zapomnieć o kilku rzeczach, które do tej pory mogły sprawiać problem lub przynajmniej irytować ze względu na swoją powtarzalność. Jako że jest on ściśle związany z samą aplikacją, jest w stanie spakować ją do postaci obrazu w sposób optymalny, tzn. z odpowiednim podziałem na warstwy oraz z zachowaniem możliwie najmniejszego rozmiaru i czasu budowania. Pisanie plików Dockerfile, wklepywanie w konsolę wciąż tych samych poleceń, a nawet instalacja Dockera – są to rzeczy, o których Jib pozwala zapomnieć.

Jedną z zalet Jiba, o której należy wspomnieć, jest fakt, że buduje on obraz w oparciu o warstwy. Każdy z elementów aplikacji (klasy, zasoby, zależności, dodatkowe zasoby) umieszczony zostaje w osobnej warstwie.

Proces

Każdorazowe budowanie obrazu opiera się o szereg czynności, z których część jest jednorazowa, jak np. napisanie Dockerfile’a, inne zaś są powtarzalne, np. uruchomienie budowania poprzez odpowiednie polecenie. Standardowy przebieg tego procesu wygląda w następujący sposób:

  1. Instalacja Dockera
    O ile punkt ten jest raczej jasny i nie trzeba go tłumaczyć, to warto dodać, że na systemach z rodziny Windows może on sprawiać trudności, gdyż Docker wspiera ten system dopiero od wersji 10.
  2. Napisanie Dockerfile’a
    Dockerfile dockerfile’owi nierówny. Samo utworzenie tej konfiguracji jest rzeczą jednorazową i względnie prostą, jednak można to zrobić w poprawny lub optymalny sposób.
  3. Zbudowanie projektu
  4. Utworzenie obrazu aplikacji
    Jest to najbardziej powtarzalna z czynności, która polega na wywołaniu polecenia „docker build”. Problematyczność może powstać w przypadku, gdy nasz projekt się rozrasta, a wraz z nim rośnie poziom zaawansowania aplikacji. W takim przypadku owe polecenie z wersji podstawowej również może się rozrosnąć o zestaw dodatkowych opcji. I o ile samo to nie jest problemem, to w przypadku, gdy za którąś iteracją zapomnimy o jednym z nich może dojść do utraty kilku godzin czasu pracy i zyskaniu kilku nowych siwych włosów.
  5. Wypchnięcie projektu
    Nie jest to część budowania obrazu, gdyż takowy mamy już po wykonaniu punktu 4 (o ile nie popełniliśmy jakiegoś błędu po drodze), jednak bardzo często zachodzi również potrzeba umieszczenia go z kontenerze obrazów.

Każdy z wyżej wymienionych punktów może sprawiać problemy lub po prostu sprawiać kłopot swoim istnieniem. Jib pozwala zniwelować te problemy praktycznie do zera, a powyższą listę skrócić do zaledwie jednego punktu, którym jest zbudowanie projektu. Skoro mamy już odpowiedź na pytanie „Po co?”, sprawdźmy teraz jak brzmi odpowiedź na pytanie „Jak?”.

Nieco praktyki

Program, który będziemy próbowali uruchomić to prosta aplikacja oparta o Spring Boot, zawierająca jeden endpoint zwracający „Hello World!”.

package com.jibintroduction;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class JibIntroductionApplication {

    public static void main(String[] args) {
        SpringApplication.run(JibIntroductionApplication.class, args);
     }

     @GetMapping("/say/hello")
     String sayHello() {
          return "Hello World!";
     }
}

Pierwszym krokiem jest dodanie odpowiedniego pluginu. Zarówno w przypadku korzystania z Gradle, jak i Mavena konfiguracja wygląda analogicznie, tj. nazwy pól i możliwe wartości są takie same. Jedyna różnica występuje w nazwach goali, jednak o tym opowiem później. Prezentowany przykład wykorzystywał będzie narzędzie Gradle.

plugins {
     id 'org.springframework.boot' version '2.4.4'
     id 'io.spring.dependency-management' version '1.0.11.RELEASE'
     id 'java'
     id 'com.google.cloud.tools.jib' version '2.8.0'
}

Aby plugin ten mógł poprawnie wykonywać swoje zadanie potrzebuje przynajmniej minimalnej konfiguracji. Należy zdefiniować, który obraz ma być obrazem bazowym dla naszej aplikacji (FROM) oraz jak ma się nazywać obraz wynikowy (TO).

jib {
    from {
         image = 'openjdk:alpine'
     }
     to {
         image = 'repositoryName/jib-introduction'
     }
}

Aplikacja, którą utworzona na potrzeby tego artykułu będzie domyślnie nasłuchiwała na ruch na porcie 8080, dlatego należy ten port aktywować (odpowiednik EXPOSE 8080 w dockerfile). Lista opcji, które można ustawić w tym miejscu jest naprawdę duża. Dla przykładu można dodać listę argumentów, z którymi zostanie uruchomiona nasza aplikacja.

 
container {
jvmFlags = ['-Xms1024m', '-Xdebug']
args = ['some', 'random', 'input', 'text']
ports = ['8080']
}

Konfiguracja konieczna do utworzenia prostego obrazu jest gotowa, jednak to nie wszystko. Pozostaje nam jeszcze skonfigurowanie dostępu do rejestru obrazów. Mowa konkretnie o autoryzacji.
Sposobów jest kilka, a to, który należy użyć zależy od rejestru, który wykorzystujemy. Opis tego zagadnienia to materiał na kolejny artykuł, dlatego tym razem skupimy się na rejestrze dockerhuba. W tym przypadku należy jedynie podać nazwę użytkownika oraz hasło (wartości USERNAME oraz PASSWORD ustawione zostały w pliku gradle.properties).

jib {
    from {
         image = 'openjdk:alpine'
    }
   to {
       image = 'repositoryName/jib-introduction'
       tags = ['latest', '1.0.0']
       auth {
            username = USERNAME
            password = PASSWORD
       }
   }
}

Następnym krokiem jest uruchomienie pluginu oraz sprawdzenie, czy obraz trafił do rejestru. Goale, z których należy skorzystać wyglądają następująco: Zbudowanie i umieszczenie w Docker deamon: jibDockerBuild (Gradle)dockerBuild (Maven).
Zbudowanie i umieszczenie w zewnętrznym rejestrze obrazów: build (Gradle / Maven). Przykładowy wynik, który możemy otrzymać po umieszczeniu obrazu w Dockerhub:jib ostatni 1 1024x562 - Wprowadzenie do JIB

Powyższa konfiguracja jest wystarczająca, by uruchomić przykładową aplikację. Istnieje jednak szereg parametrów, które mogą dostać skonfigurowane. Umożliwiają m.in. zdefiniowanie bardziej skomplikowanego punktu wejścia/ uruchomienia aplikacji, dodanie wolumenów i wiele innych rzeczy. Zachęcam do zapoznania się z nimi. Można je bez problemu znaleźć w dokumentacji Jiba.

Po pobraniu obrazu z repozytorium Dockerhub i uruchomieniu kontenera powinniśmy zobaczyć standardowe logi Spring Boota (o ile nie użyliśmy flagi -d). Następnie można przejść do sprawdzenia, czy wszystko działa. Po wywołaniu polecenia curl http://localhost:8080/say/hello naszym oczom powinien ukazać się napis „Hello World!”.

Podsumowanie

Zadaniem Jiba jest zautomatyzowanie pracy developera oraz zniwelowanie szansy na błędy natury ludzkiej spowodowanych m.in. powtarzalnością działań, niedoinformowaniem lub brakiem doświadczenia. Na powyższym przykładzie widać, że doskonale radzi sobie ze swoim zadaniem. W dodatku jest narzędziem o bardzo niskim progu wejścia i nie wymaga klęczenia nad dokumentacją, a niniejszy artykuł powinien wystarczyć, by móc rozpocząć pracę z owym pluginem. Gorąco zachęcam do samodzielnego przetestowania Jiba i zagłębienia się w dokumentację. 🙂

Patryk Stępniak
Autor: Patryk Stępniak
Programista, który: 1. Lubi, gdy rozumie dlaczego coś działa. 2. Uwielbia, gdy rozumie dlaczego coś nie działa.

    Imię i nazwisko (wymagane)

    Adres email (wymagane)

    Temat

    Treść wiadomości

    Zostaw komentarz