Netzwerk zwischen KVM-VM und Docker-Container auf demselben Host

8

Auf einem Debian-Stretch-Host (verbunden mit einem physischen LAN) habe ich eine neue Docker-Installation (v18.09) mit einem Datenbankcontainer (dem Host zugeordneter Port) und führe KVM / libvirt mit einigen Debian-Stretch-VMs aus. Ich kann über das LAN auf den Docker-Container und die VMs zugreifen (abhängig von der Konfiguration über den SSH-Tunnel oder direkt), habe jedoch Probleme, über die VMs auf den Docker-Container zuzugreifen.

Geben Sie hier die Bildbeschreibung ein

# brctl show
bridge name         bridge id           STP enabled interfaces
br-f9f3ccd64037     8000.0242b3ebe3a0   no      
docker0             8000.024241f39b89   no      veth35454ac
virbr0              8000.525400566522   yes     virbr0-nic

Nachdem ich tagelang gelesen hatte, fand ich in diesem Beitrag eine sehr überzeugende Lösung Docker und KVM mit einer Brücke ( Original ), die ich nicht zur Arbeit brachte. Die Lösung schlägt vor, Docker mit einem einzeiligen Konfigurationscode daemon.json zu initiieren, um die KVM-Standardbrücke zu verwenden. Wie schön wäre das! Gibt es Hoffnung?

Ich habe zwei verschiedene Konfigurationen für die Vernetzung zwischen den KVM-VMs ausprobiert. In beiden Fällen ist die Kommunikation zwischen den VMs und der LAN + Router + Cloud einwandfrei, aber ich weiß einfach nicht, wie ich über den Zaun kommen soll - zum grüneren Gras ... :)

Conf 1 - KVM-Standardbrücke mit NAT: Ich kann ssh zum Debian-Host und auf den Docker-Container-Port zugreifen, aber gibt es ein Setup mit einer direkten Route?

Conf 2 - Macvtap-Adapter im Bridge-Modus zum LAN: Ich kann die Host-LAN-IP nicht von der VM aus anpingen, obwohl beide mit demselben Router verbunden sind. Die Antwort von der VM selbst lautet Destination Host Unreachable. Irgendwelche Gedanken warum?

Wäre es besser, den Docker-Daemon in einer separaten VM auszuführen, als direkt auf dem Debian-Host? Auf diese Weise können sowohl der Container als auch die VM auf die KVM-Standardbrücke zugreifen. Aber ich fand es etwas seltsam, Docker in einer VM auf einem KVM-Host auszuführen.

Jede klare Anleitung wäre dankbar!

Übrigens ist die Bridge br-f9f3ccd64037eine benutzerdefinierte Bridge, die ich mit Docker für die zukünftige Kommunikation zwischen Containern erstellt habe. Es wird nicht verwendet.

Aktualisieren:

Ich habe gerade festgestellt, dass ich mit der ersten Konfiguration einfach über die IP-Adresse (172.17.0.2) der VM-Gäste eine Verbindung zum Docker-Container herstellen kann.

Meine anfängliche Einrichtung war die zweite Konfiguration, da ich RDP in die VMs einbauen wollte. Dies ist einfacher, da der Macvtap-Treiber die VMs direkt mit dem LAN verbindet und keine SSH-Verbindung erforderlich ist. Dann konnte ich den Container nicht erreichen.

sdittmar
quelle

Antworten:

3

Die Lösung war so einfach wie im verlinkten Artikel angegeben. Ich bin nicht sicher, warum sich meine Konfiguration beim ersten Neustart des Docker-Daemons nicht geändert hat.

Nachdem ich in der Docker-Daemon-Dokumentation Beweise für das Bridge-Argument in daemon.json gefunden hatte, versuchte ich es erneut und der Docker-Daemon nahm beim Start die KVM-Standardbrücke auf.

Zuerst habe ich die Konfigurationsdatei /etc/docker/daemon.jsonwie in der Dokumentation vorgeschlagen mit folgendem Inhalt erstellt (die Zeile iptables wird möglicherweise nicht einmal benötigt):

{
"bridge": "virbr0",
"iptables": false
}

alles was benötigt wurde war:

docker stop mysql
systemctl stop docker
systemctl start docker
docker start mysql

Und der vorhandene Docker-Container lief auf der KVM-Brücke. Die IP-Adresse des Containers kann überprüft werden mit:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql
192.168.122.2

Ich bin nicht sicher, ob ich die Docker0-Bridge jetzt entfernen kann, aber der Container wird zusammen mit den drei VMs unter virbr0 aufgelistet.

brctl show
bridge name bridge id           STP enabled interfaces
docker0     8000.024241f39b89   no      
virbr0      8000.068ff2a4a56e   yes         veth2abcff1
                                            virbr0-nic
                                            vnet0
                                            vnet1
                                            vnet2
sdittmar
quelle
Ich habe dies versucht, aber nach dem Neustart nicht funktioniert, da ich wollte, dass Docker-Container die IP des Haupthosts haben und nicht wie die VMs eine neue vom Netzwerk erhalten. Es gab hier einige weitere Informationen bbs.archlinux.org/viewtopic.php?id=233727 . Das Beste, was ich tun kann, ist, Docker nach Abschluss des Startvorgangs zu starten, nicht als Dienst in systemd - dann funktioniert alles für mich, ist aber nicht ideal.
Richard
Ich habe gerade eine andere Debian-Box eingerichtet und es hat wieder bei mir funktioniert. Am besten überprüfen Sie die Konfiguration mit docker network inspect bridge. Wenn die json-config-Datei nicht funktioniert, liegt dies möglicherweise daran, dass in den Dokumenten Folgendes angegeben ist: "Hinweis: Sie können in daemon.json keine Optionen festlegen, die bereits beim Start des Daemons als Flag festgelegt wurden."
Sdittmar
2

Ich bin es gewohnt, dies mit dem folgenden Setup zu implementieren:

  • Ich schaffe eine br0Brücke mit dem physischen Nizza im Inneren

  • kvm-maschinen werden über das unten stehende qemu xml config snippet auf der brücke verbunden

    <interface type='bridge'>
      <mac address='52:54:00:a9:28:0a'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
  • Docker-Stacks laufen alle gleich: Ich reserviere für jeden Stack eine öffentliche routbare IP. Ich verbinde diese öffentliche IP mit der Bridge br0über das unten stehende Konfigurations-Snippet des opensvc-Dienstes.

    • In diesem [ip#0]Abschnitt wird angegeben, dass die IP- 1.2.3.4Adresse in dem Container mit der Ressourcen-ID konfiguriert werden soll, bei container#0der es sich um ein Docker-Google / Pause handelt und die mit Bridge verbunden istbr0

    • Alle anderen Docker im Stack erben die Netzwerkkonfiguration container#0aufgrund der Konfiguration netns = container#0in der Docker-Deklaration

    • Wenn der opensvc-Dienst gestartet wird, wird die Netzwerkeinrichtung vom Agenten durchgeführt, wobei alle in den folgenden Protokollen angegebenen Befehle erstellt werden

opensvc service configuration

[DEFAULT]
docker_daemon_args = --log-opt max-size=1m --storage-driver=zfs --iptables=false
docker_data_dir = /{env.base_dir}/docker
env = PRD
nodes = srv1.acme.com srv2.acme.com
orchestrate = start
id = 4958b24d-4d0f-4c30-71d2-bb820e043a5d

[fs#1]
dev = {env.pool}/{namespace}-{svcname}
mnt = {env.base_dir}
mnt_opt = rw,xattr,acl
type = zfs

[fs#2]
dev = {env.pool}/{namespace}-{svcname}/docker
mnt = {env.base_dir}/docker
mnt_opt = rw,xattr,acl
type = zfs

[fs#3]
dev = {env.pool}/{namespace}-{svcname}/data
mnt = {env.base_dir}/data
mnt_opt = rw,xattr,acl
type = zfs

[ip#0]
netns = container#0
ipdev = br0
ipname = 1.2.3.4
netmask = 255.255.255.224
gateway = 1.2.3.1
type = netns

[container#0]
hostname = {svcname}
image = google/pause
rm = true
run_command = /bin/sh
type = docker

[container#mysvc]
image = mysvc/mysvc:4.1.3
netns = container#0
run_args = -v /etc/localtime:/etc/localtime:ro
    -v {env.base_dir}/data/mysvc:/home/mysvc/server/data
type = docker

[env]
base_dir = /srv/{namespace}-{svcname}
pool = data

Startprotokoll

2019-01-04 11:27:14,617 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - checking 1.2.3.4 availability
2019-01-04 11:27:18,565 - srv1.acme.com.appprd.mysvc.fs#1 - INFO - mount -t zfs -o rw,xattr,acl data/appprd-mysvc /srv/appprd-mysvc
2019-01-04 11:27:18,877 - srv1.acme.com.appprd.mysvc.fs#2 - INFO - mount -t zfs -o rw,xattr,acl data/appprd-mysvc/docker /srv/appprd-mysvc/docker
2019-01-04 11:27:19,106 - srv1.acme.com.appprd.mysvc.fs#3 - INFO - mount -t zfs -o rw,xattr,acl data/appprd-mysvc/data /srv/appprd-mysvc/data
2019-01-04 11:27:19,643 - srv1.acme.com.appprd.mysvc - INFO - starting docker daemon
2019-01-04 11:27:19,644 - srv1.acme.com.appprd.mysvc - INFO - dockerd -H unix:///var/lib/opensvc/namespaces/appprd/services/mysvc/docker.sock --data-root //srv/appprd-mysvc/docker -p /var/lib/opensvc/namespaces/appprd/services/mysvc/docker.pid --exec-root /var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec --log-opt max-size=1m --storage-driver=zfs --iptables=false --exec-opt native.cgroupdriver=cgroupfs
2019-01-04 11:27:24,669 - srv1.acme.com.appprd.mysvc.container#0 - INFO - docker -H unix:///var/lib/opensvc/namespaces/appprd/services/mysvc/docker.sock run --name=appprd..mysvc.container.0 --detach --hostname mysvc --net=none --cgroup-parent /opensvc.slice/appprd.slice/mysvc.slice/container.slice/container.0.slice google/pause /bin/sh
2019-01-04 11:27:30,965 - srv1.acme.com.appprd.mysvc.container#0 - INFO - output:
2019-01-04 11:27:30,965 - srv1.acme.com.appprd.mysvc.container#0 - INFO - f790e192b5313d7c3450cb257d075620f40c2bad3d69d52c8794eccfe954f250
2019-01-04 11:27:30,987 - srv1.acme.com.appprd.mysvc.container#0 - INFO - wait for up status
2019-01-04 11:27:31,031 - srv1.acme.com.appprd.mysvc.container#0 - INFO - wait for container operational
2019-01-04 11:27:31,186 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - bridge mode
2019-01-04 11:27:31,268 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link add name veth0pl20321 mtu 1500 type veth peer name veth0pg20321 mtu 1500
2019-01-04 11:27:31,273 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pl20321 master br0
2019-01-04 11:27:31,277 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pl20321 up
2019-01-04 11:27:31,281 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pg20321 netns 20321
2019-01-04 11:27:31,320 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /usr/bin/nsenter --net=/var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec/netns/fc2fa9b2eaa4 ip link set veth0pg20321 name eth0
2019-01-04 11:27:31,356 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /usr/bin/nsenter --net=/var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec/netns/fc2fa9b2eaa4 ip addr add 1.2.3.4/27 dev eth0
2019-01-04 11:27:31,362 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /usr/bin/nsenter --net=/var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec/netns/fc2fa9b2eaa4 ip link set eth0 up
2019-01-04 11:27:31,372 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /usr/bin/nsenter --net=/var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec/netns/fc2fa9b2eaa4 ip route replace default via 1.2.3.1
2019-01-04 11:27:31,375 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /usr/bin/nsenter --net=/var/lib/opensvc/namespaces/appprd/services/mysvc/docker_exec/netns/fc2fa9b2eaa4 /usr/bin/python3 /usr/share/opensvc/lib/arp.py eth0 1.2.3.4
2019-01-04 11:27:32,534 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - docker -H unix:///var/lib/opensvc/namespaces/appprd/services/mysvc/docker.sock run --name=appprd..mysvc.container.mysvc -v /etc/localtime:/etc/localtime:ro -v /srv/appprd-mysvc/data/mysvc:/home/mysvc/server/data --detach --net=container:appprd..mysvc.container.0 --cgroup-parent /opensvc.slice/appprd.slice/mysvc.slice/container.slice/container.mysvc.slice mysvc/mysvc:4.1.3
2019-01-04 11:27:37,776 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - output:
2019-01-04 11:27:37,777 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - 1616cade9257d0616346841c3e9f0d639a9306e1af6fd750fe70e17903a11011
2019-01-04 11:27:37,797 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - wait for up status
2019-01-04 11:27:37,833 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - wait for container operational
Chaoxiang N.
quelle
Vielen Dank für Ihre Antwort! Ich bin nicht mit opensvc vertraut und ich muss eine Weile auf Ihren Vorschlag kauen ... Auch für eine Verbindung zwischen KVM und Docker würde ich eine physische Verbindung benötigen, die mit der Brücke verbunden ist? Abgesehen von der Nic unterscheidet sich Ihre Bridge von der KVM-Standardbrücke virbr0?
Sdittmar
Sie sollten in Ihrem Fall keine physische NIC in der Brücke benötigen. Soweit ich weiß, kein Unterschied zu kvm virbr0. Sie haben es vielleicht verpasst, aber in meinem Setup sind keine Docker- und Iptables-Zaubersachen erforderlich. einfach zu beheben!
Chaoxiang N
Wenn ich OpenSVC betrachte, habe ich nur das Gefühl, dass ich mit einem Vorschlaghammer eine Nuss knacke ... obwohl es wirklich interessant ist ...
sdittmar
0

Als ich die Frage las, suchte ich nach einer Möglichkeit, eine Verbindung virbr0zu einem Docker-Netzwerk herzustellen. Das Bild unten ist meine Modifikation dessen, was meiner Meinung nach gefragt wurde:

Geben Sie hier die Bildbeschreibung ein

In diesem Fall besteht die Antwort darin, ein macvlanNetzwerk zu verwenden, mit dem Sie ein Docker-Netzwerk direkt an ein Hostgerät anschließen können. So etwas wie das Folgende würde Ihnen das bringen, was Sie wollen:

docker network create --driver=macvlan --subnet=192.168.0.0/16 -o parent=virbr0 mynet

Agricola
quelle