{"id":6151,"date":"2019-06-26T20:02:27","date_gmt":"2019-06-26T18:02:27","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=6151"},"modified":"2019-06-26T20:50:11","modified_gmt":"2019-06-26T18:50:11","slug":"eigene-docker-registry-fuer-images-installieren","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/eigene-docker-registry-fuer-images-installieren\/","title":{"rendered":"Eigene Docker-Registry f\u00fcr Images installieren"},"content":{"rendered":"<p>Docker bietet offizielle Images,  um eine eigene Registry zu hosten. Dadurch ist man nicht vom externen  Docker-Hub abh\u00e4ngig. Dies kann auch f\u00fcr sicherheitskritische Images eine  Option sein, die man nicht extern hosten m\u00f6chte. Aber auch ein interner  Kubernetes-Cluster ist ein Beispiel-Szenario, in dem Docker-Images  gebaut und auf einer Registry abgelegt werden k\u00f6nnen. Durch die Nutzung  einer internen Registry muss keine Internetverbindung seitens der Cluster-Server hergestellt werden.  <\/p>\n<h2 class=\"wp-block-heading\">Docker-Registry installieren<\/h2>\n<p>Das Deployment einer eigenen Registry ist recht einfach. Eine Out-of-the-Box Installation kann mit einem einzigen docker run Befehl innerhalb weniger Sekunden gestartet werden: <\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\ndocker run -d -p 5000:5000 --restart always --name registry registry:2\n<\/pre>\n<\/div>\n<p>Die Registry ist nun auf dem Hostsystem \u00fcber Port 5000 erreichbar. Mit curl k\u00f6nnen wir eine Testabfrage senden und sehen &#8211; wie erwartet &#8211; noch keine Repositorys, erhalten aber eine JSON-Antwort:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ curl http:\/\/localhost:5000\/v2\/_catalog\n{&quot;repositories&quot;:&#x5B;]}\n<\/pre>\n<\/div>\n<h2 class=\"wp-block-heading\">Docker-Registry installieren<\/h2>\n<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\ndocker run -d -p 5000:5000 --restart always --name registry registry:2\n<\/pre>\n<\/div>\n<p>Die Registry ist nun auf dem Hostsystem \u00fcber Port 5000 erreichbar. Mit curl k\u00f6nnen wir eine Testabfrage senden und sehen &#8211; wie erwartet &#8211; noch keine Repositorys, erhalten aber eine JSON-Antwort:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n$ curl http:\/\/localhost:5000\/v2\/_catalog\n{&quot;repositories&quot;:&#x5B;]}\n<\/pre>\n<\/div>\n<p>In den Standardeinstellungen wird keine Authentifizierung gesetzt. Somit kann jeder Images pullen und pushen. W\u00e4hrend dies f\u00fcr Testzwecke ausreicht, sollte man eine produktive Installation mittels Passwort sch\u00fctzen. Abgesehen davon l\u00e4uft auf der Maschine nun eine Registry, in die man beliebig Pushen kann. <\/p>\n<h2 class=\"wp-block-heading\">Erweiterte Registry-Konfiguration via YAML<\/h2>\n<p>Die Docker-Registry bietet eine ganze Reihe von Einstellungsm\u00f6glichkeiten. Beispielsweise kann der Speicherort und Typ f\u00fcr Images angepasst, ein Zugangsschutz eingerichtet und Redis als Cache-Speicher eingesetzt werden. F\u00fcr diese Optionen kommt das YAML-Format zum Einsatz. <a href=\"https:\/\/docs.docker.com\/registry\/configuration\/\" target=\"_blank\" rel=\"nofollow\">Docker selbst bietet eine ausf\u00fchrliche Dokumentation<\/a> mit Erl\u00e4uterungen und Beispielen hierzu an. Das minimalistische Beispiel ist eine gute Grundlage. Hier ist auch bereits die Authentifizierung mit eingebaut:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nversion: 0.1\nlog:\n  fields:\n    service: registry\nstorage:\n  cache:\n    blobdescriptor: inmemory\n  filesystem:\n    rootdirectory: \/var\/lib\/registry\nhttp:\n  addr: :5000\n  headers:\n    X-Content-Type-Options: &#x5B;nosniff]\nauth:\n  htpasswd:\n    realm: basic-realm\n    path: \/etc\/registry\nhealth:\n  storagedriver:\n    enabled: true\n    interval: 10s\nthreshold: 3\n<\/pre>\n<\/div>\n<h3 class=\"wp-block-heading\">BASIC Authentifizierung aktivieren<\/h3>\n<p>Die .htpasswd Datei m\u00fcssen wir noch generieren. Das htpasswd CLI-Tool ist im Debian-Paket apache2-utils enthalten. Wer es nicht auf dem Hostsystem installiert hat, kann auch einfach das bereits installierte im Container nutzen:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndocker exec -it registry htpasswd -B -b -c \/etc\/registry test test\n<\/pre>\n<\/div>\n<p>Generiert den Nutzer test mit dem Passwort test. Zu beachten ist, dass das Passwort hier ggf. f\u00fcr andere User auf dem System in der Prozess\u00fcbersicht sichtbar ist. Sofern h\u00e4ndisch generiert wird, sollte man daher den 2. Parameter des Passwortes zusammen mit dem -b Schalter weglassen. Dann wird das Passwort abgefragt. Wichtig ist jedoch der Schalter -B, der BCrypt aktiviert &#8211; dies ist derzeit die einzige von Docker unterst\u00fctzte methode. <\/p>\n<p>Nun haben wir die htpasswd-Datei zwar im Container. Da dieser allerdings fl\u00fcchtig ist, existiert diese nach dem n\u00e4chsten Neustart nicht mehr. Daher exportieren wir die erzeugte Datei auf den Host: <\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndocker exec -it registry cat \/etc\/registry &gt;&gt; registry-htpasswd\n<\/pre>\n<\/div>\n<p>Damit die Konfiguration greift, ist ein Neustart des Containers erforderlich. <\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndocker rm -vf registry\ndocker run -d -p 5000:5000 --restart always --name registry \\\n    -v $(pwd)\/registry-htpasswd:\/etc\/registry \\\n    -v $(pwd)\/config.yml:\/etc\/docker\/registry\/config.yml \\\n    registry:2\n<\/pre>\n<\/div>\n<h3 class=\"wp-block-heading\">Authentifizierung testen<\/h3>\n<p>Wird die Registry nach dem Neustart per curl aufgerufen, erhalten wir im Erfolgsfall eine Fehlermeldung. Klingt Paradox, aber da wir die Authentifizierung eingeschaltet haben, darf uns die Registry nicht mehr ohne Login antworten:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n$ curl http:\/\/localhost:5000\/v2\/_catalog\n{&quot;errors&quot;:&#x5B;{&quot;code&quot;:&quot;UNAUTHORIZED&quot;,&quot;message&quot;:&quot;authentication required&quot;,&quot;detail&quot;:&#x5B;{&quot;Type&quot;:&quot;registry&quot;,&quot;Class&quot;:&quot;&quot;,&quot;Name&quot;:&quot;catalog&quot;,&quot;Action&quot;:&quot;*&quot;}]}]}\n<\/pre>\n<\/div>\n<p>Mit den Zugangsdaten test:test sollten wir in diesem Beispiel Zugriff erhalten, d.H. die leere Repository-Liste: <\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n$ curl http:\/\/localhost:5000\/v2\/_catalog --user test:test\n{&quot;repositories&quot;:&#x5B;]}\n<\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Docker bietet offizielle Images, um eine eigene Registry zu hosten. Dadurch ist man nicht vom externen Docker-Hub abh\u00e4ngig. Dies kann auch f\u00fcr sicherheitskritische Images eine Option sein, die man nicht extern hosten m\u00f6chte. Aber auch ein interner Kubernetes-Cluster ist ein Beispiel-Szenario, in dem Docker-Images gebaut und auf einer Registry abgelegt werden k\u00f6nnen. Durch die Nutzung &#8230;<\/p>\n","protected":false},"author":5,"featured_media":6156,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[74,5,78],"tags":[497],"class_list":["post-6151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-news","category-software","tag-docker"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=6151"}],"version-history":[{"count":4,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6151\/revisions"}],"predecessor-version":[{"id":6155,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/6151\/revisions\/6155"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/6156"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=6151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=6151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=6151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}