Freitag, 25. September 2015

Docker: Linking Container

Linking Containers together

Verbindung mit dem Container per Port-Mapping
    docker run -P training/webapp python app.py

bei der Verwendung des -P Flags wird der interne Port 5000 auf einen zufälligen Port nach draußen gemappt.
Alternativ kann man den zu verwendeten Port des Hostssystem selbst bestimmen:
     docker run -d -p 80:5000 training/webapp python app.py

Hier wird dem Container gesagt, dass er Port 5000 auf Port 80 des Hosts mappen soll.
Dann kann der Port noch dem localhosts zugewiesen werden:
     docker run -d -p 127.0.0.1:80:5000 training/webapp python app.py

Und eine UDP Connection kann ebenfalls hinzugefügt werden:
     docker run -d -p 127.0.0.1:80:5000/udp training/webapp python app.py
 

Linken von Containern

Ein anderer Mechanismus um zwei oder mehr Container miteinander zu verbinden, ist das Linken. Hierbei wird dem Empfänger-Container selektierte Informationen des Sender-Containers zur Verfügung gestellt. Bei der Verlinkung kommen die Container-Namen zum Einsatz. An dieser Stelle sei angemerkt, dass die Namen der Container ebenfalls personalisiert angelegt werden können, unter zu Hilfename des Flags --name. Das kann hilfreich sein, wenn man in einer Umgebung mit vielen Containern den Überblick behalten möchte und z.B. die Container nach ihrer Verwendung (web, db) benennt.
     docker run -d -P --name web training/webapp python app.py

Dabei ist zu beachten, dass Container-Namen eindeutig sind und nicht mehrfach verwendet werden können.
Bei der Verlinkung von Containern wird ein sicherer Kanal installiert, über den der Empfänger Container definierte Daten des Senders bekommen kann. Um eine Verlinkung zu installieren wird als erstes der Sender-Container gestartet. Laut der Anleitung bei Docker:
      docker run -d --name db training/postgres

Hierbei handelt es sich um einen Container der eine Datenbank beinhaltet. Als nächstes wird der Empfänger-Container gestartet, direkt mit der Verlinkung auf den Source-Container:
      docker run -d -P --name web --link db:db training/webapp python app.py

Hierbei wird dem --link Flag die Information des zu verlinkenden Containers in Form des Container-Namens oder der ID übergeben. Der Bezeichner hinter dem Doppelpunkt entspricht einem Alias des Source-Containers und kann optional verwendet werden. Mit der docker inspect Funktion können wir die Verlinkung prüfen:
      docker inspect -f "{{ .HostConfig.Links }}" web

Wird dort für unser Beispiel [/db:/web/db] angezeigt, war unsere Verlinkung erfolgreich.

Bei der Verlinkung wird ein sicherer Tunnel zwischen den Containern erzeugt, der keinerlei Öffnung zum Hostsystem benötigt. Es handelt sich um eine rein interne Verbindung -> keine Angriffsmöglichkeit von außen. Dabei werden die Verbindungsinformationen des Source-Containers für den Empfänger auf zwei verschiedene Weisen bereit gestellt:
  • über so genannte Environment Variablen
  • Aktualisierung der /etc/host/ files
Environment Variablen    
Docker kreiert verschiedene Umgebungsvariablen bei der Verlinkung von Containern im Zielsystem. Auch stellt Docker den Kontakt der Variablen auf beiden Systemen her. Die Environment Variablen enthalten die Variablen aus dem Aufruf des Containers mit dem ENV Befehl und den -e, -env und -envfile Optionen in Verbindung mit dem run-Befehl. Diese Variablen erlauben die programmatische Erkundung der Quelle von dem Empfänger. 
Dabei ist unbedingt zu beachten, dass die bereitgestellten Environment Variablen des Sender-Container ALLEN Containern bereit gestellt werden, die auf den Sender verlinkt werden. Der Sicherheitsaspekt bei sensiblen Daten ist an dieser Stelle unbedingt zu beachten

Die Variablen haben dabei folgende Syntax:
<Alias>_Name=xyz
<Alias>_Port_<Port>_<Protokoll>="Adresse"

Mit dem verwendeten Beispiel bei Docker in meinem Terminal sieht das ganze dann so aus:
$ docker run --rm --name web2 --link db training/webapp env

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=014e1dc9db99
DB_PORT=tcp://172.17.0.1:5432
DB_PORT_5432_TCP=tcp://172.17.0.1:5432
DB_PORT_5432_TCP_ADDR=172.17.0.1
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_NAME=/web2/db
DB_ENV_PG_VERSION=9.3
HOME=/root


Hinweis zu den Environment Variablen:
In der Datei /etc/hosts sind die Adressen des Hosts gespeichert. Beim Start des Sender-Containers werden diese Adressen nicht automatisch aktualisiert. Es wird daher empfohlen dieses nachzuholen, um die IP Adressen der verlinkten Container aufzulösen. Diese Variabelen werden nur bei der ersten Verbindung des Containers gesetzt. Einige sshd Dienste löschen diese Daten bei der Erzeugung der Shells für die Verbindungen aus.

Updating /etc/hosts Datei

Zusätzlich zu den Environment Variablen wird noch ein Hosteintrag in der /etc/hosts Datei des kreierten Containers vorgenommen. Das kann dann folgendermaßen aussehen:
  
~$ docker run -t -i --rm --link db:webdb training/webapp /bin/bash
root@a2722b55e736:/opt/webapp# cat /etc/hosts
172.17.0.2    a2722b55e736
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.1    webdb 210d92839224 db
172.17.0.1    db
172.17.0.1    db.bridge
172.17.0.2    condescending_fermat
172.17.0.2    condescending_fermat.bridge
root@a2722b55e736:/opt/webapp#


Docker schreibt zum einen die Lokalhost Adresse in das File. Es sind aber weitere wichtige Einträge ebenfalls dort zu finden: z.B die ID des verlinkten Containers und ebenfalls die Adresse unter der der Container mit dem Alias gelistet ist. Diese Adresse kann unter anderem dafür verwendet werden, um den verlinkten Container anzupingen.

Keine Kommentare:

Kommentar veröffentlichen