Übung 6
Netzwerk Grundlagen
- 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:
ifconfigzeigt 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
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:
- 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:
apt update
apt install iputils-ping
Anschliessend wird ubuntu_2 angepingt
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
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