如何让 Linux 容器通过网桥连接到互联网?

如何让 Linux 容器通过网桥连接到互联网?

我的 Linux 主机有一个桥接设备br0,并且我已经创建了一个 arch Linux 容器,但它无法访问互联网。

当容器启动时,veth 设备出现在主机上:

[host]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether 74:d4:35:70:0b:2f brd ff:ff:ff:ff:ff:ff
    inet6 fe80::76d4:35ff:fe70:b2f/64 scope link 
       valid_lft forever preferred_lft forever
3: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN group default qlen 1000
    link/ether be:b3:74:db:60:5f brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 74:d4:35:70:0b:2f brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.44/24 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::76d4:35ff:fe70:b2f/64 scope link 
       valid_lft forever preferred_lft forever
37: veth2G6SCA@if36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default qlen 1000
    link/ether fe:5d:8a:48:81:74 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 169.254.192.90/16 brd 169.254.255.255 scope global noprefixroute veth2G6SCA
       valid_lft forever preferred_lft forever
    inet6 fe80::fc5d:8aff:fe48:8174/64 scope link 
       valid_lft forever preferred_lft forever

并显示以下路线(***旁边有):

[host]# ip route
default via 192.168.1.254 dev br0 proto static 
default dev veth2G6SCA scope link src 169.254.192.90 metric 237 ***
169.254.0.0/16 dev veth2G6SCA scope link src 169.254.192.90 metric 237 ***
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.44 

容器内部

[container]# ip addr
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:86:c2:9f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::216:3eff:fe86:c29f/64 scope link 
       valid_lft forever preferred_lft forever
[container]# ip route

容器无法 ping 通 IP 地址或域。

systemctl 显示联网并解决失败:

[container]# systemctl
...
● systemd-networkd.service          loaded failed failed    Network Service                                                              
● systemd-resolved.service          loaded failed failed    Network Name Resolution                                                      

使用时journalctl -r我发现一些错误,但我并不理解它们。

Feb 03 20:04:53 archie systemd[1]: Stopped Network Service.
Feb 03 20:04:53 archie systemd[1]: systemd-networkd.service: Scheduled restart job, restart counter is at 5.
Feb 03 20:04:53 archie systemd[1]: systemd-networkd.service: Service has no hold-off time (RestartSec=0), scheduling restart.
Feb 03 20:04:53 archie systemd[1]: Failed to start Network Service.
Feb 03 20:04:53 archie systemd[1]: systemd-networkd.service: Failed with result 'exit-code'.
Feb 03 20:04:53 archie systemd[1]: systemd-networkd.service: Main process exited, code=exited, status=226/NAMESPACE
Feb 03 20:04:53 archie systemd[29]: systemd-networkd.service: Failed at step NAMESPACE spawning /usr/lib/systemd/systemd-networkd: Permission>
Feb 03 20:04:53 archie systemd[29]: systemd-networkd.service: Failed to set up mount namespacing: Permission denied
Feb 03 20:04:53 archie systemd[1]: Starting Network Service...

我查了一下,169.254 IP 地址是由于 DHCP 失败造成的。

我尝试编辑容器中的 systemd-networkd 配置文件以使用静态 IP 地址,如下方的示例:https://wiki.archlinux.org/index.php/systemd-networkd#Usage_with_containers

[container]# cat /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
Address=192.168.1.77/24
Gateway=192.168.1.254
DNS=8.8.8.8

但网络仍然不起作用并且出现相同的错误。

我怎样才能使网络在容器内部正常工作?

谢谢!

答案1

我习惯使用 opensvc 代理管理我的 lxc 容器来运行此操作。

以下是服务配置示例:

[DEFAULT]
nodes = {clusternodes}
encapnodes = {container#1.name}
nodes@encapnodes = {container#1.name}

[disk#1]
type = zpool
name = {env.zfspool}
scsireserv = true
shared = true

[fs#root]
dev = {env.zfspool}
mnt = /srv/{svcname}
type = zfs
shared = true

[fs#container]
dev = {env.zfspool}/rootfs
mnt = {fs#root.mnt}/rootfs
type = zfs
shared = true

[container#1]
name = {env.lxcname}
type = lxc
rootfs = {fs#container.mnt}
shared = true

[ip#1]
type = netns
ipdev = {env.ipdev}
ipname = {env.ipname}
netmask = {env.netmask}
gateway = {env.gateway}
netns = container#1
shared = true

[env]
zfspool = {svcname}
lxcname = {svcname}
ipdev = br0
ipname = lxc.acme.com
netmask = 24
gateway = 10.11.12.1

正如您在部分中看到的ip#1,有一个对container#1部分的引用;这意味着当 opensvc 服务启动时,opensvc 代理将把 ip 配置注入到引用的容器中。

{svcname}是对实际 opensvc 服务名称的引用。

相关内容