Einrichten einer privaten Docker-Registrierung unter Ubuntu 14.04

Einführung

Docker ist ein großartiges Tool für die Bereitstellung Ihrer Server. Docker hat sogar eine öffentliche Registrierung namens Docker Hub, in der Docker-Images gespeichert werden. Mit Docker können Sie Ihre Docker-Kreationen kostenlos auf den Docker Hub hochladen. Alles, was Sie hochladen, ist auch öffentlich. Dies ist möglicherweise nicht die beste Option für Ihr Projekt.

In diesem Handbuch erfahren Sie, wie Sie Ihre eigene private Docker-Registrierung einrichten und sichern. Am Ende dieses Lernprogramms können Sie ein benutzerdefiniertes Docker-Image in Ihre private Registrierung verschieben und das Image sicher von einem anderen Host herunterladen.

Dieses Lernprogramm behandelt nicht das Containerisieren Ihrer eigenen Anwendung, sondern nur das Erstellen der Registrierung, in der Sie Ihre Bereitstellungen speichern können. Wenn Sie lernen möchten, wie Sie mit Docker selbst beginnen (im Gegensatz zur Registrierung), lesen Sie möglicherweise das Tutorial vonHow To Install and Use Docker: Getting Started.

Dieses Tutorial wurde sowohl mit dem Registrierungsserver als auch mit dem Registrierungsclient getestet, auf demUbuntu 14.04 ausgeführt wird. Es funktioniert jedoch möglicherweise mit anderen Debian-basierten Distributionen. Es wird auch die Version 2.0 der Docker-Registrierung behandelt.

Docker-Konzepte

Wenn Sie Docker noch nicht verwendet haben, sollten Sie sich eine Minute Zeit nehmen, um einige der wichtigsten Konzepte von Docker durchzugehen. Wenn Sie Docker bereits verwenden und nur wissen möchten, wie Sie mit der Ausführung Ihrer eigenen Registrierung beginnen können, fahren Sie mit dem nächsten Abschnitt fort.

Eine Auffrischung zur Verwendung von Docker finden Sie in den hervorragendenDocker Cheat Sheet.

Docker bietet im Kern die Möglichkeit, eine Anwendung und die Abhängigkeiten, die für die Ausführung erforderlich sind, vom Betriebssystem selbst zu trennen. Um dies zu ermöglichen, verwendet Dockercontainers undimages. Ein Docker-Image ist im Grunde eine Vorlage für ein Dateisystem. Wenn Sie ein Docker-Image ausführen, wird eine Instanz dieses Dateisystems live geschaltet und auf Ihrem System in einem Docker-Container ausgeführt. Standardmäßig kann dieser Container das Original-Image selbst oder das Dateisystem des Hosts, auf dem Docker ausgeführt wird, nicht berühren. Es ist eine eigenständige Umgebung.

Alle Änderungen, die Sie am Container vornehmen, bleiben im Container selbst erhalten und wirken sich nicht auf das Originalbild aus. Wenn Sie diese Änderungen beibehalten möchten, können Sie einen Container (über den Befehldocker commit) in ein Docker-Image "festschreiben". Dies bedeutet, dass Sie neue Container erzeugen können, die mit dem Inhalt Ihres alten Containers beginnen, ohne dass dies Auswirkungen auf den ursprünglichen Container (oder das Originalbild) hat. Wenn Sie mitgit vertraut sind, sollte der Workflow ziemlich ähnlich aussehen: Sie können aus jedem Container neue Zweige (Bilder im Docker-Sprachgebrauch) erstellen. Das Ausführen eines Bildes ähnelt dem Ausführen vongit checkout.

Um die Analogie fortzusetzen, entspricht das Ausführen einer privaten Docker-Registrierung dem Ausführen eines privaten Git-Repositorys für Ihre Docker-Images.

Voraussetzungen

Um dieses Tutorial abzuschließen, benötigen Sie Folgendes:

  • 2 Ubuntu 14.04 Droplets: eines für die private Docker-Registrierung und eines für den Docker-Client

  • Ein Nicht-Root-Benutzer mit Sudo-Berechtigungen für jedes Droplet (Initial Server Setup with Ubuntu 14.04erklärt, wie dies eingerichtet wird.)

  • Docker und Docker Compose werden mit den Anweisungen vonHow To Install and Use Docker Compose on Ubuntu 14.04 installiert

  • Ein Domänenname, der in das Droplet für die private Docker-Registrierung aufgelöst wird

[[Schritt-1 - Installieren des Pakets für zusätzliche Sicherheit]] == Schritt 1 - Installieren des Pakets für zusätzliche Sicherheit

Um die Sicherheit für die Docker-Registrierung einzurichten, verwenden Sie am bestenDocker Compose. Auf diese Weise können wir die Docker-Registrierung auf einfache Weise in einem Container ausführen und Nginx die Sicherheit und Kommunikation mit der Außenwelt in einem anderen übernehmen lassen. Sie sollten es bereits im Abschnitt Voraussetzungen installiert haben.

Da wir Nginx verwenden, um unsere Sicherheit zu gewährleisten, benötigen wir auch einen Speicherort für die Liste der Benutzer- und Kennwortkombinationen, auf die wir zugreifen möchten. Wir werden das Paketapache2-utilsinstallieren, das das Dienstprogrammhtpasswdenthält, mit dem Nginx leicht Kennwort-Hashes generieren kann:

sudo apt-get -y install apache2-utils

[[Schritt 2 - Installieren und Konfigurieren der Docker-Registrierung]] == Schritt 2 - Installieren und Konfigurieren der Docker-Registrierung

Das Docker-Befehlszeilentool eignet sich hervorragend zum Starten und Verwalten von Docker-Containern. Die meisten Apps, die in Docker-Containern ausgeführt werden, sind jedoch nicht isoliert vorhanden. Um die meisten Apps vollständig bereitzustellen, müssen einige Komponenten parallel ausgeführt werden. Beispielsweise bestehen die meisten Webanwendungen aus einem Webserver, der den Code der App bereitstellt, einer interpretierten Skriptsprache wie PHP oder Ruby (mit Rails) und einem Datenbankserver wie MySQL.

Mit Docker Compose können Sie eine.yml-Konfigurationsdatei für die Konfiguration für jeden Container sowie Informationen darüber schreiben, wie die Container miteinander kommunizieren. Anschließend verwenden Sie das Befehlszeilentooldocker-compose, um Befehle an alle Komponenten auszugeben, aus denen eine Anwendung besteht.

Da die Docker-Registrierung selbst eine Anwendung mit mehreren Komponenten ist, verwenden wir Docker Compose, um unsere Konfiguration zu verwalten.

Um eine Basisregistrierung zu starten, muss lediglich der Speicherort festgelegt werden, an dem die Daten in Ihrer Registrierung gespeichert werden. Richten wir eine grundlegende Docker Compose YAML-Datei ein, um eine Basisinstanz der Registrierung aufzurufen.

Erstellen Sie zunächst einen Ordner, in dem sich unsere Dateien für dieses Tutorial befinden, und einige der Unterordner, die wir benötigen:

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

Erstellen Sie mit Ihrem bevorzugten Texteditor einedocker-compose.yml-Datei:

nano docker-compose.yml

Fügen Sie der Datei den folgenden Inhalt hinzu:

docker-compose.yml

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

Das Interessante hier ist am Ende. Der Abschnittenvironment legt eine Umgebungsvariable im Docker-Registrierungscontainer mit dem Pfad/data fest. Die Docker-Registrierungs-App kann diese Umgebungsvariable beim Start überprüfen und ihre Daten daher im Ordner/datapeichern.

Nur in diesem Fall teilt das Bitvolumes: - ./data:/dataDocker mit, dass das Verzeichnis/datain diesem Container tatsächlich/data auf unserem Hostcomputer zugeordnet werden soll. Das Endergebnis ist also, dass alle Daten der Docker-Registrierung in~/docker-registry/data auf unserem lokalen Computer gespeichert werden.

Lassen Sie uns fortfahren und sicherstellen, dass alles in Ordnung ist:

cd ~/docker-registry
docker-compose up

Auf dem Bildschirm werden eine Reihe von Download-Leisten angezeigt (Docker lädt das eigentliche Docker-Registrierungs-Image von Dockers eigener Docker-Registrierung herunter). Wenn in ein oder zwei Minuten alles gut gegangen ist, sollten Sie eine Ausgabe sehen, die so aussieht (Versionen können variieren):

Output of docker-compose upregistry_1 | time="2015-10-18T23:45:58Z" 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." instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="redis not configured" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="using inmemory blob descriptor cache" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="listening on [::]:5000" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="Starting upload purge in 1m0s" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1

Mach dir keine Sorgen über dieNo HTTP secret provided-Meldung. Es ist normal.

Toll! Zu diesem Zeitpunkt haben Sie bereits eine vollständige Docker-Registrierung eingerichtet und können Port 5000 abhören (dies wurde durch das Bitports:in der Dateidocker-compose.yml festgelegt). Zu diesem Zeitpunkt ist die Registrierung noch nicht so nützlich. Sie wird erst gestartet, wenn Sie die Registrierung manuell aufrufen. Außerdem verfügt die Docker-Registrierung über keinen integrierten Authentifizierungsmechanismus, sodass sie derzeit unsicher und vollständig für die Öffentlichkeit zugänglich ist.

Docker Compose wartet standardmäßig für immer auf Ihre Eingabe. Drücken Sie alsoCTRL-C, um Ihren Docker-Registrierungscontainer herunterzufahren.

[[Schritt-3 -—- Einrichten eines Nginx-Containers]] == Schritt 3 - Einrichten eines Nginx-Containers

Beginnen wir mit der Behebung dieser Sicherheitsprobleme. Der erste Schritt besteht darin, eine Kopie von Nginx in einem anderen Docker-Container einzurichten und mit unserem Docker-Registrierungscontainer zu verknüpfen.

Beginnen wir mit der Erstellung eines Verzeichnisses zum Speichern unserer Nginx-Konfiguration:

mkdir ~/docker-registry/nginx

Öffnen Sie nun Ihredocker-compose.yml-Datei im~/docker-registry-Verzeichnis erneut:

nano docker-compose.yml

Fügen Sie Folgendes oben in die Datei ein:

docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro

Dadurch wird ein neuer Docker-Container erstellt, der auf dem offiziellen Nginx-Image basiert. Das Interessante hier ist der Abschnittlinks. Es wird automatisch eine „Verbindung“ von einem Docker-Container zum anderen hergestellt. Wenn der Nginx-Container gestartet wird, kann er den Containerregistryunter dem Hostnamenregistryerreichen, unabhängig von der tatsächlichen IP-Adresse, über die der Containerregistryverfügt. (Hinter den Kulissen fügt Docker tatsächlich einen Eintrag in die Datei/etc/hosts im Containernginxein, um die IP-Adresse des Containersregistryanzugeben.)

Der Abschnittvolumes: ähnelt dem, was wir für den Containerregistry getan haben. In diesem Fall können wir die Konfigurationsdateien, die wir für Nginx verwenden, auf unserem Hostcomputer statt im Docker-Container speichern. Das:ro am Ende teilt Docker lediglich mit, dass der Nginx-Container nur Lesezugriff auf das Host-Dateisystem haben soll.

Ihre vollständigedocker-compose.yml-Datei sollte nun folgendermaßen aussehen:

docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

Wenn Siedocker-compose up ausführen, werden jetzt zwei Container gleichzeitig gestartet: einer für die Docker-Registrierung und einer für Nginx.

Wir müssen Nginx konfigurieren, bevor dies funktioniert. Erstellen wir also eine neue Nginx-Konfigurationsdatei.

Erstellen Sie eineregistry.conf-Datei:

nano ~/docker-registry/nginx/registry.conf

Kopieren Sie Folgendes in die Datei:

~/docker-registry/nginx/registry.conf

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # 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;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
    # auth_basic "registry.localhost";
    # auth_basic_user_file /etc/nginx/conf.d/registry.password;
    # add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    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;
  }
}

Speichern und schließen Sie die Datei.

Jetzt können Sie Nginx installieren und die beiden Docker-Container mit einem Befehl starten:

docker-compose up

Nginx druckt beim Start keine Ausgabe, aber wenn alles gut gegangen ist, führen Sie jetzt eine Kopie von Nginx aus, die als Proxy für den Container Ihresregistryeingerichtet ist. Verwenden Sie zum Testencurl, um eine HTTP-Anfrage direkt an unsere Docker-Registrierung zu senden, und stellen Sie dann eine weitere Anfrage an unseren Nginx-Port. Wenn alles korrekt eingerichtet ist, ist die Ausgabe in beiden Fällen gleich (zum jetzigen Zeitpunkt gibt Docker ein leeres JSON-Objekt "{}" zurück), da Nginx die Anforderung an die Docker-Registrierung weiterleitet.

Stellen Sie zunächst eine HTTP-Anfrage direkt an die Docker-Registrierung:

curl http://localhost:5000/v2/

Zum jetzigen Zeitpunkt gibt Docker ein leeres json-Objekt zurück, daher sollten Sie Folgendes sehen:

Output{}

Senden Sie nun eine HTTP-Anfrage an den Nginx-Port:

curl http://localhost:5043/v2/

Sie sollten die gleiche Ausgabe sehen:

Output{}

Wenn die Dinge richtig funktionieren, wird im Terminal Ihresdocker-composeeine Ausgabe angezeigt, die ebenfalls wie folgt aussieht:

Output of docker-compose    registry_1 | time="2015-08-11T10:24:53.746529894Z" level=debug msg="authorizing request" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | time="2015-08-11T10:24:53.747650205Z" level=info msg="response completed" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" http.response.contenttype="application/json; charset=utf-8" http.response.duration=8.143193ms http.response.status=200 http.response.written=2 instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | 172.17.0.21 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.35.0"
    nginx_1    | 172.17.42.1 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.35.0" "-"

Wenn Sie Zeilen mit dem Präfixregistry_ sehen (die Zahl nach_ kann auf Ihrem Computer unterschiedlich sein), ist alles in Ordnung, und Nginx hat unsere HTTP-Anforderung erfolgreich an die Docker-Registrierung weitergeleitet.

Fahren Sie fort und drücken Sie erneutCTRL-C in Ihremdocker-compose-Terminal, um Ihre Docker-Container herunterzufahren.

[[Schritt 4 - Einrichten der Authentifizierung]] == Schritt 4 - Einrichten der Authentifizierung

Nachdem Nginx die Anfragen ordnungsgemäß weiterleitet, richten wir die HTTP-Authentifizierung ein, damit wir steuern können, wer Zugriff auf unsere Docker-Registrierung hat. Dazu erstellen wir eine Authentifizierungsdatei im Apache-Format (Nginx kann sie auch lesen) über das zuvor installierte Dienstprogrammhtpasswdund fügen Benutzer hinzu.

Erstellen Sie den ersten Benutzer wie folgt und ersetzen SieUSERNAME durch den Benutzernamen, den Sie verwenden möchten:

cd ~/docker-registry/nginx
htpasswd -c registry.password USERNAME

Erstellen Sie ein neues Kennwort für diesen Benutzer, wenn Sie dazu aufgefordert werden.

Wenn Sie in Zukunft weitere Benutzer hinzufügen möchten, führen Sie den obigen Befehl einfach ohne die Option-c erneut aus (c dient zum Erstellen):

htpasswd registry.password USERNAME

Zu diesem Zeitpunkt haben wir eineregistry.password-Datei mit unseren Benutzern eingerichtet und eine Docker-Registrierung verfügbar. Sie können jederzeit einen Blick auf die Datei werfen, wenn Sie Ihre Benutzer anzeigen möchten (und Benutzer entfernen, wenn Sie den Zugriff widerrufen möchten).

Als Nächstes müssen wir Nginx anweisen, diese Authentifizierungsdatei zu verwenden.

Öffnen Sie~/docker-registry/nginx/registry.conf in Ihrem bevorzugten Texteditor:

nano ~/docker-registry/nginx/registry.conf

Scrollen Sie in die Mitte der Datei, in der einige Zeilen angezeigt werden, die wie folgt aussehen:

~/docker-registry/nginx/registry.conf

# To add basic authentication to v2 use auth_basic setting plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

Kommentieren Sie die beiden Zeilen, die mitauth_basic beginnen, sowie die Zeile, die mitadd_header beginnt, aus, indem Sie das Zeichen# am Anfang
der Zeilen entfernen. Es sollte dann so aussehen:

~/docker-registry/nginx/registry.conf

# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

Wir haben Nginx nun angewiesen, die HTTP-Basisauthentifizierung für alle Anforderungen zu aktivieren, die an die Docker-Registrierung weitergeleitet werden, und ihm die Verwendung der soeben erstellten Kennwortdatei empfohlen.

Lassen Sie uns unsere Container wieder hochfahren, um zu sehen, ob die Authentifizierung funktioniert:

cd ~/docker-registry
docker-compose up

Wiederholen Sie den vorherigen Curl-Test:

curl http://localhost:5043/v2/

Sie sollten eine Meldung erhalten, in der Sie sich beschweren, dass Sie nicht autorisiert sind:

Output of curl
401 Authorization Required

401 Authorization Required


nginx/1.9.7

Versuchen Sie nun, den zuvor erstellten Benutzernamen und das Kennwort zur Anforderung voncurlhinzuzufügen:

curl http://USERNAME:PASSWORD@localhost:5043/v2/

Sie sollten dieselbe Ausgabe erhalten, die Sie zuvor erhalten haben - das leere JSON-Objekt{}. Sie sollten auch die gleicheregistry_-Ausgabe imdocker-compose-Terminal sehen.

Fahren Sie fort und verwenden SieCTRL-C im Terminaldocker-compose, um die Docker-Container herunterzufahren.

[[Schritt-5 - Einrichten von SSL]] == Schritt 5 - Einrichten von SSL

Zu diesem Zeitpunkt ist die Registrierung hinter Nginx aktiv und die HTTP-Basisauthentifizierung funktioniert. Das Setup ist jedoch immer noch nicht sehr sicher, da die Verbindungen unverschlüsselt sind. Möglicherweise haben Sie die auskommentierten SSL-Zeilen in der Nginx-Konfigurationsdatei bemerkt, die wir zuvor erstellt haben.

Aktivieren wir sie. Öffnen Sie zunächst die Nginx-Konfigurationsdatei zum Bearbeiten:

nano ~/docker-registry/nginx/registry.conf

Verwenden Sie die Pfeiltasten, um sich zu bewegen und nach diesen Zeilen zu suchen:

~/docker-registry/nginx/registry.conf

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

Kommentieren Sie die Zeilen unter dem SSL-Kommentar aus, indem Sie die#-Zeichen vor ihnen entfernen. Wenn Sie einen Domainnamen für Ihren Server eingerichtet haben, ändern Sie den Wert vonserver_name in Ihren Domainnamen, während Sie gerade dabei sind. Wenn Sie fertig sind, sollte der obere Teil der Datei folgendermaßen aussehen:

~/docker-registry/nginx/registry.conf

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  ssl on;
  ssl_certificate /etc/nginx/conf.d/domain.crt;
  ssl_certificate_key /etc/nginx/conf.d/domain.key;

Speicher die Datei. Nginx ist jetzt für die Verwendung von SSL konfiguriert und sucht nach dem SSL-Zertifikat und den Schlüsseldateien bei/etc/nginx/conf.d/domain.crt bzw./etc/nginx/conf.d/domain.key. Aufgrund der Zuordnungen, die wir zuvor in unsererdocker-compose.yml-Datei eingerichtet haben, entspricht der Pfad von/etc/nginx/conf.d/im Nginx-Container dem Ordner~/docker-registry/nginx/ auf unserem Host-Computer. Daher legen wir unsere Zertifikatdateien dort ab .

Wenn Sie bereits ein SSL-Zertifikat eingerichtet haben oder planen, eines zu kaufen, können Sie das Zertifikat und die Schlüsseldateien einfach in die inregistry.conf (ssl_certificate undssl_certificate_key) aufgeführten Pfade kopieren.

Sie könnten auch einfree signed SSL certificate erhalten.

Andernfalls müssen wir ein selbstsigniertes SSL-Zertifikat verwenden.

Signieren Sie Ihr eigenes Zertifikat

Da Docker die Verwendung von selbstsignierten SSL-Zertifikaten derzeit nicht zulässt, ist dies etwas komplizierter als üblich. Außerdem müssen wir unser System so einrichten, dass es als eigene Zertifizierungsstelle fungiert.

Wechseln wir zunächst in den Ordner~/docker-registry/nginxund bereiten Sie die Erstellung der Zertifikate vor:

cd ~/docker-registry/nginx

Erzeugen Sie einen neuen Root-Schlüssel:

openssl genrsa -out devdockerCA.key 2048

Erstellen Sie ein Stammzertifikat (geben Sie bei den Eingabeaufforderungen ein, was Sie möchten):

openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt

Generieren Sie dann einen Schlüssel für Ihren Server (dies ist die Datei, auf diessl_certificate_key in unserer Nginx-Konfiguration verweist):

openssl genrsa -out domain.key 2048

Jetzt müssen wir eine Zertifikatsignierungsanfrage stellen.

Nachdem Sie diesen Befehl eingegeben haben, werden Sie von OpenSSL aufgefordert, einige Fragen zu beantworten. Schreiben Sie für die ersten paar, was Sie möchten, aber wenn OpenSSL Sie auffordert, die“Common Name” make sure to type in the domain or IP of your servereinzugeben.

openssl req -new -key domain.key -out dev-docker-registry.com.csr

Wenn Ihre Docker-Registrierung beispielsweise in der Domänewww.ilovedocker.com ausgeführt wird, sollte Ihre Eingabe folgendermaßen aussehen:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.ilovedocker.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Geben Sie kein Challenge-Passwort ein.

Als nächstes müssen wir die Zertifikatsanforderung signieren:

openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000

Da die soeben generierten Zertifikate nicht von einer bekannten Zertifizierungsstelle (z. B. VeriSign) überprüft wurden, müssen wir allen Clients, die diese Docker-Registrierung verwenden, mitteilen, dass dies ein legitimes Zertifikat ist. Führen Sie dies lokal auf dem Host-Computer aus, damit wir Docker vom Docker-Registrierungsserver selbst aus verwenden können:

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
sudo update-ca-certificates

Starten Sie den Docker-Daemon neu, damit die Änderungen in unserem Zertifikatspeicher übernommen werden:

sudo service docker restart

[.warning] #Warning: Sie müssen diesen Schritt für jeden Computer wiederholen, der eine Verbindung zu dieser Docker-Registrierung herstellt! Anweisungen dazu für Ubuntu 14.04-Clients finden Sie inStep 9 — Accessing Your Docker Registry from a Client Machine.
#

[[Schritt-6 -—- Testing-SSL]] == Schritt 6 - Testen von SSL

Rufen Sie unsere Docker-Container über die jetzt bekanntendocker-compose up auf:

cd ~/docker-registry
docker-compose up

Führen Sie einen weiterencurl-Test von einem anderen Terminal aus durch (diesmal nur mit https), um sicherzustellen, dass unser SSL-Setup ordnungsgemäß funktioniert. Beachten Sie, dass SSL für die ordnungsgemäße Funktion denselben Domänennamen verwenden muss, den Sie zuvor beim Erstellen Ihres SSL-Zertifikats in das FeldCommon Nameeingegeben haben.

curl https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

[.Hinweis]##

Note: Wenn Sie ein selbstsigniertes Zertifikat verwenden, wird der folgende Fehler voncurl angezeigt:

curl: (60) SSL certificate problem: self signed certificate

Verwenden Sie die Option-k, umcurlnot mitzuteilen, um dies mit dem Peer zu überprüfen:

curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

Wenn der Benutzer und das Kennwort, die Sie eingerichtet haben, beispielsweisesammy undtest waren und Ihr SSL-Zertifikat fürwww.example.com lautet, geben Sie Folgendes ein:

curl https://sammy:[email protected]:5043/v2/

Wenn alles gut gegangen ist, drucktcurl ein leeres JSON-Objekt{}, und Ihr Terminaldocker-compose druckt die übliche Ausgabe vonregistry_.

Wenn nicht, überprüfen Sie die SSL-Schritte und Ihre Nginx-Konfigurationsdatei erneut, um sicherzustellen, dass alles korrekt ist.

Zu diesem Zeitpunkt haben wir eine funktionsfähige Docker-Registrierung 2.0, die hinter einem Nginx-Server ausgeführt wird, der die Authentifizierung und Verschlüsselung über SSL bereitstellt. Wenn Ihre Firewall so konfiguriert ist, dass von außen auf Port5043 zugegriffen werden kann, sollten Sie sich von jedem Computerdocker login https://<YOURDOMAIN> aus bei dieser Docker-Registrierung anmelden und den im vorherigen Abschnitt festgelegten Benutzernamen und das Kennwort eingeben können .

[[Schritt-7 - Einstellung von SSL-Port auf 443] == Schritt 7 - SSL-Port auf 443 setzen

Nur noch ein paar Schritte, bevor wir fertig sind: Ändern Sie den Port so, dass er den Standard-SSL-Port443 (optional) verwendet, und setzen Siedocker-compose, um diesen Containersatz beim Start zu starten.

Beginnen wir damit, unseren dockerisierten Nginx-Container so einzurichten, dass er den Port 443 (den Standardport für SSL) und nicht den nicht standardmäßigen Port 5043 überwacht, den wir bisher verwendet haben. Ports unter 1024 sind jedoch unter Linux "privilegierte" Ports, was bedeutet, dass wir unserendocker-compose-Container als root ausführen müssen.

Öffnen Sie zuerstdocker-compose.yml in einem Texteditor:

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

Unter dem Abschnitt Nginx sehen Sie einen Abschnittports:. Ändern Sie die Zeile- 5043:443 (dies ordnet Port 5043 auf unserem Host-Computer Port 443 im Nginx-Container zu) in- 443:443, damit unsere Der Port 443 des Nginx-Containers wird dem Port 443 unseres Host-Computers zugeordnet. Wenn Sie fertig sind, sollten Ihredocker-compose.yml so aussehen:

~/docker-registry/docker-compose.yml

nginx:
  image: "nginx:1.9"
  ports:
    - 443:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

Beenden Sie Ihredocker-compose-Sitzung überCTRL-C, wenn sie noch ausgeführt wird, und starten Sie sie an Port 443 neu:

sudo docker-compose up

[.note] #Note: Nur Root-Benutzer können Ports unter 1024 abhören. Beachten Sie, dass Sie diesmalsudo mit dem Befehldocker-compose verwenden müssen, damit Nginx auf dem Standard-SSL-Port 443 ausgeführt werden kann.
#

Sie sollten sehen, dassdocker-compose wie gewohnt gestartet wird.

Versuchen wir es mit einem anderencurl-Test unter Verwendung unseres Domainnamens. Nur dieses Mal geben wir die:5043 nicht in der URL an:

curl https://:@YOUR-DOMAIN/v2/

Wenn alles gut gegangen ist, sollten Sie die übliche Ausgabe vonregistry_in Ihrem Terminal vondocker-composeehen. Möglicherweise möchten Sie auch versuchen, denselben Befehlcurl von einem anderen Computer aus auszuführen, um sicherzustellen, dass Ihr Port 443 der Außenwelt ausgesetzt ist.

Fahren Sie fort und verwenden SieCTRL-C im Terminaldocker-compose, um die Docker-Container herunterzufahren, bevor Sie mit dem nächsten Schritt fortfahren.

[[Schritt 8 - Starten der Docker-Registrierung als Dienst]] == Schritt 8 - Starten der Docker-Registrierung als Dienst

Wenn alles gut aussieht, erstellen wir einUpstart-Skript, damit unsere Docker-Registrierung bei jedem Systemstart gestartet wird.

Entfernen Sie zunächst alle vorhandenen Container, verschieben Sie die Docker-Registrierung an einen systemweiten Speicherort und ändern Sie die Berechtigungen in root:

cd ~/docker-registry
docker-compose rm   # this removes the existing containers
sudo mv ~/docker-registry /docker-registry
sudo chown -R root: /docker-registry

Verwenden Sie dann Ihren bevorzugten Texteditor, um ein Upstart-Skript zu erstellen:

sudo nano /etc/init/docker-registry.conf

Fügen Sie den folgenden Inhalt hinzu, um das Upstart-Skript zu erstellen (Upstart zur ordnungsgemäßen Überwachung von Docker-Containern zu bringen, ist etwas schwierig. Überprüfen Siethis blog post, wenn Sie weitere Informationen zu den Funktionen dieses Upstart-Skripts wünschen.)

/etc/init/docker-registry.conf

description "Docker Registry"

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 10 5

chdir /docker-registry

exec /usr/local/bin/docker-compose up

Weitere Informationen zu Upstart-Skripten finden Sie unterthis tutorial.

Testen Sie unser neues Upstart-Skript, indem Sie Folgendes ausführen:

sudo service docker-registry start

Sie sollten so etwas sehen:

docker-registry start/running, process 25303

Sie können überprüfen, ob der Server ausgeführt wird, indem Sie Folgendes ausführen:

docker ps

Die Ausgabe sollte wie folgt aussehen (beachten Sie, dass alle Namen mitdockerregistry_ beginnen

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                          NAMES
d4b6fef0b4d1        nginx:1.9           "nginx -g 'daemon of   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:443->443/tcp   dockerregistry_nginx_1
77668352bd39        registry:2          "registry cmd/regist   2 minutes ago       Up 2 minutes        127.0.0.1:5000->5000/tcp       dockerregistry_registry_1

Upstart protokolliert die Ausgabe des Befehlsdocker-compose in/var/log/upstart/docker-registry.log. Für unseren letzten Test lassen Sie uns die Protokolldatei mittail "live beobachten" (sudo ist erforderlich, da Upstart-Protokolle als Root-Benutzer geschrieben werden):

sudo tail -f /var/log/upstart/docker-registry.log

Sie sollten die übliche Ausgabe vonregistry_ehen. Führen Sie von einem anderen Terminal oder einer anderen Maschine aus unseren jetzt bekanntencurl-Test aus:

curl https://:@[YOUR-DOMAIN]/v2/

Wenn alles richtig funktioniert, druckt Curl ein{} auf Ihr Terminal und Sie sollten das Übliche sehen:

registry_1 | time="2015-08-12T08:01:12.241887501Z" level=debug msg="authorizing request" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | time="2015-08-12T08:01:12.242206499Z" level=info msg="response completed" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" http.response.contenttype="application/json; charset=utf-8" http.response.duration=3.359883ms http.response.status=200 http.response.written=2 instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | 172.17.0.4 - - [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.37.1"
nginx_1    | 106.1.247.4 - nik [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.37.1" "-"

[[Schritt 9 - Zugriff auf Ihre Docker-Registrierung von einem Client-Computer aus]] == Schritt 9 - Zugriff auf Ihre Docker-Registrierung von einem Client-Computer aus

Um von einem anderen Computer aus auf Ihre Docker-Registrierung zuzugreifen, fügen Sie zunächst das zuvor erstellte SSL-Zertifikat zum neuen Client-Computer hinzu. Die gewünschte Datei befindet sich bei~/docker-registry/nginx/devdockerCA.crt.

Sie können es direkt auf den neuen Computer kopieren oder die folgenden Anweisungen verwenden, um es zu kopieren und einzufügen:

Zeigen Sie auf denregistry server das Zertifikat an:

sudo cat /docker-registry/nginx/devdockerCA.crt

Sie erhalten eine Ausgabe, die ungefähr so ​​aussieht:

Output of sudo cat /docker-registry/nginx/devdockerCA.crt-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTQwOTIxMDYwODE2WhcNNDIwMjA2MDYwODE2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuK4kNFaY3k/0RdKRK1XLj9+IrpR7WW5lrNaFB0OIiItHV9FjyuSWK2mj
ObR1IWJNrVSqWvfZ/CLGay6Lp9DJvBbpT68dhuS5xbVw3bs3ghB24TntDYhHMAc8
GWor/ZQTzjccHUd1SJxt5mGXalNHUharkLd8mv4fAb7Mh/7AFP32W4X+scPE2bVH
OJ1qH8ACo7pSVl1Ohcri6sMp01GoELyykpXu5azhuCnfXLRyuOvQb7llV5WyKhq+
SjcE3c2C+hCCC5g6IzRcMEg336Ktn5su+kK6c0hoD0PR/W0PtwgH4XlNdpVFqMST
vthEG+Hv6xVGGH+nTszN7F9ugVMxewIDAQABo1AwTjAdBgNVHQ4EFgQULek+WVyK
dJk3JIHoI4iVi0FPtdwwHwYDVR0jBBgwFoAULek+WVyKdJk3JIHoI4iVi0FPtdww
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkignESZcgr4dBmVZqDwh
YsrKeWSkj+5p9eW5hCHJ5Eg2X8oGTgItuLaLfyFWPS3MYWWMzggxgKMOQM+9o3+k
oH5sUmraNzI3TmAtkqd/8isXzBUV661BbSV0obAgF/ul5v3Tl5uBbCXObC+NUikM
O0C3fDmmeK799AM/hP5CTDehNaFXABGoVRMSlGYe8hZqap/Jm6AaKThV4g6n4F7M
u5wYtI9YDMsxeVW6OP9ZfvpGZW/n/88MSFjMlBjFfFsorfRd6P5WADhdfA6CBECG
LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H
6g==
-----END CERTIFICATE-----

Kopieren Sie diese Ausgabe in Ihre Zwischenablage und stellen Sie eine Verbindung zu Ihrem Client-Computer her.

Erstellen Sie auf denclient machine das Zertifikatverzeichnis:

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert

Öffnen Sie die Zertifikatsdatei zum Bearbeiten:

sudo nano /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

Fügen Sie den Inhalt des Zertifikats ein.

Stellen Sie sicher, dass die auf dem Clientcomputer gespeicherte Datei korrekt ist, indem Sie die Datei anzeigen:

cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

Wenn alles richtig funktioniert hat, wird derselbe Text von früher angezeigt:

Output of cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
...
...
LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H
6g==
-----END CERTIFICATE-----

Aktualisieren Sie nun die Zertifikate:

sudo update-ca-certificates

Sie sollten eine Ausgabe erhalten, die wie folgt aussieht (beachten Sie die "1 hinzugefügt"):

Output of sudo update-ca-certificatesUpdating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

Wenn Sie Docker noch nicht auf dem Client installiert haben, tun Sie dies jetzt (siehe Abschnitt "Voraussetzungen").

Starten Sie Docker neu, um sicherzustellen, dass die CA-Zertifikate des Systems neu geladen werden.

sudo service docker restart

Sie sollten jetzt in der Lage sein, sich vom Client-Computer aus bei Ihrer Docker-Registrierung anzumelden:

docker login https://YOUR-DOMAIN

Beachten Sie, dass Siehttps:// verwenden. Geben Sie den Benutzernamen und das Passwort ein, die Sie zuvor eingerichtet haben.

Output of docker loginUsername: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

Sie sollten die folgende Meldung sehen:

Output of docker loginLogin Succeeded

Zu diesem Zeitpunkt ist Ihre Docker-Registrierung aktiv! Erstellen wir ein Test-Image, um es in die Registrierung zu übertragen.

[[Schritt 10 - Veröffentlichung in Ihrer privaten Docker-Registrierung]] == Schritt 10 - Veröffentlichung in Ihrer privaten Docker-Registrierung

Sie können jetzt ein Bild in Ihrer privaten Docker-Registrierung veröffentlichen, aber zuerst müssen wir ein Bild erstellen. Wir werden ein einfaches Bild basierend auf demubuntu-Bild von Docker Hub erstellen.

Erstellen Sie aus Ihrenclient machine ein kleines leeres Bild, um es in unsere neue Registrierung zu verschieben.

docker run -t -i ubuntu /bin/bash

Nachdem der Download abgeschlossen ist, wird eine Docker-Eingabeaufforderung angezeigt. Nehmen Sie eine schnelle Änderung am Dateisystem vor, indem Sie eine Datei mit dem NamenSUCCESS erstellen:

touch /SUCCESS

Verlassen Sie den Docker-Container:

exit

Übernehmen Sie die Änderung:

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

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

Dieses Image ist derzeit nur lokal vorhanden. Übertragen Sie es also auf die neu erstellte Registrierung.

Im vorherigen Schritt haben Sie sich bei Ihrer privaten Docker-Registrierung angemeldet. Falls Sie noch nicht angemeldet sind, melden Sie sich erneut an (beachten Sie, dass Siehttps:// verwenden möchten):

docker login https://YOUR-DOMAIN

Geben Sie den Benutzernamen und das Passwort ein, die Sie zuvor eingerichtet haben:

Username: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

Docker verfügt über einen ungewöhnlichen Mechanismus, mit dem angegeben wird, zu welcher Registrierung der Push gesendet werden soll. Sie müssen ein Bild mit dem Speicherort der privaten Registrierung kennzeichnen, um darauf zugreifen zu können. Markieren wir unser Bild in unserer privaten Registrierung:

docker tag test-image [YOUR-DOMAIN]/test-image

Beachten Sie, dass Sie zuerst den lokalen Namen des Bildes und dann das Tag verwenden, das Sie hinzufügen möchten. Das Tag verwendetnothttps://, nur die Domäne, den Port und den Bildnamen.

Jetzt können wir das Bild in unsere Registry übertragen. Dieses Mal verwenden wir nur den Tag-Namen:

docker push [YOUR-DOMAIN]/test-image

Das Hochladen auf den Registrierungsserver dauert einen Moment. Sie sollten eine Ausgabe sehen, die mit etwas ähnlichem endet:

Output of docker pushlatest: digest: sha256:5ea1cfb425544011a3198757f9c6b283fa209a928caabe56063f85f3402363b4 size: 8008

[[Schritt-11 -—- aus Ihrer Docker-Registrierung ziehen]] == Schritt 11 - Aus Ihrer Docker-Registrierung ziehen

Um sicherzustellen, dass alles funktioniert hat, kehren wir zu unserem ursprünglichen Server zurück (auf dem Sie die Docker-Registrierung installiert haben) und rufen das Image auf, das wir gerade vom Client heruntergeladen haben. Sie können dies auch von einem dritten Server aus testen.

Wenn Docker nicht auf Ihrem Test-Pull-Server installiert ist, befolgen Sie die Installationsanweisungen (und, falls es sich um einen dritten Server handelt, die SSL-Anweisungen) aus Schritt 6.

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

docker login https://[YOUR-DOMAIN]

Und jetzt zieh das Bild. Sie möchten nur den Bildnamen "Tag", der den Domänennamen, den Port und den Bildnamen enthält (jedoch nichthttps://):

docker pull [YOUR-DOMAIN]/test-image

Docker lädt etwas herunter und bringt Sie zur Eingabeaufforderung zurück. Wenn Sie das Image auf dem neuen Computer ausführen, sehen Sie, dass sich die zuvor erstellte SUCCESS-Datei dort befindet:

docker run -t -i [YOUR-DOMAIN]/test-image /bin/bash

Listen Sie Ihre Dateien in der Bash-Shell auf:

ls

Sie sollten die DateiSUCCESSehen, die wir zuvor 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

Fazit

Herzliche Glückwünsche! Sie haben gerade Ihre eigene private Docker-Registrierung verwendet, um Ihren ersten Docker-Container zu pushen und zu ziehen!

Viel Spaß beim Andocken!