从远程计算机连接到容器

Mar*_*ner 5 docker docker-networking

我创建了一个用户定义的网络(桥接模式)hb1,并添加了2个容器。但是,我无法从网络上的外部主机连接到它们。

我仔细检查并按照此处此处的说明进行操作。

pi@raspberrypi:~ $ docker network inspect hb1
[
    {
        "Name": "hb1",
        "Id": "278a4ba8bb7a4a34b25b5f5fde9a965a807ff896d5e57c2b1d7d39af60d0a046",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.32/27",
                    "Gateway": "192.168.1.33"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "7dc7be3ae45813450bb7f75a6e2c7b4d93e59aa147aa7d393061748b8201381a": {
                "Name": "modest_bohr",
                "EndpointID": "eda20bbb52319b10911f3da6f6afadbd2167298d5a9cfd5c91f933f4b6d5fe86",
                "MacAddress": "02:42:c0:a8:01:22",
                "IPv4Address": "192.168.1.34/27",
                "IPv6Address": ""
            },
            "f12fbc30bcf5e37737bfe8c7868dcd40e6c632bb3672f5641ffd6960ede4f777": {
                "Name": "infallible_torvalds",
                "EndpointID": "92d0ecfad597485c25ad309d48c3c77b9368f25ebbd851b1168f59a795c497f2",
                "MacAddress": "02:42:c0:a8:01:23",
                "IPv4Address": "192.168.1.35/27",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
Run Code Online (Sandbox Code Playgroud)

当我从docker主机ping时,它按预期工作。

user@myhost: ~$ ping -c 1 192.168.1.34
PING 192.168.1.34 (192.168.1.34) 56(84) bytes of data.
64 bytes from 192.168.1.34: icmp_seq=1 ttl=64 time=0.474 ms

--- 192.168.1.34 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.474/0.474/0.474/0.000 ms
Run Code Online (Sandbox Code Playgroud)

但是,无法从远程主机访问该容器。

user@remotehost: ~$ ping -c 1 192.168.1.34
PING 192.168.1.34 (192.168.1.34) 56(84) bytes of data.
From 192.168.1.100 icmp_seq=1 Destination Host Unreachable

--- 192.168.1.34 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
Run Code Online (Sandbox Code Playgroud)

我应该如何配置docker用户定义的网络或本地网络,以便可以在单独的IP地址上访问容器?

Moh*_*din 2

我今天回答了一个非常相似的问题,你能看一下我的答案并遵循它吗,它非常适合我。

为 Docker 容器分配与主机 IP 地址不同的 LAN IP 地址

答案如下:

创建持久性网桥

,Bridge是一个设备(在我们的例子中是虚拟设备),其行为类似于网络交换机(主要在网络层 2 上运行),即,如果满足以下条件,它可以将两个或多个网络接口连接到同一局域网 (LAN) 上:他们有相同的子网

您将创建新的持久性桥br0(它将在系统启动时自动启动),将您的物理网络接口添加到其中(在我的例子中是eth0)。请注意,将接口添加到网桥后,该接口不再需要 IP 地址,因为网桥将获取 IP 地址并可以代替您的接口使用,即,您可以使用网桥进行通信,就好像它是您的一样物理接口,它将把输入/输出数据包转发到正确的目的地。您不需要为网桥分配任何硬件(MAC 地址),它会自动采用第一个添加的接口的 MAC。

警告:强烈建议不要远程执行这些步骤,除非您可以物理访问服务器!如果不小心,您可能会失去与服务器的连接。

安装网桥管理实用程序:

sudo apt install bridge-utils
Run Code Online (Sandbox Code Playgroud)

如果没有包,系统将无法创建桥bridge-utils

要创建持久性桥,请编辑interfaces文件:

sudo vim /etc/network/interfaces
Run Code Online (Sandbox Code Playgroud)

将以下配置添加到文件末尾(根据您的需要进行调整):

auto br0
iface br0 inet static
    bridge_ports eth0
    address 192.168.1.10
    netmask 255.255.255.0
    broadcast 192.168.1.255
    gateway 192.168.1.1
Run Code Online (Sandbox Code Playgroud)

现在删除 Docker 的默认网桥 docker0,因为我们不需要它:

sudo systemctl stop docker
sudo ip link set dev docker0 down
sudo brctl delbr docker0
Run Code Online (Sandbox Code Playgroud)

编辑 Docker 的服务启动脚本以使用您的网桥 (br0) 而不是 Docker 的默认网桥 (docker0),并传递一些重要的网桥参数:

乌班图:

sudo vim /etc/systemd/multi-user.target.wants/docker.service
Run Code Online (Sandbox Code Playgroud)

调整文件如下:

[Service]

ExecStart=/usr/bin/dockerd -H fd:// --bridge=br0 --fixed-cidr=192.168.1.32/27 --default-gateway=192.168.1.1
Run Code Online (Sandbox Code Playgroud)

现在告诉系统该文件的更改:

sudo systemctl daemon-reload
Run Code Online (Sandbox Code Playgroud)

重新启动系统:

sudo reboot
Run Code Online (Sandbox Code Playgroud)

现在检查你的桥,它应该在那里!

ip addr
Run Code Online (Sandbox Code Playgroud)

现在创建您的容器,如下所示,这将为您的容器提供固定的 IP

  docker run --name myContainer \
  -it --restart always --memory 100M \
  --network bridge --cap-add NET_ADMIN \
  --hostname client1.noureldin.local \
  --add-host "client1.noureldin.local client1":192.168.1.123 \
  mnoureldin/general-purpose:latest /bin/bash -c " \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \
  /bin/bash"
Run Code Online (Sandbox Code Playgroud)

与您的网络要求相关的重要部分是:

  --network bridge --cap-add NET_ADMIN \
  ip addr flush dev eth0; \
  ip addr add 192.168.1.123/24 brd + dev eth0; \
  ip route add default via 192.168.1.1 dev eth0; \
Run Code Online (Sandbox Code Playgroud)

当然,请确保您iproute2 net-tools iputils-ping在容器中安装了软件包,以便能够执行常见的网络命令(通过ip命令提供固定IP)。

第一次运行容器时,您可能不会注意到 IP 地址有任何变化,因为您的容器可能没有iproute2软件包(即没有ip命令),只需安装提到的软件包,然后重新启动容器,一切都应该是完全如您所愿!

希望有帮助。