Ich verarbeite meine Buildchain via Gitlab CI. Neben dem eigentlichen Build der Applikation, der Frontend-Assets werden zahlreiche Tests ausgeführt, die Code-Qualität geprüft und am Ende die fertige Website deployed. Da kommen einige Jobs zusammen. Wie schön wäre es, wenn immer genügend Gitlab-Runner zur Verfügung stehen würden? Wir brauchen autoscale Gitlab-Runner. Eine Anleitung.

Gitlab-Runner: Autoscaling in der HETZNER-Cloud.

Wofür brauche ich einen Gitlab-Runner?

Jeder Job innerhalb der Gitlab CI wird von einem sogenannten Runner ausgeführt. Dieser Runner ist an und für sich nichts besonderes; er erhält vom Gitlab-Server eine Aufgabe (z.B. "Baue die Applikation", "Teste Syntax auf Gültigkeit" oder "Deploye das Ergebnis auf den Produktiv-Server") und die passenden Daten (in der Regel das Gitlab-Repository) und arbeitet sie ab - das Ergebnis wird (auf Wunsch) zursückgeschickt und steht dann nachfolgenden Jobs zur Verfügung.

Ein Gitlab-Runner hat in der Regel kein Gedächtnis, kann sich aber Dinge merken (insbesondere wichtig für das Caching). 

Nun kann man Gitlab Runner problemlos auf einem Server registrieren, um erste Gehversuche mit Gitlab CI zu machen. Sobald man dieses Tool aber ernsthaft benutzt, stellt man fest, dass Jobs zu lange warten müssen, weil kein Runner frei ist. Wir wollen die Buildchain aber so schnell wie möglich abarbeiten und warten ist tote Zeit. 

Mehr Runner!

Die erste Reaktion auf einen Mangel ist: Mehr davon! Wir brauchen Runner! Spätestens wenn diese Runner aber über mehrere Server verteilt sind - und an diesen Punkt kommt man schneller, als man denkt: Runner können sehr viel Last auf einem Server erzeugen! - gibt es ein neues Problem: Runner auf unterschiedlichen Servern können sich nicht so ohne weiteres einen Cache teilen. Das macht die Buildchain aber wieder langsamer. Ein Dilemma.

Hinzu kommt ein wirtschaftlicher Aspekt: Die wenigsten von uns werden rund um die Uhr arbeiten. Wie überall gibt es Phasen, in denen die Luft brennt und man Runner ohne Ende braucht; dann ist es aber (typischerweise nachts und am Wochenende) auch komplett ruhig und es gibt nichts zu tun. Und es gibt normale Arbeitstage, an denen deutlich weniger durch die Build-Chains läuft als sonst.

Alle Runner, die man zu Spitzenzeiten benötigt, ständig vorzuhalten, ist ökonomischer und ökologischer Unsinn. 

Chart auf einem Computer-Bildschirm

Autoscaling!

Das Ziel ist also, immer dann viele Runner zur Verfügung zu haben, wenn wir sie brauchen. Und wenn wir sie nicht brauchen, sollen diese sich abschalten. Wir brauchen Autoscaling!

Gitlab Runner sind ein ausgezeichnetes Beispiel, wo aus meiner Sicht Cloud-Computing sinnvoll ist. Die Runner selbst haben untereinander keine Abhängigkeiten; es ist einfach eine kleine Software-Armee, die auf Arbeit wartet und diese erledigt. Ob es einen, drei oder fünfhundert Runner gibt, ist für die Buildchain egal.

Die Auswahl des richtigen Cloud-Anbieters

Hier gibt es im eigentlichen Sinn kein richtig oder falsch. Grundsätzlich sind alle Anbieter von Cloud-Lösungen dafür geeignet, sofern sie eine entsprechende API zur Verfügung stellen, um Server automatisiert zu starten, konfigurieren und wieder zu löschen. 

Das ist natürlich bei den Großen der Fall: Amazon AWS, Google Cloud-Front, Microsoft Azure, Akamai, Digital Ocean usw. können das alle. Ich habe mich für das Cloud-Angebot von HETZNER entschieden, weil ich zum einen schon lange Server bei diesem Provider stehen habe und immer gute Erfahrungen mit dem Support gesammelt habe. Zum anderen ist der Serverstandort wählbar, und man kann z.B. Server in Deutschland wählen, wenn man das möchte (was ich tue).

Die Preise von HETZNER sind sehr fair: der kleinste Server ist für knapp 3,- €/Monat zu haben, wenn er ununterbrochen läuft. Da wir u.U. sehr viele Schaltzeiten haben, habe ich Wert darauf gelegt, einen Tarif zu wählen, der nur die reine Laufzeit und keine Setup-Kosten o.ä. berechnet.

Für die Gitlab-Runner habe ich die CX21-Server gewählt. Diese bieten genügend Power für die Abarbeitung der Jobs, sind mit 1 ct/Stunde aber immer noch sehr günstig. Die CX11-Server reichen zum Ausprobieren, bei größeren Jobs kam ich damit aber an die Grenze des Hauptspeichers. 

Wer das bei der HETZNER cloud testen möchte, kann sich hierüber anmelden: https://hetzner.cloud/?ref=wNQZvWvSsgiI (Bei Anmeldungen über diesen Link bekomme ich eine kleine Provision in Form von Cloud-Guthaben von HETZNER). 

Wir brauchen einen Dirigenten

Orchester

Damit unser Orchester von Gitlab-Runnern funktioniert, benötigen wir einen Dirigenten. Dieser nimmt von Gitlab CI die Jobs entgegen und weist diese den Runnern zu. Gleichzeitig stellt er sicher, dass immer ausreichend Runner bereit stehen und schaltet Runner ab, die nicht mehr benötigt werden. 

Ich nenne diese Rolle Broker und habe den Server entsprechend benannt. Mein Broker ist ebenfalls ein Server in der HETZNER Cloud; und hier reicht bislang auch problemlos ein kleiner CX11-Server. Dieser Server läuft die ganze Zeit. 

Der Broker übernimmt bei mir noch eine weitere wichtige Rolle: er stellt Speicherplatz zur Verfügung, um Caches zwischenzuspeichern. Dies ist auch der Grund, warum ich einen Cloud-Server für den Broker benutze und diesen Dienst nicht von einem bereits bestehenden Server mit-erledigen lasse. Es ist sinnvoll, dass Broker und Gitlab-Runner netzwerktopologisch nah beiander sind, um Latenzen und Übertragungszeiten gering zu halten. Bei einer Buildchain zählt jede Sekunde und der Preis für den Broker ist sehr gut investiertes Geld.

Damit der Broker nicht aus Versehen abgeschaltet oder gar gelöscht wird, kann man diesen über die Cloud-Verwaltung schützen. 

Die Konfiguration des Brokers

Für die Konfiguration des Brokers habe ich ein Gitlab-Runner-Image von mawalu benutzt. Damit kann der Gitlab-Runner einfach in einem Docker-Container gekapselt laufen und macht wenig Probleme bei der Konfiguration. Das Projekt findet ihr hier: https://github.com/mawalu/hetzner-gitlab-runner

Die docker-compose.yml ist simpel: 

 

# docker-compose.yml
version: '2'
services:
  hetzner-runner:
    image: mawalu/hetzner-gitlab-runner:latest
    mem_limit: 128mb
    memswap_limit: 256mb
    volumes:
      - "./hetzner_config:/etc/gitlab-runner"
    restart: always

 

Mit docker-compose up -d wird der Broker gestartet. Anschliessend wird mit docker-compose run hetzner-runner register der Runner beim Gitlab-Server angemeldet und dadurch im Verzeichnis hetzner_config eine config.toml hinterlegt und die Verbindung zu Gitlab CI hergestellt. Diese config.toml werden wir gleich noch modifizieren.

Der Broker wird mit docker-compose run gestartet und ist dann aktiv. Änderungen an der config.toml wirken sich sofort aus; der Broker braucht nicht neu gestartet zu werden!

Meine config.toml sieht so aus (vertrauliche Informationen sind entfernt): 

 

[[runners]]
  name = "[HETZNER] Cloud-runner with autoscale"
  limit = 15
  url = "*************"
  token = "*************"
  executor = "docker+machine"
  environment = ["COMPOSER_CACHE_DIR=/composer-cache"]
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "marcwillmann/codeception"
    memory = "2048m"
    privileged = true
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/cache:/cache:rw", "/var/run/docker.sock:/var/run/docker.sock"]
    pull_policy = "if-not-present"
    shm_size = 536870912
  [runners.machine]
    IdleCount = 2
    IdleTime = 600
    MachineDriver = "hetzner"
    MachineName = "runner-%s"
    MachineOptions = ["hetzner-api-token=*************", "hetzner-image=ubuntu-18.04", "hetzner-server-type=cx21"]
    OffPeakPeriods = ["* * 0-8,19-23 * * mon-fri *", "* * * * * sat,sun *"]
    OffPeakTimezone = "Europe/Berlin"
    OffPeakIdleCount = 1
    OffPeakIdleTime = 600
  [runners.custom]
    run_exec = ""

 

Den HETZNER-API-Token bekommt man in der Cloud-Console (https://console.hetzner.cloud/), wenn man ein neues Projekt anlegt und dort unter Zugänge -> API-Tokens.

Mit diesem Token darf der Broker nun neue Server starten und bestehende löschen.

In der Konfiguration gibt es den IdleCount. Soviele Runner stellt unser Autoscale immer als Reserve zur Verfügung: in der Cloud-Console kann man das sehr gut beobachten. Direkt nach dem Start werden dort 2 Gitlab-Runner gestartet und warten auf Jobs. Läuft eine Gitlab-CI-Pipeline und wird einem (oder normalerweise mehreren) dieser Runner ein Job zugeteilt, erscheinen neue Server. Mit diesem Wert muss man ein wenig experimentieren. Ist er zu klein gewählt, müssen Jobs warten, bis ein neuer Runner gestartet ist (das dauert einen kleinen Moment, bis er einsatzbereit ist). Ist er zu hoch, verschenkt man Geld, weil unbenötigte Rechenpower vorgehalten wird.

Die IdleTime gibt an, wie lange ein Runner behalten wird, wenn er mit einem Job fertig ist. Kommt in der Zwischenzeit ein neuer Job, wird er wiederverwendet. Kommt kein Job, wird der Runner gelöscht.

Ich habe gute Erfahrungen mit einer IdleTime von 600 gemacht; der IdleCount steht bei mir im Produktivsystem momentan auf 5.

Weil wir alle hoffentlich einigermaßen geregelte Arbeitszeiten haben und nicht die ganze Nacht durcharbeiten, gibt es in der Konfiguration noch die OffPeak-Einstellungen. Hier können Zeiten angegeben werden, wenn die Pipeline nicht oder nur wenig gefordert wird (nach Feierabend, am Wochenende). In diesen Zeiten kann man dann einen eigenen OffPeakIdleCount (z.B. 0 oder 1) konfigurieren, um die Kosten zu reduzieren.

Übrigens: auch ein IdleCount=0 heisst nicht, dass nicht gearbeitet werden kann. Es werden nur keine Reserven vorgehalten, d.h. es dauert etwas länger, bis der Job anläuft. Für einen normalen NightlyBuild, bei dem es nicht auf Sekunden ankommt, ist das aber kein Problem.

Zeit für Verbesserungen

Damit läuft das grundsätzliche Setup schon mal. Jobs im Gitlab werden an den Broker verteilt, der dafür sorgt, dass immer genügend Runner bereit stehen und versorgt diese mit den Aufgaben. Die Zahl der Runner wird nachskaliert.

Die Runner selbst haben aber kein Gedächtnis: die Jobs selbst laufen leider momentan eher langsam. Das liegt aber nicht an fehlender Power: in der Job-Ausgabe fällt auf, dass z.B. unser Application-Build-Job kein Paket im Composer-Cache findet. Das ist auch logisch, der Server für den Runner wurde ja gerade erst gestartet und kann keinen Cache haben. Und von dem Cache, den ein anderer Runner gerade erst aufgebaut hat, weiß unser Runner nichts. Das müssen wir ändern!

Schritt 1: Platz bereitstellen

Wir bauen einen zentralen Cache auf, auf den alle Runner lesend und schreibend zugreifen dürfen. Welcher Platz dafür wäre besser geeignet als der Broker: der steht netzwerktopologisch direkt neben den Runnern, ist immer verfügbar und die Runner können ihn auch erreichen. 

Damit auf dem Broker genügend Platz verfügbar ist und dieser auch einen Delete/Rebuild des Broker-Servers überlebt, habe ich ein Volume angehängt. Das ist ein persistenter Dateispeicher, den man jederzeit problemlos vergrößern kann. Momentan nutze ich ein 25GB-Volume als gitlab-runner-cache. 

Das Volume kann über die Hetzner Console einfach angehängt werden und ist vom System aus dann unter /dev/disk/by-id/scsi-0HC_VolumeXXXX sichtbar. Dort verhält es sich wie eine normale Festplatte und kann mit dem Filesystem der Wahl (ext4 in meinem) formatiert und gemountet werden. 

Auch das ist in der Hetzner Console nachzulesen, der Vollständigkeit halber nochmals auf einen Blick:

 

sudo mkfs.ext4 -F /dev/disk/by-id/scsi-0HC_Volume_XXXXXXX
sudo mkdir /export
sudo mount -o discard,defaults /dev/disk/by-id/scsi-0HC_Volume_XXXXXXX /export
sudo echo "/dev/disk/by-id/scsi-0HC_Volume_XXXXXXX /export ext4 discard,nofail,defaults 0 0" >> /etc/fstab

 

Falls man das Volume später in der Größe ändert, muss das im Linux-System natürlich auch bekannt gemacht werden: 

 

sudo resize2fs /export/

 

 

Schritt 2: S3-Storage bereitstellen

Leider gibt es bei Hetzner aktuell noch keine S3-kompatible Storage. Aber das ist kein Problem; wir nutzen das gerade angelegte Volume und lassen den Broker diese zur Verfügung stellen. Mit minio gibt es ein schlankes Docker-Image, das einen S3-kompatiblen Dienst zur Verfügung stellt. Auch der ist schnell gestartet: 

 

docker run -it -d --restart always -p 9005:9000 -v /.minio:/root/.minio -v /export:/export --name minio minio/minio:latest server /export

 

Und mit 

 

cat /export/.minio.sys/config/config.json | grep Key

 

erhalten wir die S3-Zugangsdaten. 

Schritt 3: Multi-Runner Cache einrichten

Damit haben wir alles zusammen, um unseren Runnern einen gemeinsamen Cache zur Verfügung zu stellen. In der config.toml richten wir diesen ein: 

 

[runners.cache]
    Type = "s3"
    Shared = true
    [runners.cache.s3]
      ServerAddress = "###IP_BROKER###:9005"
      AccessKey = "***************"
      SecretKey = "************************************"
      BucketName = "runner"
      Insecure = true
    [runners.cache.gcs]

 

und freuen uns, dass künftig der Cache persistiert wird und unsere Jobs deutlich schneller laufen. Das ist insbesondere bei den Build-Jobs (composer und npm) deutlich spürbar; hier kann man teilweise die Ausführungszeit um eine Größenordnung beschleunigen!

Docker auf Speed

Wir sind aber noch nicht am Ende der Optimierung angekommen. Unsere Gitlab-Runner laufen als docker+machine-Typ, d.h. jeder Job wird an einen Docker-Container übergeben, der auf dem Runner-Server gestartet wird. Welches Image verwendet wird, geben wir in der Job-Konfiguration in der .gitlab-ci.yml an. 

Naturgemäß ist das bei einem Frontend-Build-Job ein anderer als bei einem Quality-Gate-Job und das Deployment wird wieder auf einen anderen Container setzen. 

Und wir stellen fest: das Ziehen des Docker-Images ist nun einer der zeitaufwändigsten Teile eines jeden unseres Jobs. Auch hierfür brauchen wir eine Lösung.

Docker-Images cachen

Hierfür richten wir einen Proxy auf dem Broker ein, der sich für die Runner wie ein Docker-Repository verhält. Hat der Broker das gewünschte Image im Cache, wird es direkt ausgeliefert; andernfalls vom offiziellen Repo angefordert und weitergereicht - und natürlich in den Cache gelegt. 

Hört sich kompliziert an, ist es aber nicht: 

 

sudo docker run -d -p 6005:5000 -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io --restart always --name registry registry:2

 

macht den Job. ¯\_(ツ)_/¯ 

In der config.toml des Brokers machen wir dieses neue Repository für die Runner bekannt: 

 

[runners.machine]
    ...
    MachineOptions = ["hetzner-api-token=**************", "hetzner-image=ubuntu-18.04", "hetzner-server-type=cx21", "engine-registry-mirror=http://###IP_BROKER###:6005"]
    ...

 

und freuen uns über deutlich schnellere Pipelines.

Debugging

Wichtiger Hinweis: Am 10.12.2020 erschien ein Docker-Update, das Probleme mit den hier nachfolgend beschriebenen docker+machine-Gitlab-Runnern verursacht. Ich vermute, dass der Bug demnächst behoben sein wird, aber da die meisten von uns auf funktionierende Pipelines jetzt angewiesen sind, teile ich gerne meine Erkenntnisse vom gestrigen Arbeitstag:

Im Wesentlichen besteht das Problem darin, dass der Gitlab-Runner wie gewünscht eine neue Maschine startet, dort auf den Docker-Stack wartet und diesen nicht findet. Die Maschine wird dann verworfen (aber dummerweise auch nicht gelöscht, sondern läuft weiter) und eine neue gestartet, mit der dann das gleiche Passiert. Die Pipelines in Gitlab sind stuck und laufen einfach nicht los, weil eben keine Maschine vorhanden ist. Die letzte Nachricht in Gitlab war dann meist die Zeile

 

Preparing the "docker+machine" executor

 

 und dann passierte gar nichts mehr. 

Das ganze Setup konstruktiv zu debuggen, ist gar nicht so einfach - es kann einfach an vielen Stellen eine Kleinigkeit schief gehen. Auf die falsche Fährte lockte mich zudem ein von HETZNER gemeldetes Problem mit den Cloud-Servern, bei denen ein Netzwerkproblem gemeldet wurde. Wie sich herausgestellt hatte, war das aber -  wie so oft - nur zufällig zeitgleich und zumindest meine Runner waren von diesem Netzsegment auch nicht betroffen. 

Auf die richtige Spur hat mich schließlich gebracht, nicht nur in die Logs zu sehen (der Gitlab-Broker loggen nach /var/log/syslog), sondern den Gitlab-Broker herunterzufahren und im Non-Daemon-Mode zu starten: 

 

docker-compose down
docker-compose up

 

Dort stieß ich dann auf die Fehlermeldungen

 

WARNING: Failed to process runner builds=1 error=failed to update executor: no free machines that can process builds executor=docker+machine

 

und mit dieser dann auf den Hinweis, dass das neue Docker-Update diese Probleme verursacht, weil wohl ein Timing-Problem vorliegt und die Gitlab-Runner zumindest nicht lange genug auf den Dokcer-Stack warten. 

Ob da nun Docker oder Gitlab ein entsprechendes Update nachliefern werden, bleibt abzuwarten. Damit die Pipelines wieder laufen, kann die vorherige Docker-Version benutzt werden. Die Maschinen werden ja automatisch provisioniert, weshalb wir in der config.toml (s.o.) die entsprechende Konfiguration setzen müssen: 

 

    MachineOptions = ["hetzner-api-token=*****", ..., "engine-install-url=https://releases.rancher.com/install-docker/19.03.9.sh"]

 

Ich hoffe, das hilft dem Einen oder Anderen, der sich anhand dieser Anleitung ein ähnliches Setup aufgebaut hat.

Kommentare (16)

  • Theo Hilgers
    Theo Hilgers
    am 18.06.2020
    Danke für den Interessanten Artikel.

    Ich habe einen Fehler gefunden:
    docker-compose run hetzner_runner register müsste zu
    docker-compose run hetzner-runner register geändert werden.

    Mein Broker (Manager) legt bei Hetzner Server an. Jedoch bekomme ich in Gitlab immer diese Fehlermeldung. Eine Idee was falsch ist oder wo ich suchen kann?
    https://drive.google.com/uc?id=14riIELQad7wqHRSq9dv5L1R47fk3cyOh
    • Marc Willmann
      Marc Willmann
      am 18.06.2020
      Hallo Theo,

      vielen Dank für den Hinweis - ist korrigiert.

      Zu Deinem Fehler: Ist im Gitlab der Runner aktiv (/admin/runners -> letzter Kontakt)?
      Hast Du vielleicht eine Firewall, die die Verbindung von Gitlab zu den Runnern/dem Broker unterbindet?
      Stimmt die Version von Gitlab und den Runnern?
    • Theo Hilgers
      Theo Hilgers
      am 18.06.2020
      Hallo Marc,

      gerne :)

      Ich sehe den Manager im Gitlab unter /admin/runners dort wird mir die Version 13.0.1 angezeigt. Das hat auch mein Gitlab. Habe aber jetzt ein Update gemacht auf 13.0.6-ee. Problem besteht leider weiterhin.

      Bezüglich Firewall
      Der Broker ist einfach ein Server bei Hetzner. Dort habe ich nur docker und docker-compose installiert und den Broker Container von dir gestartet und Konfiguriert. Ich sehe wie bei Hetzner runners gestartet werden.

      Grüße
      Theo
  • René
    René
    am 15.09.2020
    Moin,

    danke für diesen Artikel, ich hab mir vorgenommen, dass die Tage mal auszuprobieren.
    Ich hab zu den Cache Servern eine Frage: So wie es in dem Artikel steht, sind die jeweils unter der öffentlichen IP des Broker Servers erreichbar, oder? Das sehe ich bei dem S3 Server aufgrund der Authentifizierung nicht als problematisch an, anders aber bei dem Docker Cache Server.
    Der scheint ohne Authentifizierung öffentlich erreichbar, das würde ein Einfallstor für DoS Attacken liefern, wenn mir zum Beispiel jemand den Cache mit Docker Images vollmüllt.

    Eine Lösung wäre, nur ein privates Netz, welches man ja bei Hetzner erstellen kann, zu nutzen. Dafür müsste man die Worker Server jedoch auch automatisch in dieses Netz bewegen. Gibt es dazu eine Konfigurationsmöglichkeit in der genutzten Software? Ich konnte auf die Schnelle nichts finden, aber vielleicht hast Du Dir da auch schon Gedanken drüber gemacht.

    Viele Grüße
    René
    • Marc Willmann
      Marc Willmann
      am 29.09.2020
      Hallo René,

      Du kannst in den machine-options über die Cloud-API die Netzwerknamen angeben, die dem Server zugeordnet werden sollen (https://docs.hetzner.cloud/#servers-create-a-server). Wenn Du also ein privates Netz beim Broker erstellst und in der config.toml dieses beim Erstellen der Runner mitgibst, sollte das klappen. Ich probier das in den nächsten Tagen mal aus.

      Vielen Dank für den Hinweis

      Marc
    • Marc Willmann
      Marc Willmann
      am 11.12.2020
      Hallo René,

      ich schulde Dir noch eine Antwort auf den sicheren Umgang mit einem eigenen Registry-Server. Unter https://docs.docker.com/registry/deploying/ ist gut beschrieben, wie man eine eigene Registry aufsetzt und auch, wie man diese absichern kann. Ich hoffe, das hilft :)

      Marc
  • Jochen Schultz
    Jochen Schultz
    am 12.12.2020
    Danke für das Update!

    Ich habe auch noch eines: OffPeakPeriods sind offenbar deprecated:

    [runners.machine]
    MachineName = "runner-%s"
    MachineDriver = "hetzner"
    MachineOptions = [
    "hetzner-api-token=xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "hetzner-image=ubuntu-20.04",
    "hetzner-server-type=cx21",
    "engine-registry-mirror=http://xxx.xxx.xxx.xxx:6005"
    ]
    IdleCount = 1
    IdleTime = 30
    [[runners.machine.autoscaling]]
    Periods = ["* * 9-17 * * mon-fri *"]
    IdleCount = 1
    IdleTime = 30
    Timezone = "UTC"
    [[runners.machine.autoscaling]]
    Periods = ["* * * * * sat,sun *"]
    IdleCount = 1
    IdleTime = 30
    Timezone = "UTC"

    Wollte das eigentlich testen und das Dockerupgrade kam wohl zeitgleich. Logisch wohin einen das dann erstmal treibt!
    • Marc Willmann
      Marc Willmann
      am 12.12.2020
      Ja, bin ich auch drüber gestolpert - das wollte ich nach einem superlangen Arbeitstag dann aber nicht auch sofort anpassen. Danke für Deinen Input, ich werd die Anleitung dazu in Kürze anpassen... ??
  • Patrick
    Patrick
    am 15.05.2021
    Top-Anleitung! Vielen Dank!

    Lassen sich die Machine Options irgendwie (leicht) parametrisieren? Für die meisten Jobs reicht uns ein cx21 - der eine oder andere ist jedoch etwas aufwendiger und braucht bisschen mehr RAM.

    Derzeit fällt mir nur die Möglichkeit ein, den Builder-Container zu duplizieren und 2 Runner zu konfigurieren.

    Grüße
    Patrick
  • Barry
    Barry
    am 02.03.2023
    Hi Marc, vielen Dank für die Anleitung.
    Bei mir klappt leider noch was nicht, wollte dich fragen ob du in letzter Zeit mal selber Gitlab Runner aufsetzen musstest bei Hetzner?
    Ich sehe den Runner, aber immer mit dem Hinweis, dass kein Kontakt stattgefunden hat bislang.
    • Marc Willmann
      Marc Willmann
      am 02.03.2023
      Hast Du den Hinweis mit der Docker-Version gesehen? Ich hab das aktuell im Einsatz ohne größere Probleme. Schau mal, ob die internen Docker-Zertifikate ggf. abgelaufen sind (sollte aus der Fehlermeldung im Docker-Log hervorgehen)
  • Kay Strobach
    Kay Strobach
    am 26.06.2023
    Hast du die Meldung hier gesehen:

    https://docs.hetzner.cloud/#deprecation-notices-%E2%9A%A0%EF%B8%8F

    Ich habe derzeit immer mal Server, die dann idlen und nicht mehr vom Runner coordinator erreichbar sind, hast du sowas auch schon festgestellt?

    ERROR: could not get server handle: server ID was 0 name=runner-pmhd8x2i-g.com-1687810179-216211cf operation=stop

    Das führt dann zum Treffen des Resource limits und damit zu einem Stop der Runner 😅
    • Marc
      Marc
      am 26.06.2023
      Guter Hinweis, danke. Ich muss mal schauen, inwiefern diese Deprecation uns betrifft. Vermutlich muss der neue API-Client verwendet werden...

      Den beschriebenen Fehler habe ich so noch nicht beobachtet; wir hatten ab und an mal das Problem, dass die Docker-Zertifikate nicht mehr akzeptiert werden. Mit einem Neustart des Brokers läuft das dann aber wieder problemlos.
    • Kay Strobach
      Kay Strobach
      am 26.06.2023
      Mal schauen, ggf. macht es Sinn das Original Repo mal zu forken und zusammen drauf zu arbeiten - was meinst du? Das Originalprojekt scheint ja tot zu sein 😔
  • Max
    Max
    am 11.05.2024
    Hi Marc,

    vielen Dank für dein tolles Tutorial hier. Das hat für uns sehr einfach und schnell funktioniert.
    Nach etwas rumsuchen und GPT fragen konnte ich aber eine Frage noch nicht klären:
    Kann ich das setup oben so einstellen, dass auf einem "physischen" hetzner server mehrere docker+machine VMs gestartet werden, statt das für jeden neuen Job ein neuer server aufgesetzt wird?

    Oder lieber einfach die hetzner server configuration klein genug wählen, dass es kostenmäßig keinen Unterschied macht?

    Danke dir schon jetzt für deine Antwort!

    Liebe Grüße,
    • Guido
      Guido
      vor 6 Tagen
      Da ich mich das auch gefragt habe - die Antwort ist hier versteckt:

      https://docs.gitlab.com/runner/configuration/autoscale.html

      "Docker Machine autoscaler creates one container per VM, regardless of the limit and concurrent configuration."

      Danke Marc für die Anleitung! Mit ein paar Feintunings läuft das Runner-Autoscaling bei uns jetzt top.

Neue Antwort auf Kommentar schreiben