八、Docker:Docker网络原理

其他文章:

一、Docker:概述

二、Docker:安装

三、Docker:命令

四、Docker:可视化管理

五、Docker:镜像(image)

六、Docker:数据卷

七、Docker:DockerFile

八、Docker:Docker网络原理

九、Docker:IDEA整合Docker

----------------------------------------------------------------

八、Docker网络原理

解决的问题:docker如何处理容器之间的网络访问

测试

# 一、查看本宿主机的 ip addr
[root@kk ~]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:c1:13:6d brd ff:ff:ff:ff:ff:ff
    inet 192.168.204.130/24 brd 192.168.204.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::62dc:f8a3:a777:e321/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:c3:d5:6c brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:c3:d5:6c brd ff:ff:ff:ff:ff:ff  
# 给docker分配了一个ip。只有安装启动了docker-server就会虚拟出一个docker的网卡:docker0,地址为172.17.0.1/16
# docker内部的容器都是通过这个docker0网卡的桥接方式进行通信的。
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:00:eb:57:0d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ff:feeb:570d/64 scope link 
       valid_lft forever preferred_lft forever
      
      
      
      
# 二、启动tomcat,并查看容器内部的 ip addr
# 1.下载tomcat  以后台的方式进行运行
docker run -d -it -P --name tomcat01 tomcat

# 2. 查看容器tomcat01的内部ip       eth0@if27 此地址为 docker自动生成 地址为:172.17.0.2/16
[root@kk ~]# docker exec  -it tomcat01 ip addr # 不进入容器,直接查看ip
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
26: eth0@if27: <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     
 #3. 在宿主机上测试容器内部ip地址能否通信   ping 172.17.0.2
[root@kk ~]# 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.070 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.048 ms




# 三、在宿主机中再次ip addr 发现 多了一个 网卡
[root@kk ~]# ip addr
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:00:eb:57:0d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ff:feeb:570d/64 scope link 
       valid_lft forever preferred_lft forever
 # 此处即是  启动容器后  产生的新的网卡
27: veth8a743b7@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:9f:47:48:82:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::9f:47ff:fe48:82cc/64 scope link 
       valid_lft forever preferred_lft forever
 # 再次启动第二个tomcat02容器后,又多了一对网卡 
29: veth56293aa@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 36:ec:01:06:de:d7 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::34ec:1ff:fe06:ded7/64 scope link 
       valid_lft forever preferred_lft forever




# 四、测试两个容器tomcat01和tomcat02之间的通信
# 查看容器tomcat02的内部ip       eth0@if29 此地址为 docker自动生成 地址为:172.17.0.3/16
[root@kk ~]# docker exec tomcat02 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
28: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 查看容器tomcat01的内部ip       eth0@if27 此地址为 docker自动生成 地址为:172.17.0.2/16       
[root@kk ~]# docker exec 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
26: eth0@if27: <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

# 两个容器之间可以完美通信(tomcat02容器可以ping通comcat01的ip)
[root@kk ~]# docker exec 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.170 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.074 ms

原理

  • 我们发现每个容器启动后,会在容器内部生成一个网卡,同时会在宿主机中生成一个网卡,这两个网卡是对应的,有关联关系,并且是成对出现的。
  • veth-pair就是一对的虚拟设备接口,他们都是成对出现的
  • 一段连着协议,一段彼此相连正因为有这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备的
  • 只要容器删除,对应网桥一对就没了!

image-20210507191410449

小结

tomcat01和 tomcat02是公用的一个路由器, docker0所有的容器不指定网络的情况下,都是 docker0路由的, docker会给我们的容器分配一个默认的可用。

可以通过docker run --net=网络名称 指定使用名称。默认--net=docker0

image-20210416192102726

容器网络连通方式:–-link

思考一个场景,我们编写了一个微服务, database url:=ip:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以名字来进行访问容器?

测试
# 1.直接用容器名称ping  不通
[root@kk ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known

#2. 用  --link  命令启动    单向可以ping 通
[root@kk ~]# docker run -d -it -P --name tomcat03 --link tomcat01 tomcat
02978b9e75c3d8c094ecc8cb74cb32ed4fbf92ef2f6eb53331eff5677c2a47ab
[root@kk ~]#  docker exec -it tomcat01 ping tomcat03
ping: tomcat03: Name or service not known
[root@kk ~]#  docker exec -it tomcat03 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.325 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.085 ms
单向联通的原因
[root@kk ~]#  docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	tomcat01 2b05ac88444c #  tomcat03 中直接指明了  tomcat01 的ip
172.17.0.4	02978b9e75c3
[root@kk ~]#  docker exec -it tomcat01 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	2b05ac88444c   #  tomcat01 中没有 tomcat03的地址
本质探究

link就是我们在 tomcat03 的 hosts配置中增加了一个172.17.0.2 tomcat01 2b05ac88444c

我们现在玩 Docker已经不建议使用link

上面的测试都是基于docker0网卡!能不能自定义网络?

docker问题:他不支持容器名连接访问

自定义网络连接

网络模式
  • bridge:桥接 docker0 (默认,自己创建也使用 bridge模式)
  • none:不配置网络
  • host:和宿主机共享网络
  • container:容器网络连通!(用的少!局限很大)
#我们可以自定义一个网络
# --driver bridge	
#-- subnet 192.168.0.0/16
#-- gateway 192.168.0.1
[root@kk ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
21501df4c37c77fcbb0c61b3bdd776ede7a29802c8234413bbb85e525722a087
[root@kk ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
275762873e27   bridge    bridge    local
9293b8c12edf    host      host      local
21501df4c37c   mynet     bridge    local
dca3d5c20357   none      null      local

# 查看自定义网络的信息
[root@kk ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "21501df4c37c77fcbb0c61b3bdd776ede7a29802c8234413bbb85e525722a087",
        "Created": "2021-04-16T20:30:22.78506401+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": {},
        "Options": {},
        "Labels": {}
    }
]
在自定义的网络里启动两个tomcat
# 使用 --net mynet指定网络 默认是docker0
[root@kk ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
6f693e658afec4ac39c6c7f762c0bfa5be5da2bfe1730b7a8ae059e441edb1d5
[root@kk ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
38934ce91b2b6ddf51ae3933b7733818ce4319620cf520d88c262ed403b49459

# 查看自定义的网络,发现里面多了两个容器的信息
[root@kk ~]# docker network inspect mynet
[
   ...
        "Containers": {
            "38934ce91b2b6ddf51ae3933b7733818ce4319620cf520d88c262ed403b49459": {
                "Name": "tomcat-net-02",
                "EndpointID": "2a1baa06127e83037dfbc53523f7a749b3246026489de88a1c566739c7a315eb",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "......: {
                "Name": "tomcat-net-01",
                "EndpointID": "........",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
       ...
]

# 两个容器之间相互用 名称 ping
[root@kk ~]# docker exec tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.066 ms

[root@kk ~]# docker exec 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.055 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.078 ms

小结

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

推荐我们平时这样使用网络!

好处:

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

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

两个网络之间的联通

docker自带的网络是docker0,上面我们自定义的网络是mynet,这两个网络中的容器如何通讯?

# 1.在默认的 dockers0 下开启一个 tomcat
[root@kk ~]# docker run -d -P --name tomcat01 tomcat
4d46cb8b8200848e6ba095d7d0fb76a73470653b72efbbf7a480fce6c4070d8b

#2.测试  该 docker0 下的 tomcat 与 mynet 下的 tomcat-net-02  之间的通信   无法联通
[root@kk ~]# docker exec tomcat01 ping tomcat-net-02
ping: tomcat-net-02: Name or service not known

[root@kk ~]# docker network connect --help
Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container
   
 #3.使用  docker network connect   将容器和网络联通
 # tomcat01本来在docker0网络,这里再加入到mynet网络,相当于一台服务器有两个ip,内网ip和外网ip.
[root@kk ~]# docker network connect mynet tomcat01
[root@kk ~]# docker network inspect mynet
[
 		...
        "Containers": {
            "38934ce91b2b6ddf51ae3933b7733818ce4319620cf520d88c262ed403b49459": {
                "Name": "tomcat-net-02",
                "EndpointID": "2a1baa06127e83037dfbc53523f7a749b3246026489de88a1c566739c7a315eb",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
   #4. 发现此处多了一个 容器    即   tomcat01 有两个地址,一个在网络  docker0   一个就是 mynet
            "4d46cb8b8200848e6ba095d7d0fb76a73470653b72efbbf7a480fce6c4070d8b": {
                "Name": "tomcat01",
                "EndpointID": "39f637c20175499052aa4474ba9022de1bf23ffe2a86fbcdd5155ac5f3f7309a",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "6f693e658afec4ac39c6c7f762c0bfa5be5da2bfe1730b7a8ae059e441edb1d5": {
                "Name": "tomcat-net-01",
                "EndpointID": "ecc240f9051d0d64ee773eba961761e739cd31d4d83e1f6a4d04df4f712c75d8",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
    ...
]

# 5.再次测试 两者之间的联通情况   成功ping通,相互均可访问
[root@kk ~]# docker exec tomcat01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.148 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.066 ms

[root@kk ~]# docker exec 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.076 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.080 ms

结论: 假设要跨网络操作,就需要使用 docker network connect连通!

实战 部署redis集群

快速部署,高可用,主机故障后从机可以使用。

略。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值