Kolumne: Docker rockt Java

Docker rockt Java: Docker Registry V2

Peter Roßbach
Docker für Java-Entwickler

© Software & Support Media

JAX-Speaker und Kolumnist Peter Roßbach ist zurück mit einer neuen Folge „Docker rockt Java.“ Dieses Mal geht es um die Neuimplementierung der Docker Registry, die vorgestellt und im Zusammenspiel mit dem Docker-Distribution-Projekt auf Herz und Nieren getestet wird.

Docker Registry V2

Die starke Auslastung des Docker Hub und steigende Anforderungen an die Registry haben es notwendig gemacht, das Design und die Implementierung der Docker Registry neu zu starten. Die neue Implementierung ist nun seit einigen Monaten verfügbar. Ein erster Blick auf die Möglichkeiten und den Status des neuen <a href=“https://github.com/docker/distribution“ target=“_blank“>Docker-Distribution-Projekts</a> lohnt sich.

DevOpsCon Whitepaper 2018

Free: BRAND NEW DevOps Whitepaper 2018

Learn about Containers,Continuous Delivery, DevOps Culture, Cloud Platforms & Security with articles by experts like Michiel Rook, Christoph Engelbert, Scott Sanders and many more.

Damit ein Registry V2 genutzt werden kann, muss mindestens eine Docker Engine im Release 1.6 vorliegen. Ältere Engines können nur mit einer Registry V1 sprechen. Damit die Docker Registry sowohl lokal als auch als Basis in der Cloud bzw. des Produkts Docker Hub Enterprise dienen kann, sind eine Reihen von Anforderungen umgesetzt worden. Das Projekt Docker Distribution besitzt eine austauschbare Storage-Komponente. Zurzeit werden das lokale Dateisystem, S3, Azure, Ceph-Rados, Openstack Shift und Aliyun-OSS unterstützt. Zum Monitoring der Registry können New Relic und Bugsnat angeschlossen werden. Die Metainformationen können in einer Redis-Datenbank zwischen mehreren Knoten ausgetauscht werden. TLS und Authentifikation werden nun direkt unterstützt. Für die Skalierung können auch mehrere Registrys hinter einem Proxy betrieben werden. Das Registry API ist komplett überarbeitet worden und die Implementierung erfolgt nun in der Programmiersprache GO (Abb. 1).

Abb. 1: Docker-Distribution

Abb. 1: Docker-Distribution

Lokale Docker-Distribution

Natürlich kann für einen Test oder den lokalen Betrieb die neue Registry V2 direkt als Docker Images geladen werden. Im Beispiel wird direkt eine eigene Docker Machine generiert. Wenn die Registry nur intern oder für einen Test betrieben wird, kann auf die verschlüsselte Kommunikation erst einmal verzichtet werden. Damit die Registry dann von einer Docker Engine akzeptiert wird, muss die unverschlüsselte Kommunikation explizit erlaubt werden (Listing 1). Im Beispiel wird dann zum Test das aktuelle Ubuntu 14.10 Docker Image geladen, mit einem Tag für die eigene Registry versehen und dann in der eigenen lokalen Registry gespeichert. Durch das aktive Entfernen des Images kann leicht überprüft werden, ob das lokale Ubuntu-Image von der eigenen Registry geladen werden kann und funktioniert.

$ docker-machine create -d virtualbox registry
$ docker-machine ssh registry
$ mkdir -p /var/lib/boo2docker/data
$ docker run -d --restart always \
 -p "5000:5000" \
-v /var/lib/boot2docker/data:/var/lib/registry registry:2

$ sudo vi /var/lib/boot2docker/profile
$ EXTRA_ARGS="--insecure-registry=127.0.0.1:5000"
$ sudo /etc/init.d/docker restart

$ docker pull ubuntu:14.10
$ docker tag ubuntu:14.10 127.0.0.1:5000/ubuntu:14.10
$ docker push 127.0.0.1:5000/ubuntu:14.10
$ docker rmi 127.0.0.1:5000/ubuntu:14.10 ubuntu:14.10
$ docker run --rm -ti 127.0.0.1:5000/ubuntu:14.10 echo hello

Eine schlanke Team-Registry erzeugen

Wenn nun die eigene Entwicklung im Team oder die automatischen Docker Image Builds der eigenen CI/CD Pipeline gespeichert werden, müssen einige weitere Eigenschaften berücksichtigt werden. Erst einmal sollte der Zugang sicherlich verschlüsselt und authentifiziert werden. Nicht vergessen werden sollte, dass eine Registry evtl. große Mengen an Speicherplatz und eine kontinuierliche Sicherung erfordert. Das Löschen eines Images ist zwar nun im REST-API endlich vorgesehen, aber es wird noch nicht vom Docker CLI Client unterstützt.

TLS-Zertifikate mit OpenSSL zu erzeugen, bzw. eine einfache eigene CA aufzusetzen, ist immer eine kleine Herausforderung. Netterweise gibt es nun im Projekt Shipyard einen Zertifikatsgenerator CERTM für diese Aufgabe (Listing 2). Mit diesem Werkzeug wird eine CA aufgesetzt und die notwendigen Schlüssel und das Serverzertifikat der Team-Registry werden erzeugt. Der Zugriff von einer Docker Engine kann nun erfolgen, indem das CA-Zertifikat hinterlegt wird. Wichtig ist, dass die IP-Adresse des Registry-Servers nun stabil bleibt. Leider ist bei der Verwendung von docker-machine mit Virtualbox oder den Cloud-Providern die Stabilität der IP-Adresse nicht garantiert. Also wechseln Sie im Fall einer durch das Internet zugänglichen Registry lieber auf ein Zertifikat einer kommerziellen „Certificate Authority“.

$ mkdir -p certs
$ docker run --rm -v $(pwd)/certs:/certs ehazlett/certm -d /certs ca generate -o=local
$ docker run --rm -v $(pwd)/certs:/certs ehazlett/certm -d /certs server generate --host localhost --host 127.0.0.1 —host $(docker-machine ip registry) -o=local
$ sudo mkdir -p /etc/docker/certs.d/:5000/
$ sudo cp ca.pem /etc/docker/certs.d/:5000/ca.crt
$ sudo /etc/init.d/docker restart

Damit nicht jeder auf die Registry zugreifen kann, ist es möglich, eine Authentifizierung zu konfigurieren. Für diesen Zweck bauen und generieren wir mit einem einfachen PWGEN-Container ein Passwort und erzeugen mit dem Werkzeug htpasswd aus dem Apache-httpd-Projekt eine Passwortdatei (Listing 3). Merken Sie sich das generierte Passwort unbedingt an einem sichereren Ort.

$ mkdir -p pwgen
$ cat >pwgen/Dockerfile <

Im nächsten Schritt wird das Registry HTTP Secret zur Koordination der Uploads generiert und ebenfalls gesichert. Nun werden die Dateien für die Zertifikate und Authentifikation beim Start der Registry übergeben. Dafür wird das Werkzeug docker-compose zur Definition der Parameter und zum Betrieb des Docker-Containers für die Registry genutzt. Das Geheimnis REGISTRY_HTTP_SECRET wird hier aus dem Aufruf-Environment von docker-compose automatisch übernommen.

Schnell kann so ein Oracle Java aus einem GitHub-Projekt lokal gebaut und in der nicht öffentlichen Registry bereitgestellt werden. Oracle Java darf nicht direkt oder als Basis einer Java-Anwendung öffentlich verbreitet werden, das schließt die aktuelle Oracle-Lizenz leider aus.

$ export REGISTRY_HTTP_SECRET=$(docker run --rm infrabricks/pwgen -B -s 32 1)
$ cat >docker-compose.yml <<EOF
registry:
  restart: always
  image: registry:2
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_SECRET:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/server.crt
    REGISTRY_HTTP_TLS_KEY: /certs/server-key.pem
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: Infrabricks Registry Realm
  volumes:
    - ./data:/var/lib/registry
    - ./certs:/certs
    - ./auth:/auth
EOF
$ docker-compose up -d
$ docker build -t registry:5000/java:8-jdk-ocrale \
  -f 8/jdk/Dockerfile \
  github.com/anapsix/docker-alpine-java
$ docker run --rm <registry-ip>:5000/java:8-jdk-ocrale java —version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
$ docker login --username master --password $PW --email xx@example.com
$ docker push <registry-ip>:5000/java:8-jdk-ocrale
$ docker run --rm <registry-ip>:5000/java:8-jdk-ocrale java —version

Mehr geht immer …

Natürlich ist es möglich, einen HTTP-Proxy mit nginx oder Apache httpd vor die Registry zu installieren und dann gleich auf eine oder mehrere Registry-Instanzen zu verteilen. Allerdings müssen alle Instanzen dann auf denselben Storage und Metaindex auf der Basis von Redis zugreifen. Lokal kann das mit dem Ceph Rados oder Openstack-Shift-Speicher konfiguriert werden. Meist kommt aber in einer solchen Konfiguration AWS S3- oder Azure-Storage zum Einsatz. S3 kann auch noch in der Kombination mit der Middleware CloudFront zusammen betrieben werden. Alternativ können Registrys als Service angemietet werden. Wem die Möglichkeiten der Projekt-Docker-Distribution zu eingeschränkt oder der Betrieb zu manuell erscheinen, der greift vielleicht besser auf die kommerziellen Registry-Projekte Docker Hub Enterprise oder Artifactory 4 PRO zurück.

Fazit

Das Projekt Docker-Distribution ist im aktuellen Status nicht stabil in der Lage, einen Mirror für den Docker-Hub bereitzustellen. In meinen Tests reichen wenige Pull-Anfragen aus, und der Dienst wird instabil. Noch existiert für eine private Registry kein Search API. Das vorhandene Search API der öffentlichen Registry ist vermutlich deshalb ebenfalls unzureichend. Mit Docker 1.8 können, auf der Basis des Projekts Docker Notary, Images signiert und vom Konsument verifiziert werden. Leider steht diese Komponente noch nicht für eine private Registry zur Verfügung. Weitere Instrumente zur Autorisierung und Verwaltung der Images fehlen noch, bzw. sind nur in kommerziellen Produkten umgesetzt.

Geschrieben von
Peter Roßbach
Peter Roßbach
Peter Roßbach ist ein Infracoder, Systemarchitekt und Berater vieler Websysteme. Sein besonderes Interesse gilt dem Design und der Entwicklung von komplexen Infrastrukturen. Er ist Apache Tomcat Committer und Apache Member. Mit der bee42 solutions gmbh realisiert er Infrastrukturprodukte und bietet Schulungen auf der Grundlage des Docker-Ökosystems, aktuellen Webtechnologien, NoSQL-Datenbanken und Cloud-Plattformen an.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: