GitLab FI

GitLab Continuous Integration

GitLab Continuous Integration (CI) slouží k automatizaci některých úkolů při vývoji v repozitáři, nejčastěji pro automatické jednotkové testování. Pro použití GitLab CI lze nakonfigurovat svůj vlastní fyzický nebo virtuální stroj (viz virtualizace Stratus.FI). Navíc lze také použít fakultní stroj gitlab-ci.fi.muni.cz.


Shrnutí

Fakultní gitlab-ci.fi používá oficiální GitLab Runner s kontejnerovou izolací ve službě Docker. Po spuštění nového úkolu (např. po git push do repozitáře) GitLab Runner požádá Docker o vytvoření nového kontejneru z obrazu, který je deklarován v repozitáři v souboru .gitlab-ci.yml. Do kontejneru se naklonuje repozitář a spustí se úkoly popsané ve zmíněném souboru. Po skončení se kontejner zruší a výsledek se vrátí GitLabu, který jej zobrazí v sekci CI/CD.


Konfigurace projektu pro gitlab-ci.fi.muni.cz

Nejdříve si přečtěte úvodní informace pro používání GitLab CI/CD. Dále budete potřebovat dokumentaci ke .gitlab-ci.yml.

Výběr obrazu

Používaný obraz se deklaruje v konfiguraci .gitlab-ci.yml jako hodnota klíče image. Formát je buď REPOSITORY:TAG nebo REPOSITORY (výchozí značka se pak použije latest). Pokud nezadáte žádný obraz, použije se alpine:latest.

image: maven:latest

Výběr verze

Značky Docker obrazů nejsou statické, tj. X:3.0 je pouze symbolický název pro nějakou verzi obrazu, přičemž se kdykoliv může stát, že správce repozitáře změní obraz, na který značka ukazuje. Verzování obrazů i význam samotných verzí závisí na správcích jednotlivých Docker repozitářů, obecně je však vhodné dodržovat principy sémantického verzování.

Pokud je to možné, preferujte obrazy v co nejobecnější hlavní verzi (např. preferujte X:3 místo X:3.5.0), aby měl váš projekt k dispozici obraz s bezpečnostními záplatami a opravami chyb v použitém softvéru.

Nedoporučujeme však používat latest pro důležité projekty. Tato symbolická značka obvykle ukazuje na nejnovější stabilní verzi obrazu, může se však bez varování posunout na novější verzi, která není zpětně kompatibilní.

Nastavení značky

Aby se stroj nezatěžoval úkoly z repozitářů, které mají nastavené vlastní CI, akceptuje gitlab-ci.fi úkoly pouze z těch projektů, které jsou označené značkou shared-fi, což lze nastavit následovně:

Nastavení artefaktů

Pro projekty, které vytváří artefakty, doporučujeme nastavit CI tak, aby je GitLab automaticky uklízel, když se vytvoří novější.

Pokud uklízení nenastavíte a artefakty projektu budou vytěžovat diskový prostor GitLabu, budou smazány administrátory.

Nejdřív v projektu zabezpečte, že GitLab zachová poslední artefakt:
ProjektSettingsCI/CDArtifacts → zaškrtněte Keep artifacts from most recent successful jobs

Pak do .gitlab-ci.yml přidejte nastavení, které nastaví životnost artefaktů na velmi malou hodnotu (méně než 2 hodiny, např. 10 minut). Toto nastavte pro každý úkol JOB.
Díky nastavení výše bude poslední artefakt zachován i po vypršení životnosti.

‹JOB›:
  artifacts:
    …
    expire_in: 10 minutes

Ukázky

Ve fakultním GitLab FI se můžete podívat do projektu unix/ci-examples, kde naleznete příklady konfigurace CI pro jednoduché projekty.


Container Registry

Služba Container Registry dává uživatelům možnost uložit si k projektu Docker obrazy, které pak lze využít v CI nebo jiných projektech.

Obrazy nemusí s obsahem projektu nijak souviset. Pravděpodobně však budete k obrazu mít i Dockerfile a další závislosti, doporučujeme si tedy pro tyto soubory vytvořit repozitář, který bude zároveň udržovat aktuální verzi obrazu.

Ke Container Registry se lze připojit na stroji gitlab.fi.muni.cz a portu 5050.

Nastavení služby

  • Zapnutí služby

    V projektu, který má udržovat sestavené obrazy, zapněte
    SettingsGeneralVisibility, project features, permissionsContainer Registry.
    Službu není nutno zapínat pro projekty, které mají obraz pouze používat v CI.
  • Omezení počtu značek

    Obrazy v Container Registry zabírají obvykle mnoho místa. Častá změna značek může diskový prostor rychle vyčerpat, proto zapněte pro projekt automatické čištění:
    V nastavení SettingsPackages & Registries zapněte možnost Clean up image tags. Doporučujeme taky změnit nastavení Keep the most recent: na hodnotu 5 tags per image name.
  • Přístup k obrazu

    Přístup k obrazům se obecně řídí přístupovými právy k rodičovskému projektu:
    • Private – Pouze členové projektu
    • Internal – Pouze osoby přihlášené do GitLab FI
    • Public – Bez omezení
    Navíc lze přístup omezit výše uvedeným nastavením z Everyone with access na Only project members.

Vytvoření obrazu

Obraz vytvořte lokálně ve vlastní instanci Dockeru (příkazy níže). Lze nastavit i automatické sestavování obrazu pomocí CI, musíte si však pro ni z bezpečnostních důvodů nastavit vlastní CI Runner. Název obrazu, který se má umístit do GitLab Container Registry, musí začínat doménou a portem ve formátu gitlab.fi.muni.cz:5050, a pokračovat cestou k projektu.

Například pro projekt https://gitlab.fi.muni.cz/NAMESPACE/PROJECT.git tedy lze vytvořit obrazy s názvy tvaru

Pokud jste s obrazem spokojeni, můžete jej nahrát do Container Registry:

    docker login --username ‹LOGIN› gitlab.fi.muni.cz:5050
    docker push gitlab.fi.muni.cz:5050/NAMESPACE/...

V prvním příkazu místo ‹LOGIN› použijte svůj fakultní login. Příkaz se po spuštění zeptá na heslo; zadejte fakultní heslo nebo přístupový token GitLabu (musí mít alespoň rozsahy read_registry a write_registry i přesto, že podle dokumentace stačí pouze to druhé – je zřejmě o chybu).

Pro ukázku se můžete podívat na soubor Makefile v repozitáři https://gitlab.fi.muni.cz/xlacko1/pb173-perl-image.

Použití v GitLab CI

Nový obraz lze používat jak ve vlastní instanci Dockeru, tak i v úlohách GitLab CI/CD. Pouze v nastavení image: uveďte celou cestu k vlastnímu obrazu.

Například, pokud v repozitáři https://gitlab.fi.muni.cz/xlacko1/pb173-perl-image chceme vytvořit obraz s názvem perl-5.32:1.0, pak v adresáři s Dockerfile pro tento obraz vykonáme příkazy:

    $ docker build -t gitlab.fi.muni.cz:5050/xlacko1/pb173-perl-image/perl-5.32:1.0 .
    $ docker login --username LOGIN gitlab.fi.muni.cz:5050
    $ docker push gitlab.fi.muni.cz:5050/xlacko1/pb173-perl-image/perl-5.32:1.0

V projektu, ve kterém chceme vytvořený obraz použít pro CI, deklarujeme v souboru .gitlab-ci.yml:

image: https://gitlab.fi.muni.cz/xlacko1/pb173-perl-image:1.0

# The 'shared-fi' tag is necessary to use the faculty-wide CI
default:
  tags:
    - shared-fi

Automatické sestavování obrazu

GitLab CI lze použít k automatickému sestavení Docker obrazu a jeho nahrání do Container Registry, typicky pomocí obrazu docker:dind (Docker-in-Docker).

Tato operace však vyžaduje povolit pro kontejner s úlohou privilegovaný režim, aby mohl kontejner zadávat Docker démonovi příkazy. Zároveň však umožní kontejneru obejít bezpečnostní mechanismy systému a převzít nad ním kontrolu. Proto je tato možnost na sdíleném GitLab CI vypnuta.

Pokud chcete sestavovat obrazy automaticky, musíte si nastavit vlastní CI Runner. Doporučujeme využít virtuální stroj ve Stratus.FI. Alternativně můžete službu spustit i na vlastním počítači, mějte však na paměti, že takto si můžete otevřít prostor na Privilege Escalation útok.

  • Virtuální stroj nebo počítač?

    Pro tento úkol silně doporučujeme použít virtuální stroj ve službě Stratus.FI. Mělo by stačit využít předinstalovaný virtuální stroj.

    Využití vlastního počítače je taky možné. Berte však na vědomí, že v případě chyby konfigurace hrozí riziko eskalace oprávnění nebo převzetí kontroly nad počítačem. Totéž hrozí i pro virtuální stroj, rozsah problému je však v tomto případě menší.
  • GitLab CI Runner

    Nainstalujte GitLab Runner (→ Install on GNU/Linux pro Linux).
  • Docker in Docker

    Nakonfigurujte CI Runner pro sestavování Docker obrazů podle oficiálního návodu. Doporučujeme možnost Docker-in-Docker.
  • Registrace

    Zaregistrujte Runner pouze pro projekt, ve kterém se mají sestavovat obrazy, vizte Project Runners.
  • Zabezpečení projektu

    Zabezpečte, aby spuštění úlohy v CI mohli provádět pouze důvěryhodní uživatele v projektu (Owner, Maintainer). Zejména zabraňte tomu, aby nedůvěryhodní uživatelé mohli vytvořit Merge Request s vlastním kódem, pro který by se spustila úloha.

    Vizte Protected Branches a Pravidla pro .gitlab-ci.yml.
  • Umístnění .gitlab-ci.yml

    Potenciální útočník si může .gitlab-ci.yml změnit dle libosti a obejít nastavení výše. Toto je vážný problém zejména pro veřejné a interní projekty.

    Tento problém lze vyřešit nastavením projektu tak, aby .gitlab-ci.yml hledal v jiném privátním repozitáři, kde ho mohou upravovat pouze důvěryhodní uživatelé. Lokální soubor se pak bude ignorovat. Vizte Custom CI/CD configuration fileCustom CI/CD configuration file examples.

    Pozor, nastavení CODEOWNERS nestačí, pouze zabrání nežádanému Merge v případě, že se změnil chráněný soubor, ale úkoly pro CI se stále spustí.

Nakonec, zvažte, zda je automatické sestavování obrazu skutečně nevyhnutné. Pokud obraz sestavujete zřídka, nejbezpečnější možnost je sestavit obraz ve vlastní instanci Dockeru podle návodu výše.


Časté potíže a řešení

Zaseknuté úkoly

Pokud po konfiguraci projektu narazíte na chybu Job is stuck, pravděpodobně jste v konfiguraci úkolu neuvedli značku shared-fi. Zkontrolujte si nastavení podle postupu výše.

Nelze používat Docker příkazy v úloze

Pokud narazíte na chybu typu dial tcp: lookup docker on 147.251.48.14:53: no such host, pravděpodobně se snažíte použít fakultní CI Runner v privilegovaném režimu. To není z bezpečnostních důvodů povoleno, vizte Automatické sestavování obrazu výše.