Доступ к виртуальной машине KVM через сеть из контейнера Docker
KVM используется для размещения некоторых виртуальных машин в сети 192.168.2.1/24. Docker работает на той же машине в 192.168.3.1/24. Мне нужно настроить сеть так, чтобы контейнеры Docker могли обращаться к виртуальной машине KVM. Для тестирования у меня есть две машины, на каждой из которых работает веб-сервер для проверки рабочих соединений с помощью wget:
Контейнер Docker на 192.168.3.2
КВМ ВМ на 192.168.2.2
В KVM я настроил виртуальную сеть как перенаправление на все физические сети. Это позволяет мне получить доступ к контейнеру Docker из виртуальной машины KVM. Но не работает наоборот: доступ к виртуальной машине KVM (192.168.2.2) из контейнера Docker (192.168.3.2).
docker network create --driver=bridge --subnet=192.168.3.1/24 my-network
Контейнер запускается так:
docker run --name=gogs --network=my-network --ip=192.168.3.2 -v /var/gogs:/data gogs/gogs
Что здесь делает мастер виртуальной сети KVM, которого нет в Docker?
net.ipv4.ip_forward=1
включен в /etc/sysctl.conf
и я сделал перезагрузку с помощью sysctl --system
,
Сетевой интерфейс Docker
br-7b4175d9379d: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.3.1 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::42:9ff:fe6b:75dd prefixlen 64 scopeid 0x20<link>
ether 02:42:09:6b:75:dd txqueuelen 0 (Ethernet)
RX packets 90 bytes 41977 (41.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 116 bytes 18172 (18.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Сетевой интерфейс KVM
virbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255
ether 52:54:00:85:7f:95 txqueuelen 1000 (Ethernet)
RX packets 1463 bytes 101054 (101.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1214 bytes 1490407 (1.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2 ответа
Вы можете запустить KVM/libvirt и Docker на одном сетевом мосту. Предположим, ваш мост KVM имеет virbr0.
Сначала создайте файл конфигурации /etc/docker/daemon.json, как предлагается в документации Docker, со следующим содержимым (строка iptables может даже не понадобиться):
{
"bridge": "virbr0",
"iptables": false
}
Затем вы останавливаете контейнеры и перезапускаете службу демона docker:
systemctl restart docker
Docker должен подобрать ваш мост KVM, и при перезапуске существующих контейнеров они получат IP-адрес в адресной комнате virbr0 вместо стандартного docker0.
Мне пришлось сделать это дважды, чтобы заставить его работать, но это было так же просто, как звучит под управлением Docker v18.09. Теперь мои виртуальные машины и контейнеры работают в одном сегменте сети.
Настройкаmacvlan
сеть, вероятно, самый простой способ сделать это (я сделал это, и я не гений, когда дело доходит до сети).
Во-первых, вам нужно узнать, какую сеть использует ваша виртуальная машина и каковы ее настройки (на хост-компьютере):
$ virsh net-list
Name State Autostart Persistent
--------------------------------------------
default active yes yes
$ virsh net-info default
Name: default
UUID: 46b9f715-39a2-4e83-bcd0-f07049f32ea5
Active: yes
Persistent: yes
Autostart: yes
Bridge: virbr0
Если вы не используете сеть по умолчанию, выберите ту, на которую вы ориентируетесь. Вам просто нужно иметь правильное имя моста/устройства (в моем примере этоvirbr0
).
Теперь из терминала в самой виртуальной машине вы можете получить информацию о шлюзе и подсети:
$ ip route
default via 192.168.122.1 dev ens3 proto dhcp metric 100
192.168.122.0/24 dev ens3 proto kernel scope link src 192.168.122.49 metric 100
Опять же, ваш вывод может отличаться, но в этом примере шлюз192.168.122.1
а подсеть есть192.168.122.0/24
.
Теперь, когда у вас есть это, вы можете создать собственную сеть macvlan.
docker network create -d macvlan \
--subnet=192.168.122.0/24 \
--gateway=192.168.122.1 \
-o parent=virbr0 kvm_network
И когда вы начинаете новый контейнер, дайте--net kvm_network
В качестве опции. Затем вы сможете общаться с вашей виртуальной машиной из своего контейнера (и наоборот).