Zum Hauptinhalt springen

Übung 6

Netzwerk Grundlagen

vorsicht
  • Diese Übung wurde hinzugefügt, die Nummerierung verschiebt sich!
  • Euere Kopie vom excercises Repository ist bestimmt hinten nach.
  • Ordner Uebung06 nach Uebung07 und Uebung07 nach Uebung08 umbenennen.

Hier geht es darum wie mehrere Dockercontainer untereinander kommunizieren können. Beispielsweise muss ein Web-Container mit einem Datenbank-Container kommunizieren können und an seine Daten zu kommen.

Der Befehl

docker network ls

zeigt die vorhandenen Netzwerke an.

vmadmin@ubuntu:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
65593a9ebb3b bridge bridge local
364521a9eaa2 host host local
c69c18f0a974 none null local

Standardnetzwerk

Das Netzwerk mit dem Namen bridge ist das Standardnetzwerk und wird verwendet, wenn nichts anderes angegeben wird. Die Netzwerkarchitektur lässt sich wie folgt darstellen:

!!!bild!!!

1.7.1 Abb. 1: Bridge Netzwerk

Wir wollen diese Architektur nun nachvollziehen: Die Ausgabe von ifconfig auf dem Host zeigt unter anderem das docker0 interface an:

info
  • ifconfig zeigt nur auf Linux docker0 an.
  • Unter MacOs (und wahrscheinlich auch Windows) ist es abstrahiert.
vmadmin@ubuntu:~$ ifconfig
...
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:f5ff:fe1c:4929 prefixlen 64 scopeid 0x20<link>
ether 02:42:f5:1c:49:29 txqueuelen 0 (Ethernet) ...

Dort erkennt man die private Klasse B Schnittstelle, mit Namen docker0 und der IP-Adresse 172.17.0.1. Diese Schnittstelle dient den Containern als Gateway.

Wir starten nun einen Ubuntu-Container. Dabei wird interaktiv (-it) eine Bash-Shell im Container geöffnet:

docker run -it --name ubuntu_1 ubuntu:latest

Der Container lässt sich mit exit beenden und kann mit folgendem Befehl wieder neu gestartet werden.

docker start -i ubuntu_1

In einer zweiten Konsole kann nun das Kommando

docker network inspect bridge

ausgeführt werden:

docker network inspect bridge
[
{
"Name": "bridge",
"Id": "65593a9ebb3b25cb368166ff8dc0f3556cd5edf29cbc88286fc38dfa5068594c",
"Created": "2022-06-25T07:03:44.321727785+02:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [{ "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" }]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": { "Network": "" },
"ConfigOnly": false,
"Containers": {
"5fe8760946479f29c3b59470a7a7a23e80ea8c0689f04d1fa4d40c5f668b51c8": {
"Name": "ubuntu_1",
"EndpointID": "194b76a3cd7a3360c054ad752a322822bf122d1544fd3266b49e55e116eda643",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]

Hier erkennt man die Definition des Klasse B Netzwerkes 172.17.0.0/16 und die IP-Adresse des Containers ubuntu_1

Eigene Netzwerke

Alle Container landen standardmässig im selben Netzwerk, dem bridge-Netzwerk. Dies ist aus sicherheitstechnischen Gründen nciht ideal, wenn unterschiedliche Anwendungen voneinander isoliert sein sollen. Es lassen sich deshalb eigene Netzwerke definieren und diese den Containern zuordnen.

docker network create \
--driver=bridge \
--subnet=10.10.10.0/24 \
--gateway=10.10.10.1 \
my_net

Überprüfen mit

docker network ls
Ausgabe
NETWORK ID   NAME   DRIVER SCOPE
65593a9ebb3b bridge bridge local
364521a9eaa2 host host local
// highlight-next-line
049d1ccb15e7 my_net bridge local

ifconfig zeigt die neue Schnittstelle an:

info
  • nur auf Linux!
ifconfig
...
br-049d1ccb15e7: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.10.10.1 netmask 255.255.255.0 broadcast 10.10.10.255
ether 02:42:88:5d:17:1e txqueuelen 0 (Ethernet)
...

Ein Container kann nun beim Start diesem Netzwerk zugeordnet werden:

docker run -it --name ubuntu_2 --network=my_net ubuntu

und

docker network inspect my_net

zeigt die IP-Adresse des neuen Containers

docker network inspect my_net
...
"Config": [
{
"Subnet": "10.10.10.0/24",
"Gateway": "10.10.10.1"
...
"Containers": {
"8848cacd27a445a7805e34bed6542c21535aa5e7cbb370e4cae7e26cd7d19f15": {
"Name": "ubuntu_2",
"EndpointID": "1bf43446a8b4a23efb6af2780556fa5566a7e18c09c189b97341dedfa1f474b0",
"MacAddress": "02:42:0a:0a:0a:02",
"IPv4Address": "10.10.10.2/24",
...

Die IP-Adresse für den Container wird dabei von docker via DHCP aus dem definierten Netzwerk vergeben. Alternativ kann eine fixe IP-Adresse beim Start des Containers angegeben werden.

docker run -it --name ubuntu_2 --ip="10.10.10.10" --network=my_net ubuntu

Als Nächstes soll der weiter oben dem Netzwerk bridge zugeordnete Container ubuntu_1 dem Netzwerk my_net zugeordnet werden. Dazu trennen wir ihn zuerst von bridge mit

docker network disconnect bridge ubuntu_1

anschliessend wird er zu my_net hinzugefügt und neu gestartet

docker network connect my_net ubuntu_1
docker start -i ubuntu_1

docker inspect zeigt nun beide Container an:

docker network inspect my_net
...
"Containers": {
"5fe8760946479f29c3b59470a7a7a23e80ea8c0689f04d1fa4d40c5f668b51c8": {
"Name": "ubuntu_1",
"EndpointID": "9212735dd2214ab7fa18fadc13a7bac348582e1ddd7d0d70ee9f58f308271000",
"MacAddress": "02:42:0a:0a:0a:03",
"IPv4Address": "10.10.10.3/24",
"IPv6Address": ""
},
"8848cacd27a445a7805e34bed6542c21535aa5e7cbb370e4cae7e26cd7d19f15": {
"Name": "ubuntu_2",
"EndpointID": "1bf43446a8b4a23efb6af2780556fa5566a7e18c09c189b97341dedfa1f474b0",
"MacAddress": "02:42:0a:0a:0a:02",
"IPv4Address": "10.10.10.2/24",
"IPv6Address": ""
}

...

Um zu überprüfen, ob die beiden Container tatsächlich miteinander kommunizieren können, installieren wir auf ubuntu_1 das Paket iputils-ping:

Terminal im Container ubuntu_1
apt update
apt install iputils-ping

Anschliessend wird ubuntu_2 angepingt

Terminal im Container ubuntu_1
root@5fe876094647:/# ping 10.10.10.2
PING 10.10.10.2 (10.10.10.2) 56(84) bytes of data.
64 bytes from 10.10.10.2: icmp_seq=1 ttl=64 time=0.496 ms ...

Dabei ist es nicht einmal nötig die IP-Adresse von ubuntu_2 zu kennen, da man auch den Namen direkt verwenden kann

Terminal im Container ubuntu_1
root@5fe876094647:/# ping ubuntu_2
PING ubuntu_2 (10.10.10.2) 56(84) bytes of data.
64 bytes from ubuntu_2.my_net (10.10.10.2): icmp_seq=1 ttl=64 time=0.099 ms ...

Nachdem alle Container, die zu einem Netzwerk hinzugefügt wurden, gestoppt oder getrennt wurden, können Sie das Netzwerk mit folgendem Befehl löschen:

docker network rm my_net

Quelle