And again: Das Löschen von Images in der Docker-Registry

DockerDas Löschen von Images in einer Docker-Registry, ist ein Thema, das bereits sehr viel Zeit in Anspruch genommen hat. In einem früheren Blogpost wurde eine Variante vorgestellt, die mit einem separaten Script arbeitete. Da diese mit neueren Docker-Versionen jedoch nicht mehr funktioniert, wurde nach einer Alternative gesucht. Dabei haben wir erneut die von Docker mitgelieferte Möglichkeit getestet, die zu unserer Überraschung nun endlich richtig implementiert wurde.

Dieses Vorgehen sieht so aus, dass ein Image über die API gelöscht wird, wodurch die Abhängigkeiten der einzelnen Layer aufgelöst werden. Um dieser Layer Herr zu werden, ist es nötig einen Garbage-Collector zu starten, der diese Layer erfasst und entfernt. Der API-Call sieht zunächst wie folgt aus:

curl -k -X DELETE https://localhost:5000/v2/$IMAGENAME$/manifests/sha256:$BLOBSUM$

Die hierfür benötigte Blobsum kann einem Push/Pull des betroffenen Images entnommen werden. Tags wie “latest” werden in diesem Aufruf nicht akzeptiert. Der Garbage-Collector sollte in einem separaten Docker-Container laufen nachdem die Registry selbst gestoppt wurde. Wir haben diesen Vorgang mit einem Script umgesetzt. So ist es möglich, tagsüber Images manuell zu entfernen, sodass diese zu einer bestimmten Uhrzeit von einem Cronjob entfernt werden können.

echo "###################################################" >> /var/log/docker-registry-cleanup.log
/usr/local/sbin/icingaweb2-downtime.rb -s -H docker-registry.netways.de -S 'docker registry' -t 15 -c Cleanup && echo "$(date) [OKAY] Downtime was set." >> /var/log/docker-registry-cleanup.log
/etc/init.d/docker-registry stop && echo " $(date) [STOP] Stopping Docker-Registry ..." >> /var/log/docker-registry-cleanup.log
touch /var/log/docker-registry-cleanup.log
sleep 30
pgrep -f "/etc/docker/registry/config.yml"
echo $i
if [ "$i" = "0" ]
then
echo "$(date) [FAIL] Docker-Registry is still running. Aborting Cleanup" >> /var/log/docker-registry-cleanup.log
else
echo "$(date) [OKAY] Docker-Registry is not running. Starting Cleanup" >> /var/log/docker-registry-cleanup.log
docker run --rm -v /storage:/var/lib/registry -v /etc/docker/config.yml:/etc/docker/registry/config.yml registry:2 garbage-collect /etc/docker/registry/config.yml
/etc/init.d/docker-registry start && echo "$(date) [START] Starting the Docker-Registry ..."
pgrep -f "/etc/docker/registry/config.yml"
i=$?
if [ $i=0 ]
then
echo "$(date) [OKAY] Docker-Registry is running after cleanup" >> /var/log/docker-registry-cleanup.log
else
echo "$(date) [FAIL] Docker-Registry is not running after cleanup" >> /var/log/docker-registry-cleanup.log
fi
fi

Dieses Script setzt ebenso eine Downtime von 15 Minuten für den Container der Registry im Icinga2 und schreibt seinen Output in ein Log.
###################################################
Fri May 27 02:00:03 CEST 2016 [OKAY] Downtime was set.
Fri May 27 02:00:07 CEST 2016 [STOP] Stopping Docker-Registry ...
Fri May 27 02:00:37 CEST 2016 [OKAY] Docker-Registry is not running. Starting Cleanup
Fri May 27 02:01:10 CEST 2016 [OKAY] Docker-Registry is running after cleanup
###################################################
Sat May 28 02:00:03 CEST 2016 [OKAY] Downtime was set.
Sat May 28 02:00:07 CEST 2016 [STOP] Stopping Docker-Registry ...
Sat May 28 02:00:37 CEST 2016 [OKAY] Docker-Registry is not running. Starting Cleanup
Sat May 28 02:01:13 CEST 2016 [OKAY] Docker-Registry is running after cleanup
###################################################
Sun May 29 02:00:03 CEST 2016 [OKAY] Downtime was set.
Sun May 29 02:00:06 CEST 2016 [STOP] Stopping Docker-Registry ...
Sun May 29 02:00:36 CEST 2016 [OKAY] Docker-Registry is not running. Starting Cleanup
Sun May 29 02:01:13 CEST 2016 [OKAY] Docker-Registry is running after cleanup
###################################################
Mon May 30 02:00:02 CEST 2016 [OKAY] Downtime was set.
Mon May 30 02:00:03 CEST 2016 [STOP] Stopping Docker-Registry ...
Mon May 30 02:00:33 CEST 2016 [OKAY] Docker-Registry is not running. Starting Cleanup
Mon May 30 02:00:41 CEST 2016 [OKAY] Docker-Registry is running after cleanup

Dieses Verfahren testen wir nun seit ein paar Wochen und sind mit dem Ergebnis sehr zufrieden.

Brauchen Sie Unterstützung für Ihr Docker Projekt? Dann empfehlen wir unser Docker-Hosting Angebot.

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Get ready with NETWAYS

This entry is part 1 of 11 in the series Azubis erzählen

nerd_of_awesome_by_movillefacepalmplz-d5qvmzxGet ready with NETWAYS! Das trifft für mich auf die letzten 3 Jahre zu, in denen ich meine Ausbildung hier bei NETWAYS absolvieren durfte. An meinem ersten Tag, hatte ich keine Ahnung von Linux, Servern geschweige denn von OpenSource. Aber das hat hier niemanden abgeschreckt und mir wurde über die Zeit alles nötige beigebracht um selbstständig arbeiten und lernen zu können. Verschiedene Linux Distributionen, Hardware und Verkabelungen im Rechenzentrum, Pflege der HQ-Infrastruktur, Kundensupport und auch die Entwicklung einiger Automatisierungsskripte waren unter anderem Teil meiner Ausbildung hier. Ich empfand es als großen Vorteil, Teil einer verhältnismäßigen jungen und aufstrebenden Firma zu sein, allein schon deswegen, weil man jeden einzelnen Kollegen beim Namen kennt. Aber auch deswegen, weil eine Firma wie diese, viele neue Produkte testet und versucht sie in den produktiven Einsatz zu überführen. Manchmal erfolgreich, manchmal eher weniger. So bekommt man sehr viel von der “neuen Technik” mit und sieht in manchen Situationen auch wie es nicht geht.

Besonders überrascht war und bin ich teilweise immernoch, über den Umgang miteinander. Es herrscht ein eher freundschaftliches Verhältnis, sodass man auch in der Freizeit oder nach Feierabend mal zusammen einen trinkt, die ein oder andere Feier miterlebt oder eine LAN-Party veranstaltet. Auch Konferenzen und Schulungen in Nürnberg, Berlin, Köln, Düsseldorf, Barcelona oder den USA waren bisher immer ein sehr angenehmes Erlebnis. Soweit also eine Firma, in der man jeden Tag aufs neue gern arbeitet.

Zu jeder Ausbildung gehört am Ende auch eine Abschlussarbeit in Form eines Projektes und dessen Dokumentation. Mein Projekt befasst sich damit, eine Docker-Registry aufzusetzen. In diesem Projekt war sehr viel gefordert. Ich musste mich in kurzer Zeit in ein neues Thema einarbeiten, eine virtuelle Maschine mit entsprechenden Anforderungen aufsetzen, Fehler korrigieren, so viel automatisieren wie möglich und alles anschließend dokumentieren. Als letztes gilt es dieses Projekt im Sommer einem Prüfungsausschuss zu präsentieren und sich deren Fragen zu stellen.

Nach erfolgreichem Abschluss meiner Ausbildung werde ich im Support arbeiten und versuchen unseren Kunden bestmöglich zu helfen. Ich freue mich auf die Arbeit und auch darauf weiterhin zu lernen und Erfahrungen zu machen.

Trotz alledem lernt man nie aus und es ist auch unmöglich alles beigebracht zu bekommen. Aber bei NETWAYS bekommt man eine sehr gute Vorbereitung auf den Alltag in der IT Branche nach der Ausbildung. Für den Fall, dass jemand auf der Suche nach einer geeigneten Firma ist, dann ist er bei uns an der richtigen Stelle!

 

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Blacklists prüfen mit check_rbl

The_Blacklist_logo.svgBlacklists sind prinzipiell nichts schlechtes. Sie helfen zu verhindern, dass ein Unternehmen oder eine Privatperson mit Spam oder ähnlichem Übel gestört werden oder vielleicht sogar Schaden davon tragen.
Gelegentlich kommt es jedoch vor, dass ein Unternehmen oder eine Privatperson auf einer Blacklist landen, obwohl sie keine negativen Absichten verfolgen. Ein Grund hierfür kann zum Beispiel das Versenden von Newslettern sein, wodurch ein erhöhtes Mailaufkommen von bestimmten Systemen verzeichnet wird und Mails als “Spam” markiert werde. Als Folge dessen wird für die versendenden Server ein Eintrag auf einer Blacklist angelegt. Der Nachteil für den Betroffenen ist, dass er keine Benachrichtigung bekommt, mit dem Hinweis, auf einer Blacklist markiert worden zu sein.

Wir bei NETWAYS wollen aber kontrollieren, ob unsere Server oder die von unseren Kunden bei gewissen Systemen einen Eintrag besitzen und können dies auch überprüfen. Eine sehr elegante Möglichkeit wird hierfür mit dem check_rbl gegeben. Dieser Check durchforstet gegebene Blacklists von Servern nach einem gefragten Server.
Ein kleines Beispiel wird die Funktionsweise aufzeigen:

check_rbl -t 60 -H netways.de \
-s cbl.abuseat.org \
-s dnsbl.cyberlogic.net \
-s bl.deadbeef.com \

So würde der Check überprüfen, ob Einträge für den Host “netways.de” auf den Servern, die mit dem “-s” Parametern übergeben wurden, vohanden sind und ein “warning” beziehungsweise “critical” auslösen. Eine weitere gute Erläuterung der Funktionsweise dieses Checks findet man auf GitHub oder auf dem Icinga-exchange.

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Docker-Registry und das Geheimnis des Löschens

DockerLogo

Wenn man sich dazu entschließt, eine Docker-Registry zu installieren und zu konfigurieren, möchte man Images zentral abspeichern und verwalten können. Dies bietet viele Vorteile für den abteilungsübergreifenden Einsatz von Docker, aber auch ein paar Komplikationen im Umgang mit der Registry.
Wenn man mit dieser Registry arbeitet, entsteht irgendwann folgendes Problem. Das Löschen von Images funktioniert nicht wirklich.

Der Server ist fertig konfiguriert und man übermittelt Images an die Registry.
Der Speicherplatz wird zunehmend belegt, es liegen veraltete Images im Storage, die nicht mehr benötigt werden. Laut der Dokumentation von Docker, soll dieses Problem dadurch gelöst werden, dass man über die API Images “ganz einfach” löschen kann:

curl -k -X DELETE https://localhost:5000/v2/$imagename$/manifests/latest

Jedoch werden sich viele dann über diese (oder ähnliche) Fehlermeldung(en) ärgern:

{"errors":[{"code":"INVALID_DIGEST","message":"The digest is invalid"}]}

Laut Dokumentation, kann ein Image über die API nur dann gelöscht werden, wenn es durch den Namen und die Referenz(Tag, zum Beispiel “latest”) identifiziert werden kann, jedoch nur mittels “Digest”.
Ein Digest ist ein Wert um ein Image eindeutig identifizieren zu können. Er wird beim zum Beispiel bei einem Pull oder Push angezeigt. (Achtung! Der Digest ist nicht die Image ID, die beispielsweise bei einem “docker images” Command angezeigt wird.)

docker pull ubuntu
(...)
93f3596230c2: Pull complete
c06698a70f80: Pull complete
b6ea91fdc1f6: Pull complete
a53404c22cd2: Pull complete
Digest: sha256:c9f94277901034f3f40e73c861aee970da33dce9af2c02f13e1a4a72cdc0f8cb

Das Problem ist nun, dass der oben genannte DELETE nicht funktioniert. Eine kritische Alternative hierfür ist, auf der Commandline das Verzeichnis zu löschen

rm -rf ubuntu

Das Problem hierbei wären die Blobs, die als “Leiche” zurück bleiben würden. Wieso dies kritisch ist, möchte ich kurz versuchen zu erklären:
Jedes Image, besteht aus mehreren Layern, wobei die Layer aufeinander aufbauen. Der oberste Layer bekommt einen Tag (zum Beispiel “latest”). Blobs sind “BlobSums” (Digest) für die einzelnen Layer. Die einzelnen Layer sind wie der Digest des kompletten Images bei einem Pull, Push oder einem Api Request ersichtlich.

"schemaVersion": 1,
"name": "ubuntu",
"tag": "latest",
"architecture": "amd64",
"fsLayers": [
{
"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
},
{
"blobSum": "sha256:a53404c22cd2ac9f68c352d17667ec1a2e36f22ca729983c40e1f24c106def6f"
},
{
"blobSum": "sha256:b6ea91fdc1f68eb0274174fd8c4eeea4baeee4986c942cbc7a21be82778e78b3"
},
{
(etc)

Beim Push in die Registry wird im Verzeichnis “blob” ein Eintrag für jeden Layer angelegt, mit der jeweiligen BlobSum. Löscht man nun ein “Image” aus der Registry, werden nur die Daten des Images gelöscht die im Verzeichnis “v2/repositories/$IMAGENAME” liegen. Auf den ersten Blick ist das Image gelöscht, denn in der Registry wird es nicht mehr als verfügbares Images zum Pull angezeigt. Die restlichen Layer jedoch und somit auch die Blobs, bleiben bestehen, womit sehr viel Speicherplatz mit nicht nutzbaren Daten belegt wird. Auch andere, von Docker erstellte Abhängigkeiten werden so nicht gelöscht. Das Problem ist dann, dass das Pushen des selben Images zurück in die Registry fehlerhaft sein wird, da versucht wird, Layer zu pushen, die schon hinterlegt sind und zu einem Image gehören aber nicht mehr zuordbar sind.

Komplizierter würde es werden, wenn man zum Beispiel nicht nur ein Image löschen möchte, sondern beispielsweise alle “untagged Images”. Dies sind veraltete Images, ohne einen Tag. Dies geschieht beispielsweise bei einem Push eines Images mit dem gleichem Namen.

Will oder kann man die Images nicht über die API löschen bietet “Burnettk” auf GitHub mit einem kleinen Skript eine gute Alternative.
Es handelt sich hier um ein Script, das ein Image anhand des Names identifiziert, und alles dazugehörige löscht. Was hierfür nötig ist, ist eine Environment Variable, die auf das Reporitory gesetzt wird. Als Beispiel:

export REGISTRY_DATA_DIR=/opt/registry_data/docker/registry/v2

Dannach kann das Script als normales Command genutzt werden. Um alle untagged Images zu löschen, kann man mit einer kleinen Schleife arbeiten, die innerhalb des Repoitory Verzeichnisses läuft:

for i in *; do delete_docker_registry_image --untagged --image $i; done;

Wenn man in diesem Verzeichnis, Images in einem weiteren Unterverzeichnis abspeichert, muss das Script kopiert und angepasst werden:

repositories_dir="repositories/$UNTERVERZEICHNIS"

An dieser Stelle bietet es sich auch an, diesen Löschvorgang in Form eines Crons zu automatisieren. Das Problem, dass die Registry zu wenig Speicherplatz frei hat, wäre so gelöst. Vielleicht kommt von Docker in den nächsten Docker-Engine Versionen eine brauchbare Lösung mit, jedoch ist das für mich die bisher beste Lösung.
dockerDocker, Docker, Docker!

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Teamevent von Managed Services

Seit diesem Jahr fährt jede Abteilung von NETWAYS in ein gemeinsames Wochenende um Teambildende Maßnahmen zu ergreifen und die Bindungen unter den Mitarbeitern zu fördern.

Vergangenes Wochenende war es bei den Kollegen von Managed Services soweit. Dieser Post wird von den 3 Azubis Ufuk, Kay und mir persönlich verfasst.

Der Start war Freitag früh um 07:30 Uhr in Nürnberg bei NETWAYS. Gemeinsam mit den neuen Azubis Ufuk, Kay und Benny, ging es in 3 Fahrzeugen nach Bad Tölz in das Tagungshotel Kolberbräu, wo wir gegen 10:00 Uhr auch ankamen. Nach einem Begrüßungskaffee starteten wir in das 8 stündige “Meeting” in dem vieles besprochen wurde. Darunter auch Veränderungen im Team und dessen Struktur, aber auch Vorschläge und Kritik in den bestehenden Teams. Für das leibliche Wohl während der Tagung war durch Snacks, ein Mittagessen und durch ein 2-Gänge Menü am Abend gesorgt. Nach Ende der offiziellen Tagung wurden die Zimmer bezogen, welche sehr großzügig bemessen waren.

Der Freitag Abend wurde dann durch einen gemeinsamen Besuch in der Bowling Bahn abgerundet, wobei die Stimmung nach ersten Ermüdungserscheinungen immer besser wurde. Klassiker wie “Schatzi schenk mir ein Foto” oder “Atemlos” blieben jedoch leider aus.

Im Anschluss ging es für einige wenige weiter zu einem “Absacker”, sprich einem gemeinsamen Drink, wonach der erste Abend beendet wurde.

Der Samstag ging nach einer kurzen Nacht relativ früh los. Nach einem wohltuenden und reichlich gedeckten Frühstück brachen wir Richtung Lenggries zum Raften auf, wo wir uns mit unserem Tourguide von Montevia trafen.
Nach dem Einkleiden mit Neopren und Sicherheitsausrüstung ging es los mit dem Schleppen der Boote zum Ufer.
Nach weiteren Sicherheitsinstruktionen war der erste Kontakt mit dem Wasser sehr, sehr kalt (10°C !!).

Das hielt uns jedoch nicht davon ab, fleißig zu rudern und die wenigen Stromschnellen zu durchfahren. Die schwierigste war an der sogenannten Isar-Burg (Stufe  3 von 5). Der Rest der Tour war geprägt durch Sprünge in das kalte Gewässer, bei dem man auch die Gelegenheit bekam, sich treiben zu lassen und die Strömung bis zum Ausstieg zu genießen. 2,5 Stunden und 11 km später, war die Tour jedoch vorbei und wir wurden mit dem Transfer zurück in die Basis nach Lenggries gebracht. Der ein oder andere Kollege hatte so seine Probleme aus dem Neoprenanzug raus zu kommen, was für lustige Anblicke sorgte.

Beendet wurde der Tag mit einem herrlichen und großzügigen  BBQ, bei dem keine Wünsche offen gelassen wurden und man Energie für die Rückfahrt sammeln konnte. Um ca 15:00 Uhr ging es dann auch wieder Richtung Nürnberg los. Alles in Allem war das Wochenende eine wertvolle Erfahrung für unser Team und wir sind gespannt, welches Event nächstes Jahr auf uns wartet!

 

 

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz