docker网络

理解docker0


网卡名词解释:
lo:本机回环地址
ens33(eth0):虚拟机内网地址
docker0:docker地址

  • docker是如何处理容器网路访问的?
  • 测试:
    • 启动一个tomcat
      docker run -d -P --name tomcat01 tomcat
    • 查看当前docker的ip addr
      如果遇到一下错误

      请进入docker容器中输入这条指令:apt-get update & apt-get install -y iproute2
      更新完成后再试试ip addr

      退出容器,然后再使用这个命令在宿主机上查看docker网路
      docker exec -it tomcat01 ip addr

      这时候我们会发现在出来的结果中,有两个网卡,其中有个是4: eth0@if5命名的,我们尝试在宿主机上ping这个地址试试

      我们可以发现,这个网络,我们可以通过宿主机ping通,这时候说明宿主机可以通过网络与docker进行交互
  • 原理说明
    1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0
    2. docker与宿主机是通过桥接模式进行连接的,使用的技术是evth-pair技术

      在这个图中我们可以看见,tomcat01中的网络是4: eth0@if5,而tomcat02中的网络是14: eth0@if15,在宿主机中分别对应的位置是5: vethfb4c1a0@if415: veth225c3a1@if14,我们在这里可以清楚的看见,每一个docker容器中的网络与宿主机中的网络是一对的
      evth-pair技术:就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
  • 两个容器之间是否可以ping通呢?
    随便进入一个容器,我这里进入的是tomcat02中,输入ping tomcat01的ip
    注意,如果报bash: ping: command not found错,可以先输入这个指令apt install iputils-ping然后再ping

    这里我们发现,在一个宿主机上,两个容器之间是可以互相通信的
  • 网络模型图

    我们可以根据这个图看见,tomcat01和tomcat02是公用的一个路由器,docker0
    所有的容器不指定网络的情况下,都是docker0路由的,docker会给容器分配一个默认的可用ip
  • 完整的网络通信图

    docker中的所有的网络接口都是虚拟的,虚拟网络接口转发效率更高(内网传递文件)
    只要删除了容器,对应的网桥也会被删除

我们如果编写一个微服务,database url=ip:,项目不重启,数据库ip被更换了,我们期望处理这些问题,通过名字来进行容器的访问

  • 直接使用名字ping tomcat02
    docker exec -it tomcat01 ping tomcat02

    解决方案:
  1. 启动一个tomcat03,使用--link连接tomcat02
    docker run -d -P --name tomcat03 --link tomcat02 tomcat
    然后再尝试互相是否可以ping通

    我们可以发现,当tomcat03 ping tomcat02的时候,是可以正常ping通的,而tomcat02 ping tomcat03不能通
    查看两者的网络配置

    查看当前docker0网络配置信息
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
39edebf311bb   bridge    bridge    local
f243ef9915d4   host      host      local
71773b54ded7   none      null      local

docker network inspect 39edebf311bb

tomcat03通过--link绑定tomcat02的方法,是因为再tomcat03中的hosts中做了配置转发

[root@localhost ~]# 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.3      tomcat02 4a1dd166490e
172.17.0.4      799985b8ee3e
[root@localhost ~]# docker exec -it tomcat02 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.3      4a1dd166490e

--link一般我们不再推荐使用,一般都是自定义网络

自定义网络

  1. 查看所有的docker网络
    docker network ls
  2. docker中的网络模式
    bridge: 桥接模式(这是默认的模式,创建的时候没有做配置的话,默认使用该模式)
    none: 不配置网络
    host: 与宿主机共享网络
    container: 容器网络联通(用得较少,局限性较大)
  3. 测试与练习
# 之前启动的命令
docker run -it -P --name tomcat01 tomcat
# 其实这个命令有携带默认参数,比如关于网络设置,docker默认为bridge,在上面的命令中体现为--net bridge,命令格式如下
docker run -it -P --name tomcat01 --net bridge tomcat
docker0特点:默认,服务名不能直接访问,需要使用--link打通连接,这样并不方便

# 自定义网络方式
root@vultr:~# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
64c4720a3e4ebaeb8cf455df482fa4a57542263afa6c04e2b2bd578780c1a5e4
root@vultr:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5486a8adb0ed        bridge              bridge              local
b22a9f036cab        host                host                local
64c4720a3e4e        mynet               bridge              local
6fb037b21d6b        none                null                local
root@vultr:~#

# 参数名词解释
--driver bridge: 连接方式,默认就是bridge
--subnet 192.168.0.0/16:子网地址
--gateway 192.168.0.1: 网关
mynet: 网关名
  1. 查看自己创建的网络
docker network inspect mynet

  1. 使用我们自定义的网络创建两个容器看看

    我们可以发现,我们创建了tomcat-net-01和tomcat-net-02这两个容器后,在mynet的网络信息中,就有相关的配置信息了

  2. 尝试容器之间互相ping一下试试

    此处我尝试了四种ping的方案

    • tomcat-net-01 ping tomcat-net-02的ip
    • tomcat-net-02 ping tomcat-net-01的ip
    • tomcat-net-01 ping tomcat-net-02
    • tomcat-net-02 ping tomcat-net-01
  3. 查看两个容器的hosts配置

  4. 结论:

    • 我们自定义的docker网络,修复了docker0的缺陷,不再需要--link去做关联
    • 自定义网络可以实现不同集群的网络隔离,这样可以保证集群网络的安全和健康

不同集群的网络连通

  1. 基于网关docker0和mynet分别构建四个容器,分别是tomcat01,tomcat02,tomcat-net-01,tomcat-net-02
  2. 尝试使用tomcat01 ping tomcat-net-01

    我们会发现,这样是没法ping通的,因为两个容器直接并没有网络接口连接,那么我们应该怎么才能让这两个隶属于不同网卡下的网络通信呢?
  3. 让容器与另一个网卡连接
# 首先我们可以看见,在docker network中有一个参数是connect,代表的是让某一个指定的容器连接到某一个网络
root@vultr:~# 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.

# 再查看docker network connet的介绍文档
root@vultr:~# 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

# 使用connect参数连接tomcat01和mynet,我们可以看见,通过connect参数,我们再mynet中添加了tomcat01的信息,也就是说tomcat01已经联通了mynet
root@vultr:~# docker network connect mynet tomcat01
root@vultr:~# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "64c4720a3e4ebaeb8cf455df482fa4a57542263afa6c04e2b2bd578780c1a5e4",
        "Created": "2022-02-21T15:10:08.182488068+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": {
            "27e1c89d9c3849e28640aed87b3650daf0d7b14e2ddfe16cb01414ec563fce5e": {
                "Name": "tomcat01",
                "EndpointID": "5c22e2003b001025a8154dfb3ea62695e7d2232d3d991746db1498e967362a75",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "3a627a18acf79dbd3047497555f961e37aed410618913a73fb0677494e0fbe0a": {
                "Name": "tomcat-net-01",
                "EndpointID": "cebeda8fa5e0bf75180fd64efb4d97105a695d9f539ea47f5080b38ecacd78e0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "bc6a2cb9a68314ffd8bb78a610c7a9bc5c9f0af133c6673697fae2e339cd6da8": {
                "Name": "tomcat-net-02",
                "EndpointID": "b0d973d595ecbecc14c7700b8cd89a6fcb4844ed1379a6365e6f18614b1a5600",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 使用tomcat01 ping tomcat-net-01和tomcat-net-02试试

root@vultr:~# docker exec -it tomcat01 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.759 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.403 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.105 ms
^C
--- tomcat-net-01 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.105/0.422/0.759/0.267 ms
root@vultr:~# docker exec -it 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.223 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.122 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.103 ms
^C
--- tomcat-net-02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.103/0.149/0.223/0.052 ms

# 再使用tomcat02 ping tomcat-net-01和tomcat-net-02试试

root@vultr:~# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
root@vultr:~# docker exec -it tomcat02 ping tomcat-net-02
ping: tomcat-net-02: Name or service not known
root@vultr:~#

# 总结:这样做,就是一个容器多个ip,类似阿里云中的的服务器,有一个公网ip,同时也有私网ip

网络联通构造图

posted @ 2022-02-20 22:11  影梦无痕  阅读(143)  评论(0)    收藏  举报