In dem Artikel “Microservice-Deployment ganz einfach mit Giant Swarm” habe ich die PaaS-Lösung Giant Swarm als Rundum-sorglos-Paket für das Deployment von Microservice-Anwendungen vorgestellt. In einem weiteren Artikel “Microservice-Deployment ganz einfach mit Kubernetes” habe ich vorgestellt, wie man mit Kubernetes einen Cluster aus Docker-Containern aufbauen kann. Heute möchte ich vorstellen, wie man eine Microservice-Anwendung mit Docker-Bordmitteln aufbauen kann, um eine Microservice-Anwendung auf einem Entwicklerrechner oder einer AWS-Instanz zu betreiben, was sehr praktisch ist, wenn man schnell eine Produktpräsentation oder einem Integrationstest durchführen möchte.
Docker baut ein internes Netzwerk für alle Container auf, in dem jeder Container eine eigene IP-Adresse bekommt. Die IP-Adresse kann mit docker inspect angezeigt werden. Um die verschiedenen Container miteinander zu verlinken, wird Port-Mapping eingesetzt. Das Linking-System von Docker ermöglicht es beliebig viele Container miteinander zu verlinken . Wenn Container miteinander verbunden sind, setzt Docker entsprechende Umgebungsvariablen in den Zielcontainern. In diesen sind IP-Adressen und Ports der anderen Containern enthalten. Wie das aussieht, kann man im folgenden Listing sehen:
1bz@cc $ docker ps
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
387bb5524067d zutherb/product-service:latest "/product-0.6/bin/pr 14 seconds ago Up 13 seconds 0.0.0.0:18080->18080/tcp compose_product_1
4bz@cc $ docker exec 87bb5524067d env
5PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
6HOSTNAME=87bb5524067d
7MONGODB_PORT_27017_TCP=tcp://172.17.0.28:27017
8MONGODB_PORT_27017_TCP_ADDR=172.17.0.28
9MONGODB_PORT_27017_TCP_PORT=27017
10MONGODB_PORT_27017_TCP_PROTO=tcp
Das folgende Listing zeigt die Verlinkung von vier Containern:
- einer mit einem Online-Shop,
- einer mit einem REST-basierten Warenkorb-Microservice,
- jeweils einer mit den Datenbanken MongoDB und
- Redis .
Für den Endbenutzer bedeutet das Verlinken von Containern das Ausführen mehrerer Docker-Kommandos.
1bz@cc ~$ docker run -d --name mongodb mongo
2705084daa3f852ec796c8d6b13bac882d56d95c261b4a4f8993b43c5fb2f846c
3bz@cc ~$ docker run -d --name redis redis
4784ebde0e867adb18663e3011b3c1cabe990a0c906396fc306eac669345628cf
5bz@cc ~$ docker run -d -P --name cart --link redis:redis zutherb/cart-service
6438b2657c7a5c733787fb32b7d28e1a0b84ba9e10d19a8a015c6f24085455011
7bz@cc ~$ docker run -d -P -p 8080:8080 --name shop --link cart:cart --link mongodb:mongodb zutherb/monolithic-shop
89926e187faa215ac9044603d51adbd8d679d8076b4a349ebbc9917dade6d560e
Wie man durch das vorherige Listing sieht, sind schon zum Erstellen von einfachen Anwendungen mehrere Kommandos nötig. Das folgende Verteilungsdiagramm lässt erahnen, wie kompliziert das Ganze mit einer wachsenden Zahl von Microservices wird. Es wäre doch schön, wenn man eine Möglichkeit hätte, um solche komplexen Deployment-Szenarien zu beschreiben.
Abhilfe schafft an dieser Stelle Docker Compose (früher Fig), mit dem sich ganze Microservice-Anwendungen in einer Datei beschreiben und mit einem einzelnen Kommando starten lassen. Hierfür definiert man alle Microservices einer Anwendung in einer docker-compose.yml Datei (früher fig.yml). Im folgenden Listing kann man die Beschreibung einer Online-Shop-Anwendung sehen, die man direkt auf jeden Rechner, auf dem Docker läuft, ausführen kann. Das komplette Beispiel findet sich auch in meinem GitHub-Repository :
1mongodb:
2 image: mongo
3 ports:
4 - "27017"
5redis:
6 image: redis
7 ports:
8 - "6379"
9checkout:
10 image: zutherb/monolithic-shop
11 ports:
12 - "8080"
13 links:
14 - mongodb
15 - cart
16product:
17 image: zutherb/product-service
18 ports:
19 - "18080"
20 links:
21 - mongodb
22navigation:
23 image: zutherb/navigation-service
24 ports:
25 - "18090"
26 links:
27 - mongodb
28cart:
29 image: zutherb/cart-service
30 ports:
31 - "18100"
32 links:
33 - redis
34catalog:
35 image: zutherb/catalog-frontend
36 ports:
37 - "80:80"
38 links:
39 - product
40 - navigation
41 - cart
42 - shop
Letztlich kann man mit dieser docker-compose.yml Datei und dem Kommando docker-compose up die komplette Umgebung starten. Das Konsolen-Programm docker-compose lässt sich sehr einfach mit Brew auf einem Mac installieren und es bietet Kommandos an, mit denen man den kompletten Lifecycle unserer Applikation steuern kann, wie z.B.:
- Start, Stop und Rebuild eine Services,
- Anzeigen der Stati der laufenden Services,
- Anzeigen der Logs der laufenden Services und
- An/Ausschalten von Services.
Im folgenden Listing sind die Phasen Starten und Stoppen des Online-Shop-Beispiels in der Shell zu sehen:
1bz@cc ~$ docker-compose up -d
2....
3bz@cc ~$ docker ps
4CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52730bad656eb zutherb/catalog-frontend:latest "dockerize -template 8 seconds ago Up 7 seconds 443/tcp, 0.0.0.0:80->80/tcp fig_catalog_1
63ba6e424506e zutherb/navigation-service:latest "/navigation-0.6/bin 10 seconds ago Up 8 seconds 0.0.0.0:18090->18090/tcp fig_navigation_1
7db169f173cef zutherb/monolithic-shop:latest "/sbin/my_init" 12 seconds ago Up 10 seconds 0.0.0.0:8080->8080/tcp fig_shop_1
84db1ae8b366e zutherb/cart-service:latest "/cart-0.6/bin/cart" 13 seconds ago Up 12 seconds 0.0.0.0:18100->18100/tcp fig_cart_1
9392fc3da4cfe zutherb/product-service:latest "/product-0.6/bin/pr 15 seconds ago Up 13 seconds 0.0.0.0:18080->18080/tcp fig_product_1
10fd0ed6323975 redis:latest "redis-server /etc/r 16 seconds ago Up 14 seconds 0.0.0.0:6379->6379/tcp fig_redis_1
11dbcbc99d4fb6 mongodb:latest "mongod" 17 seconds ago Up 16 seconds 28017/tcp, 0.0.0.0:27017->27017/tcp fig_mongodb_1
125efc445dbbbd dockerui/dockerui:latest "./dockerui" 19 seconds ago Up 17 seconds 0.0.0.0:9000->9000/tcp fig_dockerui_1
13bz@cc ~$ docker-compose stop
Betrachten wir einen praktischen Anwendungsfall für Docker Compose. Möchte man beispielsweise einen A/B Test vom Deployment her integrativ testen, ist es nötig zwei unterschiedliche Versionen einer Microservice-Umgebung auszuliefern. Es gibt verschiedene Möglichkeiten für das Deployment von A/B-Tests. Entweder man baut eine neue Version des Microservice und pusht diese entsprechend in eine öffentliche oder private Docker-Registry oder man steuert den Test mit Umgebungsvariablen, die dann bestimmte Feature Toggle s in der Applikation umschalten. Die folgenden Listings zeigen, wie diese beiden Alternativen in der docker-compose.yml Datei aussehen würden.
1#Alternative Version des Service
2catalog:
3 image: zutherb/catalog-frontend:latest-b
4 ports:
5 - "80:80"
6 links:
7 - product
8 - navigation
9 - cart
10 - checkout
1#Umgebungsvariable für die Steuerung von FeatureToggles
2catalog:
3 image: zutherb/catalog-frontend
4 ports:
5 - "80:80"
6 links:
7 - product
8 - navigation
9 - cart
10 - checkout
11 environment:
12 - CHECKOUT_DESIGN=amelia
Um das Deployment von unterschiedlichen Produkt-Konfigurationen mit Docker Compose zu verdeutlichen, habe ich das folgende Video erstellt, das noch fig als Kommando benutzt. Das fig-Kommando kann man jetzt einfach durch docker-compose ersetzen. Auch die Images wurden im dem Video schon vorher aus der zentralen Docker-Registry heruntergeladen. Deshalb sind die beiden Deployments von Variante A und Variante B recht schnell. Wenn man das Beispiel auf dem eigenen Rechner ausprobiert, müssen die Images noch aus der Docker-Registry heruntergeladen werden, das kann ein paar Minuten dauern. Das Beispiel selbst befindet sich in dem folgenden Github-Repository .
Mit dem Laden des Videos akzeptieren Sie die Datenschutzerklärung von YouTube.
Mehr erfahren
YouTube immer entsperren
Zusammenfassend kann man sagen, dass Docker Compose das Deployment einer Microservice-Anwendung stark vereinfacht, die aus mehreren auf einem Host zu deployenden Einzelservices besteht. Man erstellt einfach eine docker-compose.yml Datei, in der man die Verbindungen der einzelnen Docker-Containern definiert und kann mit dem Konsolen-Programm docker-compose eine komplette Microservice-Umgebung starten. Noch viel einfacher kann das Deployment von komplexen Microservice-Anwendungen kaum sein.
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Blog-Autor*in
Bernd Zuther
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.