Beliebte Suchanfragen
//

Microservice-Deployment ganz einfach mit Docker Compose

10.5.2015 | 5 Minuten Lesezeit

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.

Verteilungsdiagramm eines Online-Shop mit Docker

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

Video laden

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.

Beitrag teilen

//

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.