Creación de redes entre la máquina virtual KVM y el contenedor docker en el mismo host

En un host Debian-Stretch (conectado a una LAN física) tengo una nueva instalación de docker (v18.09) con un contenedor de base de datos (puerto asignado al host) y ejecuto KVM/libvirt con algunas máquinas virtuales Debian-Stretch. Puedo acceder al contenedor de la ventana acoplable y a las máquinas virtuales desde la LAN (dependiendo de la configuración a través del túnel SSH o directo), pero tengo problemas para acceder al contenedor de la ventana acoplable desde las máquinas virtuales.

enter image description here

# brctl showbridge name         bridge id           STP enabled interfacesbr-f9f3ccd64037     8000.0242b3ebe3a0   no      docker0             8000.024241f39b89   no      veth35454acvirbr0              8000.525400566522   yes     virbr0-nic

Después de leer durante días, encontré una solución muy convincente en esta publicación Docker y KVM con puente (original) que no llegué a trabajar. La solución sugiere iniciar docker con un demonio de configuración de una línea.código json para usar el puente KVM "predeterminado". Qué bonito sería! Hay alguna esperanza?

Probé dos configuraciones diferentes para la creación de redes entre las máquinas virtuales KVM. En ambos casos, la comunicación entre las máquinas virtuales y la LAN+el enrutador+la nube es impecable, pero simplemente no sé cómo superar la valla, hacia el césped más verde... :)

Conf 1-Puente predeterminado KVM con NAT: Puedo ssh al host Debian y acceder al puerto del contenedor docker, pero ¿hay una configuración con una ruta directa?

Conf 2-adaptador macvtap en modo Puente a la LAN: No puedo hacer ping a la IP de la LAN del host desde la máquina virtual, aunque ambas están conectadas al mismo enrutador. La respuesta de la propia máquina virtual es Destination Host Unreachable. ¿Alguna idea de por qué?

¿Sería mejor ejecutar el demonio docker en una máquina virtual separada en lugar de directamente en el host Debian? De esta forma, tanto el contenedor como la máquina virtual podrían acceder al puente KVM predeterminado. Pero pensé que es un poco extraño ejecutar docker en una máquina virtual en un host KVM.

Cualquier orientación clara sería apreciada!

Por cierto, el puente br-f9f3ccd64037 es un puente definido por el usuario que creé con docker para futuras comunicaciones entre contenedores. No se utiliza.

Actualizar:

Me acabo de dar cuenta de que con la primera configuración simplemente puedo conectarme al contenedor docker por su dirección IP (172.17.0.2) desde los invitados de la máquina virtual.

Mi configuración inicial fue la segunda configuración porque quería RDP en las máquinas virtuales, lo cual es más fácil ya que el controlador macvtap conecta las máquinas virtuales directamente a la LAN y no se necesita un enlace SSH. Fue entonces cuando no pude alcanzar el contenedor.

La solución fue tan simple como se indica en el artículo vinculado. No estoy seguro de por qué mi configuración no cambió la primera vez que reinicié el demonio docker.

Después de que encontré evidencia en el Documentación del demonio de Docker para el argumento bridge en daemon.sin embargo, le di otra oportunidad y el demonio docker recogió el puente predeterminado de KVM al inicio.

Primero creé el archivo de configuración /etc/docker/daemon.json como se sugiere en la documentación con el siguiente contenido (la línea de iptables puede que ni siquiera sea necesaria):

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

todo lo que se necesitaba era:

docker stop mysqlsystemctl stop dockersystemctl start dockerdocker start mysql

Y el contenedor docker existente se estaba ejecutando en el puente KVM. La dirección IP del contenedor se puede verificar con:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mysql192.168.122.2

No estoy seguro de poder eliminar el puente docker0 ahora, pero el contenedor aparece en virbr0 junto con las tres máquinas virtuales.

brctl showbridge name bridge id           STP enabled interfacesdocker0     8000.024241f39b89   no      virbr0      8000.068ff2a4a56e   yes         veth2abcff1                                            virbr0-nic                                            vnet0                                            vnet1                                            vnet2

Estoy acostumbrado a implementar eso usando la siguiente configuración :

  • Creo un br0 puente con la NIC física en el interior

  • las máquinas kvm se conectan en el puente utilizando el fragmento de configuración XML de qemu a continuación

    <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>
  • las pilas de docker se ejecutan de la misma manera : reservo una IP pública enrutable para cada pila. Conecto esta IP pública al puente br0 usando el fragmento de configuración del servicio opensvc a continuación.

    • el [ip#0] la sección dice que queremos la IP 1.2.3.4 configurado en el contenedor con id de recurso container#0 que es una ventana acoplable de google / pause y está conectada a Bridge br0

    • todos los demás dockers de la pila heredan la configuración de red de container#0 debido a la configuración netns = container#0 en la declaración de Docker

    • cuando se inicia el servicio opensvc, el agente realiza la configuración de la red, produciendo todos los comandos informados en los registros a continuación

configuración del servicio opensvc

[DEFAULT]docker_daemon_args = --log-opt max-size=1m --storage-driver=zfs --iptables=falsedocker_data_dir = /{env.base_dir}/dockerenv = PRDnodes = srv1.acme.com srv2.acme.comorchestrate = startid = 4958b24d-4d0f-4c30-71d2-bb820e043a5d[fs#1]dev = {env.pool}/{namespace}-{svcname}mnt = {env.base_dir}mnt_opt = rw,xattr,acltype = zfs[fs#2]dev = {env.pool}/{namespace}-{svcname}/dockermnt = {env.base_dir}/dockermnt_opt = rw,xattr,acltype = zfs[fs#3]dev = {env.pool}/{namespace}-{svcname}/datamnt = {env.base_dir}/datamnt_opt = rw,xattr,acltype = zfs[ip#0]netns = container#0ipdev = br0ipname = 1.2.3.4netmask = 255.255.255.224gateway = 1.2.3.1type = netns[container#0]hostname = {svcname}image = google/pauserm = truerun_command = /bin/shtype = docker[container#mysvc]image = mysvc/mysvc:4.1.3netns = container#0run_args = -v /etc/localtime:/etc/localtime:ro    -v {env.base_dir}/data/mysvc:/home/mysvc/server/datatype = docker[env]base_dir = /srv/{namespace}-{svcname}pool = data

registro de inicio

2019-01-04 11:27:14,617 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - checking 1.2.3.4 availability2019-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-mysvc2019-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/docker2019-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/data2019-01-04 11:27:19,643 - srv1.acme.com.appprd.mysvc - INFO - starting docker daemon2019-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=cgroupfs2019-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/sh2019-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 - f790e192b5313d7c3450cb257d075620f40c2bad3d69d52c8794eccfe954f2502019-01-04 11:27:30,987 - srv1.acme.com.appprd.mysvc.container#0 - INFO - wait for up status2019-01-04 11:27:31,031 - srv1.acme.com.appprd.mysvc.container#0 - INFO - wait for container operational2019-01-04 11:27:31,186 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - bridge mode2019-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 15002019-01-04 11:27:31,273 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pl20321 master br02019-01-04 11:27:31,277 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pl20321 up2019-01-04 11:27:31,281 - srv1.acme.com.appprd.mysvc.ip#0 - INFO - /sbin/ip link set veth0pg20321 netns 203212019-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 eth02019-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 eth02019-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 up2019-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.12019-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.42019-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.32019-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 - 1616cade9257d0616346841c3e9f0d639a9306e1af6fd750fe70e17903a110112019-01-04 11:27:37,797 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - wait for up status2019-01-04 11:27:37,833 - srv1.acme.com.appprd.mysvc.container#mysvc - INFO - wait for container operational

Cuando leí la pregunta, estaba buscando ver si había una manera de conectarme virbr0 a una red Docker. La imagen de abajo es mi modificación de lo que creo que se me estaba preguntando:

enter image description here

Si ese es el caso, la respuesta es usar un macvlan red, que le permite conectar una red de Docker directamente a un dispositivo host. Entonces, algo como lo siguiente te daría lo que quieres:

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