Docker 1.12 Swarm mode mit PHP und Nginx in der Praxis

Ausgehend vom ersten Beispiel der Docker Services aus dem Blog-Beitrag von Docker selbst, habe ich mich gefragt, wie eine klassische PHP-Anwendung als Docker-Service aussehen würde. Einer kurzen Einführung in die neuen Docker-Services habe ich im letzten Beitrag einen Abschnitt gewidmet, der folgende Text geht davon aus, dass ein Docker Swarm im neuen Swarm mode erfolgreich eingerichtet wurde.

Ein erstes Beispiel

Eines der neuen Features von Docker ist der eingebaute Load-Balancer. Dabei handelt es sich eigentlich um einen alten Bekannten, denn hier verwendet Docker den IPVS (IP Virtual Server) für so genanntes Layer-4-Switching, der sich seit ca. 15 Jahren im Linux-Kernel befindet. Das folgende Beispiel stammt somit direkt aus dem bereits zitierten Blog-Beitrag, der Swarm Cluster sieht wie folgt aus:

geschke@waren:~$ docker node ls
ID                           HOSTNAME               MEMBERSHIP  STATUS  AVAILABILITY  MANAGER STATUS
cbzv67j025owtpjhxv3my8dyd    schwerin.mushaake.org  Accepted    Ready   Active        Reachable
cfp7ajyrm1xnlrz1l3siup6qb *  waren.mushaake.org     Accepted    Ready   Active        Leader
ed558w0v3im5rfp53zqhrf4ps    rostock.mushaake.org   Accepted    Ready   Active        Reachable

Nun wird die “vote”-Anwendung gestartet, zunächst nur ein Task:

geschke@waren:~$ docker service create --name vote -p 8080:80 instavote/vote
a4sl6cj2nrrdu0hvvs51pfcvb

geschke@waren:~$ docker service ls
ID            NAME  REPLICAS  IMAGE           COMMAND
a4sl6cj2nrrd  vote  1/1       instavote/vote

geschke@waren:~$ docker service tasks vote
ID                         NAME    SERVICE  IMAGE           LAST STATE             DESIRED STATE  NODE
1gql8v8x9kbo702kqu21iwhpa  vote.1  vote     instavote/vote  Running 5 minutes ago  Running        waren.mushaake.org

Laut Beispiel müsste nun tatsächlich der Port 8080 auf allen beteiligten Nodes verfügbar sein und die Einstiegsseite der Anwendung darstellen. Tatsächlich ist genau dies der Fall, wie die nächsten Screenshots zeigen – gleichgültig auf welchen der Nodes man sich bewegt, die Antwort wird vom gleichen Container generiert.

Bildschirmfoto 2016-07-25 um 19.12.22

Bildschirmfoto 2016-07-25 um 19.12.44

Damit die Anwendung vollständig läuft, wäre zwar noch ein Overlay-Network und eine darüber ansprechbare Redis-Datenbank notwendig, dies ist aber hier vernachlässigbar.

Natürlich funktioniert das Scale-Kommando wie bereits gezeigt und erwartet:

geschke@waren:~$ docker service scale vote=3
vote scaled to 3

geschke@waren:~$ docker service tasks vote
ID                         NAME    SERVICE  IMAGE           LAST STATE              DESIRED STATE  NODE
1gql8v8x9kbo702kqu21iwhpa  vote.1  vote     instavote/vote  Running 11 minutes ago  Running        waren.mushaake.org
4z4ke4z52cz0xvb2c1gbs7a5e  vote.2  vote     instavote/vote  Running 50 seconds ago  Running        rostock.mushaake.org
74m3raezqrgizeuzoyk3tdsdp  vote.3  vote     instavote/vote  Running 50 seconds ago  Running        schwerin.mushaake.org

Nun befindet sich auf allen Nodes jeweils ein Task. Das Load-Balancing wird auch dahingehend fortgeführt, als dass bei einem Reload auf derselben URL zufällig einer der Container ausgewählt und angesprochen wird. Ob diese Strategie auch änderbar ist, konnte ich der bisherigen Dokumentation nicht wirklich entnehmen, auch der Unterschied der beiden möglichen “endpoint modes” “vip” (virtual IP) und “dnsrr” (DNS Round Robin) verlangt noch einige nähere Erläuterungen.

Ein Image für PHP-FPM

Insgesamt ist dieses eingebaute Load-Balancing-Feature schon ziemlich cool. Nun bringt die Beispiel-Anwendung alles mit bis auf die Datenbank, insofern “Backend” und “Frontend” in einem. Wie würde aber z.B. eine klassische PHP-Anwendung als Service aussehen? Aktuell wird häufig PHP als php-fpm-Prozess gestartet, während Nginx als Web-Server genutzt wird. Damit ist bereits eine grundsätzliche Verteilung möglich, so können durch Nginx etwa nicht nur PHP über den Unix-Socket auf dem lokalen Rechner angesprochen werden, sondern auch über IP auf weiteren Rechnern. Üblicherweise steht zuletzt noch eine Datenbank, etwa MySQL/MariaDB zur Verfügung, die ebenfalls wieder auf mehreren Nodes ansprechbar ist, sei es durch eine Master-Slave-Konfiguration oder wie bei Galera Cluster als gleichberechtigte Instanzen. Oder vielleicht lieber eine MongoDB als ReplicaSet verwenden? Die Möglichkeiten sind vielfältig, daher klammere ich den Aspekt der Datenbank hier zunächst aus.

Interessanter wird es bereits bei PHP-FPM. Davon ausgehend, dass Nginx und PHP-FPM in unterschiedlichen Containern laufen sollen, müssen für beide Services entsprechende Images generiert werden. Nun ist es jedoch nicht möglich, die PHP-Anwendung, insofern das Verzeichnis, in dem die PHP-Dateien enthalten sind, beim Definieren der Services und somit Start der Container als Volume hinzu zu mounten. Beim Weg per “docker run...“-Kommando war dies noch möglich, weil die Verbindung von Container zu Node viel enger war.

docker service create --name php -p 9000:9000 --volume /home/geschke/docker-php-fpm/test:/var/www/html geschke/php-fpm
unknown flag: --volume
See 'docker service create --help'.

Das funktioniert also nicht. Insofern müssen die PHP-Quelltexte im Image enthalten sein, was als Service gestartet werden soll. Als Basis-Image habe ich dafür zunächst ein minimales Image für PHP-FPM erstellt: php-fpm.

Zwar existieren etliche, auch offizielle Images für PHP, aber diese sind teilweise für einen sehr speziellen Einsatz oder aber so allgemein gehalten, dass die Konfiguration schwieriger zu verstehen ist als schnell ein minimales Image zu erstellen, was genau diejenigen Module beinhaltet, die man benötigt und noch dazu auf der gewohnten Linux-Distribution basiert.

Mit dem Image ist es auch möglich, ein Volume für den PHP-Quellcode hinein zu mounten, aber für die Verwendung als Service muss ein abgeleitetes Dockerfile erstellt werden. Dies sieht wie folgt aus:

FROM geschke/php-fpm

MAINTAINER Ralf Geschke <ralf@kuerbis.org>

LABEL last_changed="2016-07-23"

WORKDIR /var/www/html
COPY html/* /var/www/html/

EXPOSE 9000

CMD ["php-fpm7.0"]

Viel einfacher geht es nicht – der Inhalt des Verzeichnisses “html” wird in das Image nach /var/www/html/ kopiert. Zum Test befinden sich genau zwei Dateien darin, eine mit dem berühmten Aufruf von phpinfo(), die andere zeigt letztlich auch nur den Server-Namen an, denn dieser wird vom jeweils laufenden Container bzw. Task bestimmt, vgl. die “vote”-Anwendung aus dem Eingangsbeispiel:

[...]
    <p>Server name: <?php echo $_SERVER["SERVER_NAME"]; ?></p>
[...]

Also Image bauen und ins private Repository pushen, schließlich müssen derartige Tests nicht unbedingt auf dem Docker Hub landen:

geschke@connewitz:~/docker-php-test$ docker build -t phptestb .
geschke@connewitz:~/docker-php-test$ docker tag phptest hub.kuerbis.org:81/phptest
geschke@connewitz:~/docker-php-test$ docker push hub.kuerbis.org:81/phptest

Damit ist das Image namens “hub.kuerbis.org:81/phptest” nun auch erreichbar und kann herunter geladen werden. Vor dem ersten Test wird noch ein Overlay-Network angelegt, was zur Kommunikation zwischen den späteren Nginx-Services und den PHP-FPM-Services dienen soll:

geschke@connewitz:~/docker-php-test$ docker network create -d overlay gnswarm
ek325du00636j2xkpawrwwtf2

geschke@connewitz:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
31a05a5c9cae        bridge              bridge              local
812ea049842a        docker_gwbridge     bridge              local
ek325du00636        gnswarm             overlay             swarm
42212f4a4b9b        host                host                local
2jvt0k5zac46        ingress             overlay             swarm
c59912cd4ec8        none                null                local

Das sieht soweit gut aus, und die Ports 9000, auf denen PHP-FPM lauscht, sollen auch nicht nach außen freigegeben werden. Somit kann der Service gestartet werden:

geschke@connewitz:~/docker-php-test$ docker service create --name phpbackend --network gnswarm --replicas 5 hub.kuerbis.org:81/phptest
22skrcle9mp3pft93urukbv7w
geschke@connewitz:~/docker-php-test$ docker service ls
ID            NAME        REPLICAS  IMAGE                       COMMAND
22skrcle9mp3  phpbackend  1/5       hub.kuerbis.org:81/phptest

Das sieht soweit erfolgreich aus, doch befindet sich das Image in einem privaten Repository. Üblicherweise werden die Images automatisch auf den jeweiligen Nodes herunter geladen, sofern sie nicht bereits existieren. Wie sieht dies hier aus?

docker service tasks phpbackend
ID                         NAME          SERVICE     IMAGE                       LAST STATE                        DESIRED STATE  NODE
7k8femn25mjttty2tgkjariim  phpbackend.1  phpbackend  hub.kuerbis.org:81/phptest  Accepted 4 seconds ago            Accepted       kaditz
2fizbz7v0fy6z5ohe0uup5ifr  phpbackend.2  phpbackend  hub.kuerbis.org:81/phptest  Accepted 2 seconds ago            Accepted       miltitz
e0nuu90kkzpeu44z8d9nt0bil  phpbackend.3  phpbackend  hub.kuerbis.org:81/phptest  Running 51 seconds ago            Running        connewitz
e9unueuee9fj8428cmcbicv83  phpbackend.4  phpbackend  hub.kuerbis.org:81/phptest  Accepted 1 seconds ago            Accepted       tondi
e0utqt66rhs4ugsww8zu7jf1a  phpbackend.5  phpbackend  hub.kuerbis.org:81/phptest  Allocated less than a second ago  Accepted

Die Antwort lautet, dass die einzelnen Nodes zwar den Download versuchen, aber dabei zunächst scheitern. Der Status wechselt dabei auch auf “rejected”, da die Credentials für den Download zwar auf dem Client bekannt sind, von dem das Image in das private Repository gepusht wurde (Node “connewitz”), aber die anderen Nodes kennen die Zugangsdaten nicht. Daher werden die Tasks nicht erfolgreich gestartet.

Glücklicherweise hat Docker dafür einen Schalter vorgesehen, und zwar “--registry-auth“. Wird beim create-Kommando “--registry-auth” angegeben, werden die Credentials an die einzelnen Nodes weiter gegeben, so dass der Download erfolgreich stattfinden kann. Ich habe dies auch erst später bemerkt und beim Update verwendet, die ersten Versuche bestanden darin, das Image einzeln auf jeden Node zu laden, was bei einer gewissen Anzahl von Nodes eher suboptimal ist.

Und sobald die Images vorhanden sind, werden sie auch erfolgreich gestartet:

geschke@tondi:~$ docker service tasks phpbackend
ID                         NAME          SERVICE     IMAGE                       LAST STATE              DESIRED STATE  NODE
62ta97u1bryeacrr09x0ziyqu  phpbackend.1  phpbackend  hub.kuerbis.org:81/phptest  Running 14 seconds ago  Running        lindenau
0b5fx2mjfkcrhsrrifafww1rf  phpbackend.2  phpbackend  hub.kuerbis.org:81/phptest  Accepted 4 seconds ago  Accepted       tolkewitz
7l1tk47b3bygh8ijjc8f83og0  phpbackend.3  phpbackend  hub.kuerbis.org:81/phptest  Running 9 minutes ago   Running        tondi
a4duhf5dyed6rri25wpum87vd  phpbackend.4  phpbackend  hub.kuerbis.org:81/phptest  Running 15 seconds ago  Running        miltitz
4cjak7yqw7l655s4j8qns3hhc  phpbackend.5  phpbackend  hub.kuerbis.org:81/phptest  Running 14 minutes ago  Running        connewitz

Ein Image für Nginx

Um die Funktionalität des PHP-FPM-Services grundsätzlich zu testen, wollte ich zunächst auf klassischem Wege per “docker run...” einen Nginx-Container starten, der der zuvor angelegte Overlay-Network nutzt, um PHP-FPM auf Port 9000 zu erreichen. Auch für Nginx hatte ich mir vor einiger Zeit ein minimales Image gebaut, was auf Alpine Linux basiert, und mit dem es möglich ist, eine doch Ubuntu-ähnliche Konfiguration (Konfigurationsdateien für virtuelle Server in “sites-enabled” etc.) zu verwenden. Dabei werden beim bisherigen Weg die Konfigurationsdateien als Volume zur Laufzeit in den Container gemountet.

Nach Anpassung der Konfigurationsdateien der erste Versuch:

geschke@connewitz:~/docker-nginx/files$ docker run -d --name nginx --restart=always     -v /home/geschke/docker-nginx/sites-enabled:/etc/nginx/sites-enabled  -v /home/geschke/docker-nginx/www:/var/www   -v /home/geschke/docker-nginx/conf.d:/etc/nginx/conf.d     --publish 80:80 --net=gnswarm    geschke/nginx
docker: Error response from daemon: swarm-scoped network (gnswarm) is not compatible with `docker create` or `docker run`. This network can only be used by a docker service.
See 'docker run --help'.

Auf die klassische Art und Weise funktionierte dies also nicht. Insofern musste auch für Nginx bzw. dessen Konfiguration ein Image gebaut werden, was wiederum im privaten Repository Platz genommen hat.

Um es abzukürzen – die Konfiguration bestand aus einigen Versuchen per Trial-and-Error, hauptsächlich bedingt durch die jeweiligen Pfade, die bei Nginx und PHP-FPM verwendet werden. Nginx gibt z.B. die Angabe über das Document-Root-Verzeichnis an PHP-FPM weiter, so dass PHP seine Dateien darin finden kann. Denn sobald eine Datei mit der Endung “.php” genutzt wird, kommt auch PHP zum Einsatz. Statische Dateien hingegen können im Nginx-Image Platz nehmen, von dort aus werden sie direkt von Nginx beim Request ausgeliefert.

Das Dockerfile von Nginx sieht letztlich wie folgt aus:

FROM geschke/nginx

LABEL last_changed="2016-07-23"

MAINTAINER Ralf Geschke <ralf@kuerbis.org>

COPY files/nginx.conf /etc/nginx/
RUN mkdir -p /etc/nginx/sites-enabled && mkdir -p /var/www/html
COPY files/sites-enabled/* /etc/nginx/sites-enabled/
COPY files/www/* /var/www/html/


EXPOSE 80 443

CMD ["nginx"]

Im Verzeichnis files/sites-enabled befindet sich eine Datei namens “default”, die nicht viel anders ist als die Standard-Konfiguration für einen virtuellen Host:

server {
        listen 80;
        server_name _;

        root /var/www/html;
        index index.php index.html index.htm;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ /index.php;

        }


        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
        #       # With php5-cgi alone:
                fastcgi_pass phpbackend:9000;
        #       # With php5-fpm:
                #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                fastcgi_index index.php;
                include fastcgi.conf;
        }

}

Ebenfalls recht kurz gehalten ist die zentrale nginx.conf, die in das Image hinein kopiert wird:

# (Hinweis: Kommentare der Übersichtlichkeit halber entfernt)

worker_processes  4;
daemon off;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;



    sendfile        on;

    keepalive_timeout  65;

    gzip on;
    gzip_disable "msie6";


    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

}

In dem “files/www/“-Verzeichnis befindet sich nur eine statische HTML-Datei, um die direkte Auslieferung von Nginx zu testen. Die PHP-Dateien hingegen sind im PHP-FPM-Image “phptest” enthalten!

Also gebaut und gepusht:

geschke@connewitz:~/docker-nginx$ docker build -t nginxphp .
[...]
geschke@connewitz:~/docker-nginx$ docker tag nginxphp hub.kuerbis.org:81/nginxphp
geschke@connewitz:~/docker-nginx$ docker pull hub.kuerbis.org:81/nginxphp

Bei einem weiteren Versuch wollte ich den Nginx-Service nur auf dem (lokalen) Node “connewitz” starten. Dazu wurden so genannte Constraints genutzt, hier zur Einschränkung der Node-ID:

docker service create --name frontend -p 80:80/tcp --network gnswarm --constraint node.id==9r6mfzv4gflyafi9uwikaaqvf hub.kuerbis.org:81/nginxphp

Aus noch unbekannten Gründen war dies leider nicht erfolgreich, der Port 80 ließ sich auf dem betreffenden Node nicht ansprechen. Daher der neue Versuch, nun sollte Docker sich um die Verteilung der Tasks kümmern:

docker service create --name frontend -p 80:80/tcp --network gnswarm hub.kuerbis.org:81/nginxphp
b196ddilz9d645imr20we4b7z

geschke@connewitz:~/docker-nginx$ docker service ls
ID            NAME        REPLICAS  IMAGE                        COMMAND
9jxmteiyjk8k  phpbackend  5/5       hub.kuerbis.org:81/phptest
b196ddilz9d6  frontend    1/1       hub.kuerbis.org:81/nginxphp

geschke@connewitz:~/docker-nginx$ docker service tasks frontend
ID                         NAME        SERVICE   IMAGE                        LAST STATE              DESIRED STATE  NODE
b8j84fl6ga2hvnhmtblegqvnf  frontend.1  frontend  hub.kuerbis.org:81/nginxphp  Running 35 seconds ago  Running        miltitz

Der Task lief auf “miltitz” – und tatsächlich war die “Anwendung” nun auch erreichbar:

Bildschirmfoto 2016-07-25 um 21.11.24

 

Und auch die anderen Nodes waren erreichbar, einzig wechselte wiederum der Hostname, je nach dem, auf welcher PHP-FPM-Instanz man sich befand bzw. von welchem Task der Request verarbeitet wurde. Grundsätzlich also sehr, sehr cool!

Auch das Hinzufügen weiterer Tasks war möglich, ebenso konnte die Anzahl wieder verringert werden usw.:

geschke@connewitz:~/docker-php-test$ docker service scale frontend=3
frontend scaled to 3

geschke@connewitz:~/docker-php-test$ docker service ls
ID            NAME        REPLICAS  IMAGE                        COMMAND
9jxmteiyjk8k  phpbackend  5/5       hub.kuerbis.org:81/phptest
b196ddilz9d6  frontend    3/3       hub.kuerbis.org:81/nginxphp

Load-Balancing per DNS-Round-Robin

Eine (sehr) einfache Möglichkeit der Lastverteilung kann z.B. per DNS Round Robin erfolgen. Dabei werden einem Hostnamen mehrere IP-Adressen zugeordnet. Die grundlegende Funktionsweise beschreibt Wikipedia sehr gut, im Beispiel hatte ich den lokalen DNS so konfiguriert, dass alle Nodes mittels des Namens “swarm” ansprechbar sind:

swarm        IN A 192.168.10.72
swarm        IN A 192.168.10.73
swarm        IN A 192.168.10.39
swarm        IN A 192.168.10.64
swarm        IN A 192.168.10.66
swarm        IN A 192.168.10.65
swarm        IN A 192.168.10.43

Bei der DNS-Abfrage wird dieser Name aufgelöst, und bei mehreren Anfragen wechselt die Reihenfolge.

geschke@connewitz:~$ dig swarm.geschke.net

; <<>> DiG 9.10.3-P4-Ubuntu <<>> swarm.geschke.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59633
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 2, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;swarm.geschke.net.		IN	A

;; ANSWER SECTION:
swarm.geschke.net.	172800	IN	A	192.168.10.43
swarm.geschke.net.	172800	IN	A	192.168.10.39
swarm.geschke.net.	172800	IN	A	192.168.10.73
swarm.geschke.net.	172800	IN	A	192.168.10.72
swarm.geschke.net.	172800	IN	A	192.168.10.65
swarm.geschke.net.	172800	IN	A	192.168.10.64
swarm.geschke.net.	172800	IN	A	192.168.10.66
[...]

Für wirkliche Ausfallsicherheit müsste nun noch der DNS-Server so konfiguriert werden, dass je nach Verfügbarkeit der Nodes die Konfiguration angepasst wird. Später…

Nachtrag – scale up and down

Als ich während des Schreibens dieses Artikels ein wenig die laufenden Services modifiziert habe, d.h. die Anzahl der Tasks verringert, wieder erhöht usw., zeigte sich eine zeitweise Instabilität. So wurden bei manchen Nodes 502 “Bad gateway”-Fehler angezeigt, andere antworteten gar nicht. In der Netzwerk-Konfiguration von Docker bzw. den Services fand ich nichts Ungewöhnliches (“docker service inspect <service>”), und bis zur Analyse der Logfiles bin ich währenddessen nicht gekommen. Die genaue Ursache gilt es somit noch, herauszufinden, denn natürlich darf die erwünschte Eigenschaft der Ausfallsicherheit nicht zu Lasten der Stabilität gehen. Insofern bleibt noch einiger Raum für Analysen und Experimente…

Fazit

Grundsätzlich sind die Docker Services ein sehr gutes Feature, insbesondere das Load-Balancing, sofern es denn funktioniert, bietet eine relativ einfach konfigurierbare Lösung zur Herstellung von Ausfallsicherheit. Ich beziehe mich hier tatsächlich auf Ausfallsicherheit und nicht auf Skalierbarkeit. Denn um Letztere zu erreichen, müssen alle Systemkomponenten darauf ausgelegt sein, was jedoch nicht mit einem einzelnen “scale”-Kommando auf einer fest stehenden Anzahl von Nodes erreicht wird. Zwar können Nodes auch relativ einfach hinzugefügt werden, womit wiederum eine horizontale Skalierung erreicht würde, aber dazu muss erst einmal die entsprechende Infrastruktur bereit stehen.

Betrachtet man jedoch ein mit Docker Services aufgebautes System, was aus mehreren Nodes besteht, ist eine gewisse Ausfallsicherheit gegeben. Fälle ein Node aus, sorgt Docker dafür, dass die Tasks auf die noch vorhandenen Nodes verteilt werden.

Die Images müssen jedoch für den Betrieb als Service von vornherein ausgelegt sein. In diesem Sinn sind die Tasks der Services ein shared-nothing-System, sie kennen keinen gemeinsamen Speicherbereich, haben keinen Zugriff auf ein gemeinsames Dateisystem und müssen auch unabhängig voneinander in derselben Konfiguration lauffähig sein. Die Konfiguration muss daher ebenfalls entweder direkt in das Image gepackt werden oder als Umgebungsvariable mittels --env-Parameter übergeben werden können.

Dies wird bereits bei einfachen Features von Web-Anwendungen wie Uploads von Bildern etc. zu einer Herausforderung, auf die die Anwendung angepasst werden muss. Die Speicherung im Filesystem verbietet sich, insofern müsste ein gemeinsamer Speicher bzw. -Dienst wie AWS S3 genutzt werden, oder z.B. GridFS von MongoDB. Überhaupt stellen Datenbanken eine weitere Herausforderung dar. Dies beginnt bereits bei der Konfiguration, denn für den Aufbau etwa eines MariaDB-Galera-Clusters muss ein Image vorhanden sein, was von Initialisierung bis zu Betrieb einwandfrei ist, und wo sollen überhaupt die Daten gespeichert werden – verteiltes Dateisystem – oder doch besser auf Docker in diesem Umfeld verzichten? Und man muss ja auch nicht alles “dockerisieren”. Bei MongoDB funktioniert dies zwar auf dem klassischen Weg recht gut, aber auch das setzt einige Vorab-Konfiguration voraus. Und nicht zuletzt liegen die Daten auf den Hosts, von denen die Volumes in die Container gemountet werden. Um diese von einem Service-Task zu erreichen, müsste es jedoch ein gemeinsames Netz geben, oder man müsste mittels Firewall wiederum nur den Zugriff von außen verbieten…

Insofern – insgesamt gibt es noch etliche Baustellen, noch sind nicht alle Probleme gelöst oder Herausforderungen bewältigt. Und nicht zu vergessen, aktuell (Stand 25.07.2016) ist Docker 1.12 mit diesen neuen Features ja auch noch Release Candidate…

 

Ein Gedanke zu „Docker 1.12 Swarm mode mit PHP und Nginx in der Praxis“

  1. Danke für den Artikel!
    Ich beschäftige mich gerade genau mit dem Thema, da ich demnächst eine wohl sehr schnell waschsende Online Plattform betreiben werde.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Tags: