同一主机上的 KVM VM 与 docker 容器之间的网络

同一主机上的 KVM VM 与 docker 容器之间的网络

在 Debian-Stretch 主机(连接到物理 LAN)上,我有一个新的 docker 安装(v18.09),其中包含一个数据库容器(端口映射到主机),并且我使用一些 Debian-Stretch VM 运行 KVM/libvirt。我可以从 LAN 访问 docker 容器和 VM(取决于通过 SSH 隧道或直接的配置),但我很难从 VM 访问 docker 容器。

在此处输入图片描述

# 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

经过几天的阅读,我在这篇文章中找到了非常令人信服的解决方案带有桥接器的 Docker 和 KVM原来的),但我没能成功。解决方案建议使用一行配置 daemon.json 代码启动 docker,以使用 KVM“默认”桥。那该有多好啊!还有希望吗?

我尝试了两种不同的 KVM VM 之间的网络连接配置。在这两种情况下,VM 和 LAN+路由器+云之间的通信都很顺畅,但我不知道如何越过栅栏,走向更绿的草地……:)

Conf 1-带有 NAT 的 KVM 默认桥接器:我可以通过 ssh 连接到 Debian 主机并访问 docker 容器端口,但是是否有直接路由的设置?

Conf 2 - macvtap 适配器以桥接模式连接到 LAN:我无法从 VM ping 主机 LAN IP,尽管两者都连接到同一个路由器。VM 本身的响应是Destination Host Unreachable。知道为什么吗?

在单独的 VM 中而不是直接在 Debian 主机上运行 docker 守护程序会更好吗?这样,容器和 VM 都可以访问 KVM 默认网桥。但我认为在 KVM 主机上的 VM 中运行 docker 有点奇怪。

任何明确的指导都将不胜感激!

顺便说一句,该桥接器br-f9f3ccd64037是我使用 docker 创建的用户定义桥接器,用于将来的容器间通信。它没有使用。

更新:

我刚刚意识到,通过第一个配置,我可以从 VM 客户机通过其 IP 地址(172.17.0.2)简单地连接到 docker 容器。

我最初的设置是第二种配置,因为我想通过 RDP 进入虚拟机,这更容易,因为 macvtap 驱动程序将虚拟机直接连接到 LAN,不需要 SSH 链接。那时我无法访问容器。

答案1

解决方案就像链接文章中说的一样简单。我不确定为什么我第一次重新启动docker守护进程时配置没有改变。

在我找到证据之后Docker 守护进程文档对于 daemon.json 中的 bridge 参数,我再次尝试,docker 守护进程在启动时选择了 KVM 默认桥接器。

首先我按照文档中的建议创建了配置文件/etc/docker/daemon.json,其内容如下(甚至可能不需要 iptables 行):

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

所需要的只是:

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

现有的 docker 容器正在 KVM 桥上运行。可以使用以下命令检查容器的 IP 地址:

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

我不知道现在是否可以删除 docker0 网桥,但是容器与三个虚拟机一起列在 virbr0 下。

brctl show
bridge name bridge id           STP enabled interfaces
docker0     8000.024241f39b89   no      
virbr0      8000.068ff2a4a56e   yes         veth2abcff1
                                            virbr0-nic
                                            vnet0
                                            vnet1
                                            vnet2

答案2

当我读到这个问题时,我正在寻找是否有办法连接virbr0到 Docker 网络。下图是我对所问问题的修改:

在此处输入图片描述

如果是这种情况,答案是使用网络macvlan,它允许您将 docker 网络直接连接到主机设备。因此,类似下面的操作可以实现您想要的效果:

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

答案3

我习惯使用以下设置来实现这一点:

  • 我创建了一个br0带有物理网卡的桥

  • kvm 机器使用下面的 qemu xml 配置片段连接到桥上

    <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>
  • br0所有 docker 堆栈都以相同的方式运行:我为每个堆栈保留一个公共可路由 IP。我使用下面的 opensvc 服务配置代码片段将此公共 IP 连接到网桥。

    • [ip#0]部分告诉我们,我们希望将 IP配置到资源 ID为 docker google/pause 的1.2.3.4容器中,并连接到网桥container#0br0

    • 堆栈中的所有其他 docker 都从container#0配置中继承网络配置netns = container#0由于docker 声明中的

    • 当 opensvc 服务启动时,网络设置由代理完成,并生成以下日志中报告的所有命令

opensvc 服务配置

[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

启动日志

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

相关内容