[Docker]八.Docker 容器跨主机通讯

一.跨主机通讯原理

在主机192.168.31.140上的docker0(172.17.0.0/16)中有一个容器mycentos( 172.17.0.2/16),

在主机192.168.31.81上的docker0(172.17.0.0/16)中有一个容器mycentos( 172.17.0.2/16),然后在主机192.168.31.140上ping主机192.168.31.81,发现ping不通要实现两个主机间容器的通信,怎么实现呢?

各项配置如下(举例说明):

  • 主机1的IP地址为:192.168.31.140

  • 主机2的IP地址为:192.168.31.81

  • 为主机1上的Docker容器分配的子网:192.168.1.0/24

  • 为主机2上的Docker容器分配的子网:192.168.2.0/24

  • 这样配置之后,两个主机上的Docker容器就肯定不会使用相同的IP地址从而避免了IP冲突

接下来定义两条路由规则即可:
从container1 发往 container2 的数据包,首先发往 container1 的 "网关 "docker0 ,然后通过查找主机 1的路由得知需要将数据包发给主机2 ,数据包到达主机 2 后再转发给主机 2 的 docker0 ,最后由其将数据包转到container2 中,反向原理相同

二.两台主机机通讯实验

1.分别在主机1和主机2上面创建两个网络

主机****1创建网络

bash 复制代码
docker network create --driver bridge --subnet 192.168.1.0/24 --gateway
192.168.1.1 docker1

docker network ls查看网络

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker network ls
NETWORK ID     NAME                 DRIVER    SCOPE
2d19a8dfb493   bridge               bridge    local
c0fbaf2266c8   docker1              bridge    local
fc03b9653496   host                 host      local

docker inspect NETWORK_ID查看配置:发现其网络在192.168.1.0/24上,网关为: 192.168.1.1

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker inspect c0fbaf2266c8
[
    {
        "Name": "docker1",
        "Id": "c0fbaf2266c86f504d02a9324c45fb49c1909f908631d6a2cd5b1bb04dc981a8",
        "Created": "2023-11-20T18:19:18.375826061-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
    ...
    }

主机****2创建网络

bash 复制代码
docker network create --driver bridge --subnet 192.168.2.0/24 --gateway 192.168.2.1 docker1

docker network ls查看网络

bash 复制代码
[root@MiWiFi-R3L-srv centos7]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5fd741696fa2   bridge    bridge    local
04f03105e411   docker1   bridge    local
2110fa85f0da   host      host      local

docker inspect NETWORK_ID查看配置:发现其网络在192.168.2.0/24上,网关为: 192.168.2.1

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker inspect 04f03105e411
[
    {
        "Name": "docker1",
        "Id": "c0fbaf2266c86f504d02a9324c45fb49c1909f908631d6a2cd5b1bb04dc981a8",
        "Created": "2023-11-20T18:19:18.375826061-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.2.0/24",
                    "Gateway": "192.168.2.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
    ...
    }

这样就在两台主机上创建了两个网络,一个主机的网段为1.0,一个主机的网段为2.0

下面在启动容器的时候需要把容器加入到不同的网络中

2.在两个主机上启动对应的容器

在主机1上通过镜像启动一个容器mycentos:

bash 复制代码
#通过cnetos镜像启动一个mycentos1的容器,并指定网络为docker1
[root@MiWiFi-R3L-srv docker]# docker run -it -d --name mycentos1 --net docker1 d757f6342cfa /bin/bash
644cdc0acda390cf236f247bbec6c20080ea9b7a064670fdbbaaeb33cef8995f
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
644cdc0acda3   d757f6342cfa   "/bin/bash"   20 seconds ago   Up 13 seconds             mycentos1

#查看mycentos1容器网络:发现ip:192.168.1.2 在docker1网络上
[root@MiWiFi-R3L-srv docker]# docker exec -it mycentos1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 02:42:c0:a8:01:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2376 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在主机2上通过镜像启动一个容器mycentos:

bash 复制代码
#通过cnetos镜像启动一个mycentos1的容器,并指定网络为docker1
[root@MiWiFi-R3L-srv docker]# docker run -it -d --name mycentos1 --net docker1 d757f6342cfa /bin/bash
644cdc0acda390cf236f247bbec6c20080ea9b7a064670fdbbaaeb33cef8995f
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
4ba38cf3943b d757f6342cfa   "/bin/bash"   20 seconds ago   Up 13 seconds             mycentos1

#查看mycentos1容器网络:发现ip:192.168.2.2 在docker1网络上
[root@MiWiFi-R3L-srv docker]# docker exec -it mycentos1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.2  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 02:42:c0:a8:01:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2376 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 在主机1上ping主机2,能够ping通,他们处于同一网段
  • 在主机1的容器中ping主机1,他们也能ping通
  • 在主机1的容器中ping主机2可以ping通
  • 在主机1的容器中ping主机2的容器,ping不通,因为他们不处于同一网段
bash 复制代码
#主机1上ping主机2,ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.31.81
PING 192.168.31.81 (192.168.31.81) 56(84) bytes of data.
64 bytes from 192.168.31.81: icmp_seq=1 ttl=64 time=1.42 ms
^C
--- 192.168.31.81 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.418/1.418/1.418/0.000 ms
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
644cdc0acda3   d757f6342cfa   "/bin/bash"   12 minutes ago   Up 12 minutes             mycentos1

#进入主机1容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acda3 /bin/bash
[root@644cdc0acda3 wwwroot]# 

#容器中ping主机2,ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.31.140
PING 192.168.31.140 (192.168.31.140) 56(84) bytes of data.
64 bytes from 192.168.31.140: icmp_seq=1 ttl=64 time=0.359 ms
^C
--- 192.168.31.140 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.359/0.359/0.359/0.000 ms

#容器中ping主机1,ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.31.81 
PING 192.168.31.81 (192.168.31.81) 56(84) bytes of data.
64 bytes from 192.168.31.81: icmp_seq=1 ttl=63 time=0.419 ms
64 bytes from 192.168.31.81: icmp_seq=2 ttl=63 time=0.387 ms
^C
--- 192.168.31.81 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1049ms
rtt min/avg/max/mdev = 0.387/0.403/0.419/0.016 ms

#容器中ping主机2中的容器,ping不通
[root@644cdc0acda3 wwwroot]# ping 192.168.2.2  
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.

那么要时主机1中的容器和主机2中的容器通信,怎么办呢,这就需要配置路由规则

3.添加路由规则

主机1上添加路由规则

bash 复制代码
#查看主机1上的路由规则
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     427    0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9a2fe27fdd30
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-fe75119d5a77
192.168.1.0     0.0.0.0         255.255.255.0   U     426    0        0 br-c0fbaf2266c8
192.168.2.0     0.0.0.0         255.255.255.0   U     425    0        0 br-2d9c2d29e6d3
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

把访问 192.168.2.0 的请求转发到主机2服务器 192.168.31.81

bash 复制代码
#在主机1上配置192.168.2.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.31.81

当访问192.168.2.0这个结点的ip时,就会转发到192.168.31.81这台主机服务器上

bash 复制代码
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     427    0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9a2fe27fdd30
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-fe75119d5a77
192.168.1.0     0.0.0.0         255.255.255.0   U     426    0        0 br-c0fbaf2266c8
192.168.2.0     192.168.31.81   255.255.255.0   UG    0      0        0 ens33
192.168.2.0     0.0.0.0         255.255.255.0   U     425    0        0 br-2d9c2d29e6d3
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

主机2上添加路由规则

bash 复制代码
#查看主机1上的路由规则
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        0 br-04f03105e411
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

把访问 192.168.1.0 的请求转发到主机2服务器 192.168.31.140

bash 复制代码
#在主机2上配置192.168.1.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.31.140

当访问192.168.1.0这个结点的ip时,就会转发到192.168.31.140这台主机服务器上

bash 复制代码
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.1.0     192.168.31.140  255.255.255.0   UG    0      0        0 ens33
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        0 br-04f03105e411
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

4.配置iptables规则

IPTABLES是与最新的 3.5 版本 Linux 内核集成的 IP 信息包过滤系统 (相当于ip的防火墙),命令如下:

bash 复制代码
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网>
--sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j DNAT --to
192.168.1.1

-t nat : 实现共享网络
-I PREROUTING:用于目标地址转换(DNAT)。
-I POSTOUTING:用于源地址转换(SNAT)
-s 源ip/子网
-d 目标ip/子网
-j DNAT DNAT:目标地址转换

主机 1 上添加如下规则:

bash 复制代码
iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j DNAT --to 192.168.1.1

主机 2 上添加如下规则:

bash 复制代码
iptables -t nat -I PREROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j DNAT --to 192.168.2.1

5.容器间通信

在主机1/主机1的容器中ping主机2容器,发现可以ping通

bash 复制代码
#主机1上ping主机2的容器:可以ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=63 time=1.74 ms


64 bytes from 192.168.2.2: icmp_seq=2 ttl=63 time=0.346 ms


#进入主机1容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acda3 /bin/bash

#ping主机2的容器,可以ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.192 ms

在主机2/主机2的容器中ping主机1容器,发现可以ping通

bash 复制代码
#主机2上ping主机1的容器:可以ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=63 time=1.74 ms

64 bytes from 192.168.2.2: icmp_seq=2 ttl=63 time=0.346 ms

#进入主机2容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acd1a3 /bin/bash

#ping主机1的容器,可以ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.192 ms

这样不同主机间的容器就可以相互通信了,即可以实现负载均衡/转发等功能,一台主机部署web,一台主机部署数据库,通过docker配置就可以实现相互通信

三.三台主机通讯实验

这个和上面方法一致

1.分别在主机1**、主机2、主机3上面创建两个网络**

  • 主机1的IP地址为:192.168.31.140
  • 主机2的IP地址为:192.168.31.81
  • 主机2的IP地址为:192.168.31.117

主机****1创建网络

bash 复制代码
docker network create --driver bridge --subnet 192.168.1.0/24 --gateway
192.168.1.1 docker1

docker network ls查看网络

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker network ls
NETWORK ID     NAME                 DRIVER    SCOPE
2d19a8dfb493   bridge               bridge    local
c0fbaf2266c8   docker1              bridge    local
fc03b9653496   host                 host      local

docker inspect NETWORK_ID查看配置:发现其网络在192.168.1.0/24上,网关为: 192.168.1.1

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker inspect c0fbaf2266c8
[
    {
        "Name": "docker1",
        "Id": "c0fbaf2266c86f504d02a9324c45fb49c1909f908631d6a2cd5b1bb04dc981a8",
        "Created": "2023-11-20T18:19:18.375826061-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
    ...
    }

主机****2创建网络

bash 复制代码
docker network create --driver bridge --subnet 192.168.2.0/24 --gateway 192.168.2.1 docker1

docker network ls查看网络

bash 复制代码
[root@MiWiFi-R3L-srv centos7]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5fd741696fa2   bridge    bridge    local
04f03105e411   docker1   bridge    local
2110fa85f0da   host      host      local

docker inspect NETWORK_ID查看配置:发现其网络在192.168.2.0/24上,网关为: 192.168.2.1

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker inspect 04f03105e411
[
    {
        "Name": "docker1",
        "Id": "c0fbaf2266c86f504d02a9324c45fb49c1909f908631d6a2cd5b1bb04dc981a8",
        "Created": "2023-11-20T18:19:18.375826061-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.2.0/24",
                    "Gateway": "192.168.2.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
    ...
    }

主机3创建网络

bash 复制代码
docker network create --driver bridge --subnet 192.168.3.0/24 --gateway 192.168.3.1 docker1

docker network ls查看网络

bash 复制代码
[root@MiWiFi-R3L-srv centos7]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5fd741696fa2   bridge    bridge    local
04f03105e413  docker1   bridge    local
2110fa85f0da   host      host      local

docker inspect NETWORK_ID查看配置:发现其网络在192.168.3.0/24上,网关为: 192.168.3.1

bash 复制代码
[root@MiWiFi-R3L-srv docker]# docker inspect 04f03105e413
[
    {
        "Name": "docker1",
        "Id": "c0fbaf2266c86f504d02a9324c45fb49c1909f908631d6a2cd5b1bb04dc981a8",
        "Created": "2023-11-20T18:19:18.375826061-08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.3.0/24",
                    "Gateway": "192.168.3.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
    ...
    }

这样就在三台主机上创建了三个网络,一个主机的网段为1.0,一个主机的网段为2.0,,一个主机的网段为3.0,下面在启动容器的时候需要把容器加入到不同的网络中

2.在三台主机上启动对应的容器

在主机1上通过镜像启动一个容器mycentos:

bash 复制代码
#通过cnetos镜像启动一个mycentos1的容器,并指定网络为docker1
[root@MiWiFi-R3L-srv docker]# docker run -it -d --name mycentos1 --net docker1 d757f6342cfa /bin/bash
644cdc0acda390cf236f247bbec6c20080ea9b7a064670fdbbaaeb33cef8995f
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
644cdc0acda3   d757f6342cfa   "/bin/bash"   20 seconds ago   Up 13 seconds             mycentos1

#查看mycentos1容器网络:发现ip:192.168.1.2 在docker1网络上
[root@MiWiFi-R3L-srv docker]# docker exec -it mycentos1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 02:42:c0:a8:01:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2376 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在主机2上通过镜像启动一个容器mycentos:

bash 复制代码
#通过cnetos镜像启动一个mycentos1的容器,并指定网络为docker1
[root@MiWiFi-R3L-srv docker]# docker run -it -d --name mycentos1 --net docker1 d757f6342cfa /bin/bash
644cdc0acda390cf236f247bbec6c20080ea9b7a064670fdbbaaeb33cef8995f
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
4ba38cf3943b d757f6342cfa   "/bin/bash"   20 seconds ago   Up 13 seconds             mycentos1

#查看mycentos1容器网络:发现ip:192.168.2.2 在docker1网络上
[root@MiWiFi-R3L-srv docker]# docker exec -it mycentos1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.2  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 02:42:c0:a8:01:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2376 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在主机3上通过镜像启动一个容器mycentos:

bash 复制代码
#通过cnetos镜像启动一个mycentos1的容器,并指定网络为docker1
[root@MiWiFi-R3L-srv docker]# docker run -it -d --name mycentos1 --net docker1 d757f6342cfa /bin/bash
644cdc0acda390cf236f247bbec6c20080ea9b7a064670fdbbaaeb33cef8995f
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
4ba38cf3943b3 d757f6342cfa   "/bin/bash"   20 seconds ago   Up 13 seconds             mycentos1

#查看mycentos1容器网络:发现ip:192.168.3.2 在docker1网络上
[root@MiWiFi-R3L-srv docker]# docker exec -it mycentos1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.3.2  netmask 255.255.255.0  broadcast 192.168.3.255
        ether 02:42:c0:a8:01:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2376 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 在主机1上ping主机2,能够ping通,他们处于同一网段
  • 在主机1的容器中ping主机1,他们也能ping通
  • 在主机1的容器中ping主机2可以ping通
  • 在主机1的容器中ping主机2的容器,在主机1的容器中ping主机3的容器,ping不通,因为他们不处于同一网段
bash 复制代码
#主机1上ping主机2,ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.31.81
PING 192.168.31.81 (192.168.31.81) 56(84) bytes of data.
64 bytes from 192.168.31.81: icmp_seq=1 ttl=64 time=1.42 ms
^C
--- 192.168.31.81 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.418/1.418/1.418/0.000 ms
[root@MiWiFi-R3L-srv docker]# docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
644cdc0acda3   d757f6342cfa   "/bin/bash"   12 minutes ago   Up 12 minutes             mycentos1

#进入主机1容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acda3 /bin/bash
[root@644cdc0acda3 wwwroot]# 

#容器中ping主机2,ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.31.140
PING 192.168.31.140 (192.168.31.140) 56(84) bytes of data.
64 bytes from 192.168.31.140: icmp_seq=1 ttl=64 time=0.359 ms
^C
--- 192.168.31.140 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.359/0.359/0.359/0.000 ms

#容器中ping主机1,ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.31.81 
PING 192.168.31.81 (192.168.31.81) 56(84) bytes of data.
64 bytes from 192.168.31.81: icmp_seq=1 ttl=63 time=0.419 ms
64 bytes from 192.168.31.81: icmp_seq=2 ttl=63 time=0.387 ms
^C
--- 192.168.31.81 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1049ms
rtt min/avg/max/mdev = 0.387/0.403/0.419/0.016 ms

#容器中ping主机2中的容器,ping不通
[root@644cdc0acda3 wwwroot]# ping 192.168.2.2  
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.


#容器中ping主机3中的容器,ping不通
[root@644cdc0acda3 wwwroot]# ping 192.168.3.2  
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.

那么要时主机1中的容器和主机2中的容器/主机2中的容器 通信,怎么办呢,这就需要配置路由规则

3.添加路由规则

主机1上添加路由规则

bash 复制代码
#查看主机1上的路由规则
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     427    0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9a2fe27fdd30
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-fe75119d5a77
192.168.1.0     0.0.0.0         255.255.255.0   U     426    0        0 br-c0fbaf2266c8
192.168.2.0     0.0.0.0         255.255.255.0   U     425    0        0 br-2d9c2d29e6d3
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

把访问 192.168.2.0 的请求转发到主机2服务器 192.168.31.81
把访问 192.168.2.0 的请求转发到主机3服务器 192.168.31.117

bash 复制代码
#在主机1上配置192.168.2.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.31.81
#在主机1上配置192.168.3.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.3.0 netmask 255.255.255.0 gw 192.168.31.117

当访问192.168.2.0这个结点的ip时,就会转发到192.168.31.81这台主机服务器上

当访问192.168.3.0这个结点的ip时,就会转发到192.168.31.117这台主机服务器上

bash 复制代码
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     427    0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9a2fe27fdd30
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-fe75119d5a77
192.168.1.0     0.0.0.0         255.255.255.0   U     426    0        0 br-c0fbaf2266c8
192.168.2.0     192.168.31.81   255.255.255.0   UG    0      0        0 ens33
192.168.3.0     192.168.31.117   255.255.255.0   UG    0      0        0 ens33
192.168.2.0     0.0.0.0         255.255.255.0   U     425    0        0 br-2d9c2d29e6d3
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

主机2上添加路由规则

bash 复制代码
#查看主机1上的路由规则
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        0 br-04f03105e411
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

把访问 192.168.1.0 的请求转发到主机2服务器 192.168.31.140
把访问 192.168.3.0 的请求转发到主机2服务器 192.168.31.117

bash 复制代码
#在主机2上配置192.168.1.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.31.140

#在主机2上配置192.168.3.0这个路由
[root@MiWiFi-R3L-srv docker]# route add -net 192.168.3.0 netmask 255.255.255.0 gw 192.168.31.117

当访问192.168.1.0这个结点的ip时,就会转发到192.168.31.140这台主机服务器上

当访问192.168.3.0这个结点的ip时,就会转发到192.168.31.117这台主机服务器上

bash 复制代码
[root@MiWiFi-R3L-srv docker]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         XiaoQiang       0.0.0.0         UG    100    0        0 ens33
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.1.0     192.168.31.140  255.255.255.0   UG    0      0        0 ens33
192.168.3.0     192.168.31.117  255.255.255.0   UG    0      0        0 ens33
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0        0 br-04f03105e411
192.168.31.0    0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

4.配置iptables规则

IPTABLES是与最新的 3.5 版本 Linux 内核集成的 IP 信息包过滤系统 (相当于ip的防火墙),命令如下:

bash 复制代码
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网>
--sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j DNAT --to
192.168.1.1

-t nat : 实现共享网络
-I PREROUTING:用于目标地址转换(DNAT)。
-I POSTOUTING:用于源地址转换(SNAT)
-s 源ip/子网
-d 目标ip/子网
-j DNAT DNAT:目标地址转换

主机 1 上添加如下规则:

bash 复制代码
iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j DNAT --to 192.168.1.1

iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.3.0/24 -j DNAT --to 192.168.1.1

主机 2 上添加如下规则:

bash 复制代码
iptables -t nat -I PREROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j DNAT --to 192.168.2.1

iptables -t nat -I PREROUTING -s 192.168.2.0/24 -d 192.168.3.0/24 -j DNAT --to 192.168.2.1

主机3 上添加如下规则:

bash 复制代码
iptables -t nat -I PREROUTING -s 192.168.3.0/24 -d 192.168.1.0/24 -j DNAT --to 192.168.2.1

iptables -t nat -I PREROUTING -s 192.168.3.0/24 -d 192.168.2.0/24 -j DNAT --to 192.168.2.1

5.容器间通信

在主机1/主机1的容器中ping主机2容器/主机3容器,发现可以ping通

bash 复制代码
#主机1上ping主机2的容器:可以ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=63 time=1.74 ms


64 bytes from 192.168.2.2: icmp_seq=2 ttl=63 time=0.346 ms


#主机1上ping主机3的容器:可以ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.3.2
PING 192.168.3.2 (192.168.3.2) 56(84) bytes of data.
64 bytes from 192.168.3.2: icmp_seq=1 ttl=63 time=1.74 ms


64 bytes from 192.168.3.2: icmp_seq=2 ttl=63 time=0.346 ms


#进入主机1容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acda3 /bin/bash

#ping主机2的容器,可以ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.192 ms


#ping主机3的容器,可以ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.3.2
PING 192.168.3.2 (192.168.3.2) 56(84) bytes of data.
64 bytes from 192.168.3.2: icmp_seq=1 ttl=64 time=0.192 ms

在主机2/主机2的容器中ping主机1容器/主机3容器,发现可以ping通

bash 复制代码
#主机2上ping主机1的容器:可以ping通
[root@MiWiFi-R3L-srv docker]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=63 time=1.74 ms

64 bytes from 192.168.2.2: icmp_seq=2 ttl=63 time=0.346 ms

#进入主机2容器
[root@MiWiFi-R3L-srv docker]# docker exec -it 644cdc0acd1a3 /bin/bash

#ping主机1的容器,可以ping通
[root@644cdc0acda3 wwwroot]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.192 ms

上一节\][\[Docker\]七.配置 Docker 网络](https://blog.csdn.net/zhoupenghui168/article/details/134484824 "[Docker]七.配置 Docker 网络")

相关推荐
文牧之6 分钟前
PostgreSQL 常用日志
运维·数据库·postgresql
蓝莓味柯基11 分钟前
DevOps:概念与学习路径
运维·学习·devops
FJW02081426 分钟前
【Linux】web服务器的部署和优化
linux·运维·服务器·rhce
有谁看见我的剑了?42 分钟前
docker 运行时权限和 Linux 能力了解
linux·docker·容器
平生不喜凡桃李1 小时前
Linux 进程控制
linux·运维·服务器
鱼与宇1 小时前
Linux常用命令
linux·运维·服务器
小南家的青蛙1 小时前
lspci的资料
linux·运维·服务器
敖云岚1 小时前
【那些年踩过的坑】Docker换源加速详细教程(截至2025年4月)
运维·docker·容器
柳如烟@2 小时前
Docker安装ES :确保 Kibana 正确连接 Elasticsearch
运维·数据库·elasticsearch·docker·容器·kibana
网络工程师_ling2 小时前
【WLAN】华为无线AC双机热备负载分担—双链路热备份
运维·网络