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 Beiträge
von Bernd Zuther
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
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.