Einrichten einer privaten Docker-Registrierung unter Ubuntu 18.04

Der Autor hat die Apache Software Foundation ausgewählt, um eine Spende als Teil der Write for DOnations zu erhalten. Programm.

Einführung

Docker Registry ist eine Anwendung, die das Speichern und Bereitstellen von Docker-Container-Images verwaltet. Registries zentralisieren Container-Images und verkürzen die Erstellungszeiten für Entwickler. Docker-Images garantieren durch Virtualisierung die gleiche Laufzeitumgebung, aber das Erstellen eines Images kann einen erheblichen Zeitaufwand bedeuten. Anstatt zum Verwenden von Docker Abhängigkeiten und Pakete separat zu installieren, können Entwickler ein komprimiertes Image aus einer Registrierung herunterladen, die alle erforderlichen Komponenten enthält. Darüber hinaus können Entwickler mithilfe fortlaufender Integrationstools wie TravisCI das Pushen von Bildern in eine Registrierung automatisieren, um die Bilder während der Produktion und Entwicklung nahtlos zu aktualisieren.

Docker hat auch eine kostenlose öffentliche Registrierung, Docker Hub, die Ihre benutzerdefinierten Docker-Images hosten kann, aber es gibt Situationen, in denen Sie nicht möchten, dass Ihr Image öffentlich verfügbar ist. Bilder enthalten in der Regel den gesamten Code, der zum Ausführen einer Anwendung erforderlich ist. Daher ist die Verwendung einer privaten Registrierung bei Verwendung proprietärer Software vorzuziehen.

In diesem Tutorial richten Sie Ihre eigene private Docker-Registry ein und sichern diese. Mit Docker Compose definieren Sie Konfigurationen zum Ausführen Ihrer Docker-Anwendungen und Nginx zum Weiterleiten des Serververkehrs von HTTPS an den ausgeführten Docker-Container. Sobald Sie dieses Lernprogramm abgeschlossen haben, können Sie ein benutzerdefiniertes Docker-Image in Ihre private Registrierung verschieben und das Image sicher von einem Remote-Server herunterladen.

Voraussetzungen

Bevor Sie mit diesem Handbuch beginnen, benötigen Sie Folgendes:

Schritt 1 - Installieren und Konfigurieren der Docker-Registrierung

Das Docker-Befehlszeilentool ist nützlich, um einen oder zwei Docker-Container zu starten und zu verwalten. Für die vollständige Bereitstellung müssen jedoch für die meisten Anwendungen, die in Docker-Containern ausgeführt werden, andere Komponenten parallel ausgeführt werden. Viele Webanwendungen bestehen beispielsweise aus einem Webserver wie Nginx, der den Code der Anwendung bereitstellt, einer interpretierten Skriptsprache wie PHP und einem Datenbankserver wie MySQL.

Mit Docker Compose können Sie eine "+ .yml " - Datei schreiben, um die Konfiguration jedes Containers und die Informationen einzurichten, die die Container zur Kommunikation miteinander benötigen. Sie können dann das Befehlszeilentool ` docker-compose +` verwenden, um Befehle an alle Komponenten auszugeben, aus denen Ihre Anwendung besteht.

Da Docker Registry selbst eine Anwendung mit mehreren Komponenten ist, können Sie Ihre Konfiguration mit Docker Compose verwalten. Um eine Instanz der Registrierung zu starten, richten Sie eine "+ docker-compose.yml +" - Datei ein, um den Speicherort für die Registrierungsdaten festzulegen.

Auf dem Server, den Sie zum Hosten Ihrer privaten Docker-Registry erstellt haben, können Sie ein Docker-Registry-Verzeichnis erstellen, in dieses Verzeichnis verschieben und dann einen Data-Unterordner mit den folgenden Befehlen erstellen:

mkdir ~/docker-registry && cd $_
mkdir data

Verwenden Sie Ihren Texteditor, um die Konfigurationsdatei + docker-compose.yml + zu erstellen:

nano docker-compose.yml

Fügen Sie der Datei den folgenden Inhalt hinzu, der die Grundkonfiguration für eine Docker-Registrierung beschreibt:

docker-compose.yml

version: '3'

services:
 registry:
   image: registry:2
   ports:
   - "5000:5000"
   environment:
     REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
   volumes:
     - ./data:/data

Der Abschnitt "+ environment " legt eine Umgebungsvariable im Docker-Registrierungscontainer mit dem Pfad " / data " fest. Die Docker Registry-Anwendung überprüft diese Umgebungsvariable beim Start und beginnt, ihre Daten im Ordner " / data +" zu speichern.

Da Sie jedoch die Zeile "+ volume: - ./data: / data " eingefügt haben, beginnt Docker, das Verzeichnis " / data " in diesem Container " / data " auf Ihrem Registrierungsserver zuzuordnen. Das Endergebnis ist, dass die Daten der Docker-Registry alle in " ~ / docker-registry / data +" auf dem Registry-Server gespeichert werden.

Der Abschnitt "+ ports " mit der Konfiguration "+5000: 5000 +" weist Docker an, den Port " 5000 " auf dem Server dem Port " 5000 " im laufenden Container zuzuordnen. Auf diese Weise können Sie eine Anfrage an den Port " 5000 +" auf dem Server senden und die Anfrage an die Registrierungsanwendung weiterleiten lassen.

Sie können Docker Compose jetzt starten, um das Setup zu überprüfen:

docker-compose up

In Ihrer Ausgabe werden Download-Leisten angezeigt, die zeigen, wie Docker das Docker-Registrierungs-Image aus der Docker-eigenen Registrierung herunterlädt. Innerhalb von ein oder zwei Minuten wird eine Ausgabe angezeigt, die der folgenden ähnelt (Versionen können variieren):

Output of docker-compose upStarting docker-registry_registry_1 ... done
Attaching to docker-registry_registry_1
registry_1  | time="2018-11-06T18:43:09Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2
registry_1  | time="2018-11-06T18:43:09Z" level=info msg="redis not configured" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2
registry_1  | time="2018-11-06T18:43:09Z" level=info msg="Starting upload purge in 20m0s" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2
registry_1  | time="2018-11-06T18:43:09Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2
registry_1  | time="2018-11-06T18:43:09Z" level=info msg="listening on [::]:5000" go.version=go1.7.6 instance.id=c63483ee-7ad5-4205-9e28-3e809c843d42 version=v2.6.2

Die Warnmeldung "+ Kein HTTP-Geheimnis angegeben " wird später in diesem Lernprogramm behandelt. Die Ausgabe zeigt, dass der Container gestartet wird. In der letzten Zeile der Ausgabe wird angezeigt, dass die Überwachung des Ports " 5000 +" erfolgreich gestartet wurde.

Standardmäßig wartet Docker Compose weiterhin auf Ihre Eingabe. Drücken Sie daher die Tastenkombination STRG + C +, um den Docker-Registrierungscontainer herunterzufahren.

Sie haben eine vollständige Docker-Registrierung eingerichtet, die den Port "+ 5000 +" überwacht. Zu diesem Zeitpunkt wird die Registrierung erst gestartet, wenn Sie sie manuell aufrufen. Außerdem verfügt Docker Registry über keinen integrierten Authentifizierungsmechanismus. Daher ist die Registrierung derzeit unsicher und für die Öffentlichkeit uneingeschränkt zugänglich. In den folgenden Schritten werden Sie diese Sicherheitsbedenken ansprechen.

Schritt 2 - Einrichten der Nginx-Portweiterleitung

Sie haben bereits HTTPS auf Ihrem Docker-Registrierungsserver mit Nginx eingerichtet. Dies bedeutet, dass Sie jetzt die Portweiterleitung von Nginx zu Port "+ 5000 +" einrichten können. Sobald Sie diesen Schritt ausgeführt haben, können Sie direkt unter auf Ihre Registrierung zugreifen.

Als Teil der So sichern Sie Nginx mit Let’s Encrypt Voraussetzung ist, dass Sie bereits die Datei "+ / etc / nginx / sites-available / +" eingerichtet haben, die Ihre Serverkonfiguration enthält.

Öffnen Sie diese Datei mit Ihrem Texteditor:

sudo nano /etc/nginx/sites-available/

Suchen Sie die vorhandene Zeile "+ location +". Es wird so aussehen:

/etc/nginx/sites-available/example.com

...
location / {
 ...
}
...

Sie müssen den Datenverkehr an den Port "+ 5000 " weiterleiten, auf dem Ihre Registrierung ausgeführt wird. Sie möchten der Registrierung auch Header an die Anforderung anhängen, die bei jeder Anforderung und Antwort zusätzliche Informationen vom Server bereitstellen. Löschen Sie den Inhalt des Abschnitts " location +" und fügen Sie den folgenden Inhalt in diesen Abschnitt ein:

/etc/nginx/sites-available/example.com

...
location / {
   # Do not allow connections from docker 1.5 and earlier
   # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
   if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
     return 404;
   }

   proxy_pass                          http://localhost:5000;
   proxy_set_header  Host              $http_host;   # required for docker client's sake
   proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
   proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
   proxy_set_header  X-Forwarded-Proto $scheme;
   proxy_read_timeout                  900;
}
...

Der Abschnitt "+ $ http_user_agent " überprüft, ob die Docker-Version des Clients höher als " 1.5 " ist, und stellt sicher, dass der " UserAgent " keine " Go " - Anwendung ist. Da Sie die Version " 2.0 +" der Registrierung verwenden, werden ältere Clients nicht unterstützt. Weitere Informationen finden Sie im Dockers Registry Nginx-Handbuch.

Speichern und schließen Sie die Datei. Übernehmen Sie die Änderungen, indem Sie Nginx neu starten:

sudo service nginx restart

Sie können bestätigen, dass Nginx Datenverkehr an den Port "+ 5000 +" weiterleitet, indem Sie die Registrierung ausführen:

cd ~/docker-registry
docker-compose up

Öffnen Sie in einem Browserfenster die folgende URL:

https:///v2

Sie sehen ein leeres JSON-Objekt oder:

{}

In Ihrem Terminal wird eine Ausgabe ähnlich der folgenden angezeigt:

Output of docker-compose upregistry_1  | time="2018-11-07T17:57:42Z" level=info msg="response completed" go.version=go1.7.6 http.request.host=cornellappdev.com http.request.id=a8f5984e-15e3-4946-9c40-d71f8557652f http.request.method=GET http.request.remoteaddr=128.84.125.58 http.request.uri="/v2/" http.request.useragent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7" http.response.contenttype="application/json; charset=utf-8" http.response.duration=2.125995ms http.response.status=200 http.response.written=2 instance.id=3093e5ab-5715-42bc-808e-73f310848860 version=v2.6.2
registry_1  | 172.18.0.1 - - [07/Nov/2018:17:57:42 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/604.4.7 (KHTML, like Gecko) Version/11.0.2 Safari/604.4.7"

Aus der letzten Zeile können Sie ersehen, dass eine "+ GET " - Anfrage an " / v2 / " gestellt wurde. Dies ist der Endpunkt, an den Sie eine Anfrage von Ihrem Browser gesendet haben. Der Container hat die von Ihnen gestellte Anforderung von der Portweiterleitung empfangen und eine Antwort von " {} " zurückgegeben. Der Code " 200 +" in der letzten Zeile der Ausgabe bedeutet, dass der Container die Anforderung erfolgreich verarbeitet hat.

Nachdem Sie die Portweiterleitung eingerichtet haben, können Sie die Sicherheit Ihrer Registrierung weiter verbessern.

Schritt 3 - Einrichten der Authentifizierung

Wenn Nginx-Proxys Anforderungen ordnungsgemäß verarbeitet, können Sie jetzt Ihre Registrierung mit HTTP-Authentifizierung sichern, um zu verwalten, wer Zugriff auf Ihre Docker-Registrierung hat. Um dies zu erreichen, erstellen Sie eine Authentifizierungsdatei mit "+ htpasswd +" und fügen Benutzer hinzu. Die HTTP-Authentifizierung lässt sich schnell und sicher über eine HTTPS-Verbindung einrichten, die von der Registrierung verwendet wird.

Sie können das Paket + htpasswd + installieren, indem Sie Folgendes ausführen:

sudo apt install apache2-utils

Jetzt erstellen Sie das Verzeichnis, in dem Sie unsere Authentifizierungsdaten speichern, und wechseln in dieses Verzeichnis. + $ _ + wird bis zum letzten Argument des vorherigen Befehls erweitert, in diesem Fall + ~ / docker-registry / auth +:

mkdir ~/docker-registry/auth && cd $_

Als nächstes erstellen Sie den ersten Benutzer wie folgt und ersetzen "+" durch den Benutzernamen, den Sie verwenden möchten. Das Flag " -B " gibt " bcrypt +" an, was sicherer ist als die Standardverschlüsselung. Geben Sie das Passwort ein, wenn Sie dazu aufgefordert werden:

htpasswd -Bc registry.password

Als Nächstes bearbeiten Sie die Datei "+ docker-compose.yml +", um Docker anzuweisen, die von Ihnen erstellte Datei zur Authentifizierung von Benutzern zu verwenden.

cd ~/docker-registry
nano docker-compose.yml

Sie können Umgebungsvariablen und ein Volume für das von Ihnen erstellte Verzeichnis "+ auth / " hinzufügen, indem Sie die Datei " docker-compose.yml +" bearbeiten, um Docker mitzuteilen, wie Sie Benutzer authentifizieren möchten. Fügen Sie der Datei den folgenden hervorgehobenen Inhalt hinzu:

docker-compose.yml

version: '3'

services:
 registry:
   image: registry:2
   ports:
   - "5000:5000"
   environment:



     REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
   volumes:

     - ./data:/data

Für "+ REGISTRY_AUTH " haben Sie " htpasswd ", das von Ihnen verwendete Authentifizierungsschema, angegeben und " REGISTRY_AUTH_HTPASSWD_PATH " auf den Pfad der Authentifizierungsdatei gesetzt. Schließlich bedeutet " REGISTRY_AUTH_HTPASSWD_REALM " den Namen von " htpasswd +" Realm.

Sie können nun überprüfen, ob Ihre Authentifizierung ordnungsgemäß funktioniert, indem Sie die Registrierung ausführen und überprüfen, ob Benutzer zur Eingabe eines Benutzernamens und eines Kennworts aufgefordert werden.

docker-compose up

Öffnen Sie in einem Browserfenster "+ https: /// v2 +".

Nach Eingabe von "+" und dem entsprechenden Passwort sehen Sie erneut " {} +". Sie haben das grundlegende Authentifizierungssetup bestätigt: Die Registrierung hat das Ergebnis erst zurückgegeben, nachdem Sie den richtigen Benutzernamen und das richtige Kennwort eingegeben haben. Sie haben jetzt Ihre Registrierung gesichert und können die Registrierung weiterhin verwenden.

Schritt 4 - Starten der Docker-Registrierung als Dienst

Sie möchten sicherstellen, dass Ihre Registrierung bei jedem Systemstart gestartet wird. Wenn unvorhergesehene Systemabstürze auftreten, sollten Sie sicherstellen, dass die Registrierung beim Neustart des Servers neu gestartet wird. Öffne + docker-compose.yml +:

nano docker-compose.yml

Fügen Sie unter + registry: + die folgende Inhaltszeile hinzu:

docker-compose.yml

...
 registry:

...

Sie können Ihre Registrierung als Hintergrundprozess starten, wodurch Sie die Sitzung + ssh + beenden und den Prozess fortsetzen können:

docker-compose up -d

Wenn Ihre Registrierung im Hintergrund ausgeführt wird, können Sie Nginx jetzt für das Hochladen von Dateien vorbereiten.

Schritt 5 - Erhöhen der Datei-Upload-Größe für Nginx

Bevor Sie ein Bild in die Registrierung übertragen können, müssen Sie sicherstellen, dass Ihre Registrierung große Dateiuploads verarbeiten kann. Obwohl Docker große Bild-Uploads in separate Ebenen aufteilt, können sie manchmal über + 1GB + ​​liegen. Standardmäßig ist Nginx beim Hochladen von Dateien auf + 1MB + beschränkt, daher müssen Sie die Konfigurationsdatei für + nginx + bearbeiten und die maximale Größe für das Hochladen von Dateien auf + 2GB + ​​einstellen.

sudo nano /etc/nginx/nginx.conf

Suchen Sie den Abschnitt "+ http +" und fügen Sie die folgende Zeile hinzu:

/etc/nginx/nginx.conf

...
http {

       ...
}
...

Starten Sie Nginx abschließend neu, um die Konfigurationsänderungen zu übernehmen:

sudo service nginx restart

Sie können jetzt große Bilder ohne Nginx-Fehler in Ihre Docker-Registrierung hochladen.

Schritt 6 - Veröffentlichen in Ihrer privaten Docker-Registrierung

Sie können jetzt ein Bild in Ihrer privaten Docker-Registrierung veröffentlichen, müssen jedoch zuerst ein Bild erstellen. In diesem Tutorial erstellen Sie ein einfaches Bild, das auf dem "+ ubuntu" -Bild von Docker Hub basiert. Docker Hub ist eine öffentlich gehostete Registrierung mit vielen vorkonfigurierten Images, die zum schnellen Andocken von Anwendungen verwendet werden können. Mit dem "+ ubuntu +" - Image testen Sie das Pushen und Ziehen in Ihre Registrierung.

Erstellen Sie auf Ihrem * Client * -Server ein kleines, leeres Image, um es in Ihre neue Registrierung zu übertragen. Die Flags "+ -i " und " -t +" ermöglichen Ihnen den interaktiven Shell-Zugriff auf den Container:

docker run -t -i ubuntu /bin/bash

Beachten Sie, dass sich Ihre Container-ID nach "+ root @ " ändert, nachdem der Download abgeschlossen ist. Nehmen Sie eine schnelle Änderung am Dateisystem vor, indem Sie eine Datei mit dem Namen " SUCCESS +" erstellen. Im nächsten Schritt können Sie anhand dieser Datei feststellen, ob der Veröffentlichungsprozess erfolgreich ist:

touch /SUCCESS

Verlassen Sie den Docker-Container:

exit

Der folgende Befehl erstellt ein neues Image mit dem Namen "+ test-image " basierend auf dem bereits ausgeführten Image und den von Ihnen vorgenommenen Änderungen. In unserem Fall ist das Hinzufügen der Datei " / SUCCESS +" im neuen Image enthalten.

Übernehmen Sie die Änderung:

docker commit $(docker ps -lq) test-image

Zu diesem Zeitpunkt ist das Bild nur lokal vorhanden. Jetzt können Sie es in die neu erstellte Registrierung verschieben. Melden Sie sich bei Ihrer Docker-Registrierung an:

docker login https://

Geben Sie das ++ und das entsprechende Passwort von früher ein. Als Nächstes markieren Sie das Image mit dem Speicherort der privaten Registrierung, um darauf zuzugreifen:

docker tag test-image /test-image

Übertragen Sie das neu markierte Bild in die Registrierung:

docker push /test-image

Ihre Ausgabe sieht ungefähr so ​​aus:

OutputThe push refers to a repository [/test-image]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed
...

Sie haben sichergestellt, dass Ihre Registrierung die Benutzerauthentifizierung verarbeitet und authentifizierten Benutzern das Pushen von Bildern in die Registrierung ermöglicht. Als Nächstes bestätigen Sie, dass Sie auch Bilder aus der Registrierung abrufen können.

Schritt 7 - Abrufen von Ihrer privaten Docker-Registrierung

Kehren Sie zu Ihrem Registrierungsserver zurück, damit Sie das Abbild von Ihrem * Client * -Server testen können. Es ist auch möglich, dies von einem dritten Server aus zu testen.

Melden Sie sich mit dem zuvor eingerichteten Benutzernamen und Passwort an:

docker login https://

Jetzt können Sie das Bild ziehen. Verwenden Sie Ihren Domainnamen und den Bildnamen, die Sie im vorherigen Schritt getaggt haben:

docker pull /test-image

Docker lädt das Bild herunter und kehrt zur Eingabeaufforderung zurück. Wenn Sie das Image auf dem Registrierungsserver ausführen, wird die zuvor erstellte Datei "+ SUCCESS +" angezeigt:

docker run -it /test-image /bin/bash

Listen Sie Ihre Dateien in der Bash-Shell auf:

ls

Sie sehen die + SUCCESS + Datei, die Sie für dieses Bild erstellt haben:

SUCCESS  bin  boot  dev  etc  home  lib  lib64  media   mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

Sie haben die Einrichtung einer sicheren Registrierung abgeschlossen, in die Benutzer benutzerdefinierte Bilder übertragen und abrufen können.

Fazit

In diesem Tutorial haben Sie Ihre eigene private Docker-Registrierung eingerichtet und ein Docker-Image veröffentlicht. Wie in der Einführung erwähnt, können Sie auch TravisCI oder ein ähnliches CI-Tool verwenden, um das direkte Pushen in eine private Registrierung zu automatisieren. Indem Sie Docker und Registries in Ihren Workflow einbinden, können Sie sicherstellen, dass das Image, das den Code enthält, auf jedem Computer, egal ob in der Produktion oder in der Entwicklung, dasselbe Verhalten zeigt. Weitere Informationen zum Schreiben von Docker-Dateien finden Sie in diesem Docker-Tutorial, in dem der Vorgang erläutert wird.