狂神说Docker:Docker网络详解

首先来个docker镜像清理

停掉所有线程:

[root@localhost home]# docker stop $(docker ps -aq)

删除所有镜像:

[root@localhost home]# docker rmi -f $(docker images -aq)

理解Docker0

 三个网络

docker是如何处理容器网络访问的?

 上面我们可以看到eth0@if55,这个是docker分配的

[root@localhost home]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.144 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.088 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.106 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.090 ms

我们发现docker是可以ping通的。

原理

  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术。
  2. 再启动一个容器测试,我们发现又多了一对网卡。

我们发现这个容器带来的网卡,都是一对一对的

evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连

正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的。

我们测试一下tomcat01和tomcat02是否可以ping通

新建一个tomcat02

[root@localhost home]# docker run -d -P --name tomcat02 tomcat:9.0
1c26376153b5720b49292e3aa8579407cd6fc1553350737e58aa0f10761e79a5
[root@localhost home]# 
[root@localhost home]# 
[root@localhost home]# docker ps
CONTAINER ID   IMAGE        COMMAND             CREATED          STATUS          PORTS                                         NAMES
1c26376153b5   tomcat:9.0   "catalina.sh run"   5 seconds ago    Up 3 seconds    0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
6c545fef8cc9   tomcat:9.0   "catalina.sh run"   14 minutes ago   Up 14 minutes   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@localhost home]# docker exec -it tomcat01 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
54: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@localhost home]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.236 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.088 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.095 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 0.088/0.139/0.236/0.069 ms
[root@localhost home]# 

我们可以看到tomcat02是可以ping通tomcat01的,可以说他们之间是可以相互ping通的

img

docker使用的是Linux桥接,宿主机中是一个Docker容器的桥接。

imgDocker中的所有的网络接口都是虚拟的,虚拟的转发效率高,只要删除容器,对应的网桥也会删除。

容器互联--Link

首先我们来看一段代码

[root@localhost home]# docker exec -it tomcat02 ping tomcat01

tomcat02 ping tomcat01是ping不通的

引用下方命令,新建tomcat03,使用--link连接tomcat02

[root@localhost home]# docker run -d -P --name tomcat03 --link tomcat02 tomcat:9.0

 然后我们再tomcat02和tomcat03之间互相ping一下

[root@localhost home]# docker exec -it tomcat02 ping tomcat03   
ping: tomcat03: Name or service not known
[root@localhost home]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.148 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.081 ms
^C
--- tomcat02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.081/0.114/0.148/0.035 ms
[root@localhost home]# 

我们发现2 ping 3 不行  但是3 ping 2 却是可以的

如果想要2连3,那么需要在2这里配置3的

现在我们不是这么玩了。

自定义网络

查看所有的Docker网络

[root@localhost home]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
870e7b5932d7   bridge    bridge    local
b849afd2252a   host      host      local
a018dbb14fc5   none      null      local

网络模式:

bridge:桥接docker(默认)

none:不配置网络

host:和宿主机共享网络

container:容器网络连通!(用的少,局限很大)

测试

我们之前在创建网络的时候,docker会给我们默认的网络配置 --net

[root@localhost home]# docker run -d -P --name tomcat01 --net bridge tomcat:9.0

docker 默认指定的网络就是bridge(--net bridge)

所以理论上我们可以不用docker默认的网络,用自己定义的网路

[root@localhost home]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network  #可以创建网络
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.

创建自定义网络

[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
51276ec9ede3d8e0b428f96dbfe6b0cdb6ed8ef8f3ec6fcc8cd40e08390360e4
[root@localhost ~]# 

[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 改命令中

--driver bridge 

--subnet 192.168.0.0/16  表示我自己定义的网路,16位子网

--gateway 后面显示我的网关

将容器发布到自己创建的网络当中

[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat:9.0
87caa4dcc10d9a40c796c143132113d63f74ee744c5b4605d799f1242b475895
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat:9.0 
2a748aa939b4704debd95de41d7778d7c2a480b8a41f36a8fc0c24c420be99ef
[root@localhost ~]# 

我们创建两个容器,配置我们自己创建的网络。

同过docker网络查看我们两个容器的配置信息

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
870e7b5932d7   bridge    bridge    local
b849afd2252a   host      host      local
51276ec9ede3   mynet     bridge    local
a018dbb14fc5   none      null      local
[root@localhost ~]# docker network inspect 51276ec9ede3
[
    {
        "Name": "mynet",
        "Id": "51276ec9ede3d8e0b428f96dbfe6b0cdb6ed8ef8f3ec6fcc8cd40e08390360e4",
        "Created": "2021-08-02T14:11:46.235947859+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2a748aa939b4704debd95de41d7778d7c2a480b8a41f36a8fc0c24c420be99ef": {
                "Name": "tomcat-net-02",
                "EndpointID": "0caa924913d2c7140fb3ab6f756a1df2174810ce79a729d084ec19d7dd800f75",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "87caa4dcc10d9a40c796c143132113d63f74ee744c5b4605d799f1242b475895": {
                "Name": "tomcat-net-01",
                "EndpointID": "42d7ada04da6b9b548057c2f1d55de89960eca4f790250e0fb317b1418150fe4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

现在我们来测试一下:

他们两个之间的互相访问成功

[root@localhost ~]# docker exec -it tomcat-net-02 ping tomcat-net-01   
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.178 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.082 ms
^C
--- tomcat-net-01 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 0.069/0.109/0.178/0.050 ms
[root@localhost ~]# 

我们自定义的网络docker都已经帮我们维护好了对应的关系

好处:

redis-不同的集群使用不同的网络,保证集群是安全和健康

mysql-不同的集群使用不同的网络,保证集群是安全和健康

网路联通

我们使用tomcat02 访问tomcat-02-net

 

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE        COMMAND             CREATED         STATUS         PORTS                                         NAMES
2a748aa939b4   tomcat:9.0   "catalina.sh run"   5 minutes ago   Up 5 minutes   0.0.0.0:49158->8080/tcp, :::49158->8080/tcp   tomcat-net-02
87caa4dcc10d   tomcat:9.0   "catalina.sh run"   6 minutes ago   Up 6 minutes   0.0.0.0:49157->8080/tcp, :::49157->8080/tcp   tomcat-net-01
c0b80e6be2cb   tomcat:9.0   "catalina.sh run"   3 hours ago     Up 3 hours     0.0.0.0:49156->8080/tcp, :::49156->8080/tcp   tomcat03
1c26376153b5   tomcat:9.0   "catalina.sh run"   3 hours ago     Up 3 hours     0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
6c545fef8cc9   tomcat:9.0   "catalina.sh run"   4 hours ago     Up 4 hours     0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@localhost ~]# docker exec -it tomcat-net-02 ping tomcat02
ping: tomcat02: Name or service not known
[root@localhost ~]# 

可以看到的是tomcat02 访问tomcat-02-net是访问不通的

我们查看docker network --help 看有没有解决方法

[root@localhost ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network   #docker给出的方法
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COM

测试打通tomcat01到tomcat-01-net

[root@localhost ~]# docker network connect mynet tomcat01
[root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat01       
PING tomcat01 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.079 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=4 ttl=64 time=0.061 ms
^C
--- tomcat01 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 0.061/0.090/0.135/0.028 ms

我们再来看看mynet里面的信息

[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "51276ec9ede3d8e0b428f96dbfe6b0cdb6ed8ef8f3ec6fcc8cd40e08390360e4",
        "Created": "2021-08-02T14:11:46.235947859+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2a748aa939b4704debd95de41d7778d7c2a480b8a41f36a8fc0c24c420be99ef": {
                "Name": "tomcat-net-02",
                "EndpointID": "0caa924913d2c7140fb3ab6f756a1df2174810ce79a729d084ec19d7dd800f75",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
------------------"重点"----------------------
            "6c545fef8cc9ccebbad800db7bdd2388cea6ec0ad1eb31be1033c6b96d99191a": {
                "Name": "tomcat01",
                "EndpointID": "b055a1f9cf792bb970b11ef63e66f18d093e0e234baa19ab688de14dc42ac288",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "87caa4dcc10d9a40c796c143132113d63f74ee744c5b4605d799f1242b475895": {
                "Name": "tomcat-net-01",
                "EndpointID": "42d7ada04da6b9b548057c2f1d55de89960eca4f790250e0fb317b1418150fe4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

联通之后,就是把tomcat01加入到mynet里面,实际上就是一个容器,两个地址


版权声明:本文为zuodingquan666原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。