docker学习---网络知识

1. 网络知识

ip addr

root@ubuntu:/# 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:0a:87:9d brd ff:ff:ff:ff:ff:ff
    inet 192.168.240.143/24 brd 192.168.240.255 scope global dynamic ens33
       valid_lft 1366sec preferred_lft 1366sec
    inet6 fe80::feac:5bc6:f91d:a3bc/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:66:78:0e:c4 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:66ff:fe78:ec4/64 scope link 
       valid_lft forever preferred_lft forever
79: vetha37276e@if78: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether de:3c:77:04:ab:5b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::dc3c:77ff:fe04:ab5b/64 scope link 
       valid_lft forever preferred_lft forever
81: veth962d582@if80: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether f2:ea:ed:db:66:9a brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::f0ea:edff:fedb:669a/64 scope link 
       valid_lft forever preferred_lft forever

 

  • lo:本地回环地址
  • ens33:阿里云服务器的地址/外网地址
  • docker0:docker自己的网卡地址

尝试一下,运行一个tomcat容器,执行容器的ip addr命令。

 

docker pull tomcat

docker run -d -p 8899:80 --name tomcat_test tomcat

root@ubuntu:/# docker exec -it tomcat_test 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
80: eth0@if81: <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

 

  • 80: eth0@if81: 80端口映射到这个网址上,172.17.0.3/16

尝试宿主机ping这个ip地址,发现是可以ping的通的

root@ubuntu:/# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.113 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.070 ms

 

 

但是宿主机访问:http://127.0.0.1:8899/  

 

 

 

为什么宿主机能够ping通容器内部呢?

原因:

1. 安装docker后,会自动获得docker0这个网卡,172.17.0.1,这个网卡,会给每个运行的容器分配一个网址,和docker0为同网段

 

宿主机的docker0

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:66:78:0e:c4 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:66ff:fe78:ec4/64 scope link 
       valid_lft forever preferred_lft forever

 

运行的容器ip addr

80: eth0@if81: <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

 

容器和宿主机的dokerfile0都在172.17.0 网段中

2. 继续启动一个tomacat_test02, 查看宿主机的ip addr

 

root@ubuntu:/# docker run -d -P --name tomcat_test1 tomcat
44b9784af5deac72250ed09b4eae1419c471b22b778fe84c92c67e3189296f64
root@ubuntu:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44b9784af5de tomcat "catalina.sh run" 5 seconds ago Up 4 seconds 0.0.0.0:49154->8080/tcp tomcat_test1
ea93ce0a1e43 tomcat "catalina.sh run" 27 seconds ago Up 26 seconds 0.0.0.0:49153->8080/tcp tomcat_test
f977ada284aa nginx "/docker-entrypoint.…" About an hour ago Up 59 minutes 0.0.0.0:8888->80/tcp nginx_test
root@ubuntu:/#

 

 

ip addr

root@ubuntu:/# 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:0a:87:9d brd ff:ff:ff:ff:ff:ff
    inet 192.168.240.143/24 brd 192.168.240.255 scope global dynamic ens33
       valid_lft 1733sec preferred_lft 1733sec
    inet6 fe80::feac:5bc6:f91d:a3bc/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:66:78:0e:c4 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:66ff:fe78:ec4/64 scope link 
       valid_lft forever preferred_lft forever
79: vetha37276e@if78: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether de:3c:77:04:ab:5b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::dc3c:77ff:fe04:ab5b/64 scope link 
       valid_lft forever preferred_lft forever
83: veth1105325@if82: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ce:b4:57:7e:32:12 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ccb4:57ff:fe7e:3212/64 scope link 
       valid_lft forever preferred_lft forever
# 新多出来的配置
85: vethb1aba67@if84: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 82:ce:fc:cb:8e:29 brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::80ce:fcff:fecb:8e29/64 scope link valid_lft forever preferred_lft forever

 

进入tomcat_test1里面,查看ip addr 

root@ubuntu:/# docker exec -it 44b9784af5de 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

# 和宿主机ipp addr 新出来的配置对应上了
84: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

总结:

容器的网卡都是一对对出现的,使用的技术是 evth-pair技术

evth-pair 是一对的虚拟设备接口,成对出现

evth-pair 充当一个桥梁,连接各种虚拟网络设备

Openstack, Docker,Ovs的连接,都是用这种技术。

 

测试tomcat_test和tomcat_test1是否可以互相ping通?可以

用tomcat_test来ping tomcat_test1的网路
root@ubuntu:/# docker exec -it ea93ce0a1e43 ping 172.17.0.4 PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data. 64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.074 ms 64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.088 ms 64 bytes from 172.17.0.4: icmp_seq=3 ttl=64 time=0.084 ms 64 bytes from 172.17.0.4: icmp_seq=4 ttl=64 time=0.085 ms 64 bytes from 172.17.0.4: icmp_seq=5 ttl=64 time=0.114 ms 64 bytes from 172.17.0.4: icmp_seq=6 ttl=64 time=0.086 ms ^C

 

 

理解 docker0 作为一个路由器的作用

 

 

  •  tomcat01和tomcat02直接的通信,也是需要走docker0才能完成

 

使用场景:一个微服务(镜像),里面有mysql,供其他的微服务去连接,每次启动docker,ip地址就会改变,那么连接这个微服务的其他容器就要修改连接地址,很麻烦,怎么解决?

  • 通过名字进行访问,不需要通过ip,例如tomcat_test如何不通过ip去访问tomcat_test1,
root@ubuntu:/# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                     NAMES
44b9784af5de   tomcat    "catalina.sh run"        44 minutes ago   Up 44 minutes   0.0.0.0:49154->8080/tcp   tomcat_test1
ea93ce0a1e43   tomcat    "catalina.sh run"        44 minutes ago   Up 44 minutes   0.0.0.0:49153->8080/tcp   tomcat_test
f977ada284aa   nginx     "/docker-entrypoint.…"   2 hours ago      Up 2 hours      0.0.0.0:8888->80/tcp      nginx_test
root@ubuntu:/# docker exec tomcat_test ping tomcat_test1
ping: tomcat_test1: Name or service not known

 

  发现直接使用名字ping不通,决绝办法,在启动的时候指定 link + 容器名,以连接的方式启动就可以解决

  启动一个新的容器,tomcat_test2, 指定连接tomcat_test

root@ubuntu:/# docker run -d -P --name tomcat_test2 --link tomcat_test tomcat
6d1cf33d549d1fa4212111f17316f497fa36aed26a7fdcd764755d97f59bad4f
root@ubuntu:/# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                     NAMES
6d1cf33d549d   tomcat    "catalina.sh run"        7 seconds ago    Up 6 seconds    0.0.0.0:49155->8080/tcp   tomcat_test2
44b9784af5de   tomcat    "catalina.sh run"        48 minutes ago   Up 48 minutes   0.0.0.0:49154->8080/tcp   tomcat_test1
ea93ce0a1e43   tomcat    "catalina.sh run"        48 minutes ago   Up 48 minutes   0.0.0.0:49153->8080/tcp   tomcat_test
f977ada284aa   nginx     "/docker-entrypoint.…"   2 hours ago      Up 2 hours      0.0.0.0:8888->80/tcp      nginx_test
root@ubuntu:/# docker exec tomcat_test ping tomcat_test2  # 说明是单向连接
ping: tomcat_test2: Name or service not known
root@ubuntu:/# docker exec tomcat_test2 ping tomcat_test
PING tomcat_test (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat_test (172.17.0.3): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from tomcat_test (172.17.0.3): icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from tomcat_test (172.17.0.3): icmp_seq=3 ttl=64 time=0.087 ms
64 bytes from tomcat_test (172.17.0.3): icmp_seq=4 ttl=64 time=0.085 ms

 

  缺点:单向连接

  本质是:link 后在tomcat_test2的hosts文件增加一个映射,通过名字映射  172.17.0.3 tomcat_test ea93ce0a1e43

root@ubuntu:/# docker exec tomcat_test2 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    tomcat_test ea93ce0a1e43
172.17.0.5    6d1cf33d549d

 

真实的docker使用中,不适用docker0,使用自定义的网桥

 

 

自定义网桥docker0

查看docker网络

docker network --help

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

root@ubuntu:/# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
27c309a6abdf   bridge    bridge    local
18af791e92f9   host      host      local
ea89697bdfc3   none      null      local
  • bridge:桥接模式,默认模式
  • host:和宿主机共享网络
  • none:不配置网络 

自定义网桥的优点就是,不用link,容器指定了自定义网桥后,里面的所有容器都可以通过名字进行ping和连接

root@ubuntu:/# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

 

删除前面所有的容器

创建自己的桥接网络

root@ubuntu:/# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
5724b1e3ee3b3e3365ead34386f45a952b4f8be11579c4de89a9ca46d1122f74
root@ubuntu:/# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
27c309a6abdf   bridge    bridge    local
18af791e92f9   host      host      local
5724b1e3ee3b   mynet     bridge    local
ea89697bdfc3   none      null      local

--driver 指定模式 选择桥接模式
--subnet 指定子网,它能支持的所有子网的规则
--gateway 指定
网关,所有的请求都经过它。

 

查看我们创建的桥接网络mynet

root@ubuntu:/# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "5724b1e3ee3b3e3365ead34386f45a952b4f8be11579c4de89a9ca46d1122f74",
        "Created": "2021-02-18T16:05:29.590111897+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_test01和tomcat_test02,指定网络为 mynet

root@ubuntu:/# docker run -d -P --name tomcat_test01 --net mynet tomcat
8eed2ec3c79d14860fd0cd2db329e550006d24ff2bef5132ad27ff17d0fcad74
root@ubuntu:/# docker run -d -P --name tomcat_test02 --net mynet tomcat
5f4e4e8dc075450a15fccc230d8822912b8662b035640f4e511654f98b46eb1b
root@ubuntu:/# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                     NAMES
5f4e4e8dc075   tomcat    "catalina.sh run"   7 seconds ago    Up 5 seconds    0.0.0.0:49157->8080/tcp   tomcat_test02
8eed2ec3c79d   tomcat    "catalina.sh run"   12 seconds ago   Up 11 seconds   0.0.0.0:49156->8080/tcp   tomcat_test01

 

两个容器互相通过名字ping对方

root@ubuntu:/# docker exec -it tomcat_test01 ping tomcat_test02
PING tomcat_test02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat_test02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from tomcat_test02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from tomcat_test02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.097 ms
^C
--- tomcat_test02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 39ms
rtt min/avg/max/mdev = 0.064/0.085/0.097/0.016 ms
root@ubuntu:/# ^C
root@ubuntu:/# docker exec -it tomcat_test02 ping tomcat_test01
PING tomcat_test01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat_test01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.038 ms
64 bytes from tomcat_test01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.097 ms
64 bytes from tomcat_test01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.096 ms
64 bytes from tomcat_test01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.150 ms
64 bytes from tomcat_test01.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.096 ms
^C
--- tomcat_test01 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 107ms
rtt min/avg/max/mdev = 0.038/0.095/0.150/0.036 ms

 

这就是我们自定义网络的好处一:不需要 link就可以让下面所有的容器通过名字进行连接

root@ubuntu:/# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "5724b1e3ee3b3e3365ead34386f45a952b4f8be11579c4de89a9ca46d1122f74",
        "Created": "2021-02-18T16:05:29.590111897+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": {
            "5f4e4e8dc075450a15fccc230d8822912b8662b035640f4e511654f98b46eb1b": {
                "Name": "tomcat_test02",
                "EndpointID": "e96c6af9c566012c28e9c2d25eb3f4e0559998e992c6485203ef6818b1415317",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "8eed2ec3c79d14860fd0cd2db329e550006d24ff2bef5132ad27ff17d0fcad74": {
                "Name": "tomcat_test01",
                "EndpointID": "8649791467e72e8febf00ef3053515540d19d1abf1e3c06023d83195db71960a",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

 

这就是我们自定义网络的好处二:指定gateway后,保证了我们不同集群之间数据安全和健康

 

 

需求二:默认的网络启动两个tomcat_test_001和tomcat_test_002,如何让 tomcat_test_001去和mynet下的tomcat_test01进行连接呢?

docker network --help

Commands:
  connect Connect a container to a network

root@ubuntu:/# docker run -d -P --name tomcat_test_001 tomcat
b0be1fdf3f47554f8918c194a6378fb807605fe4dc50245940cb577f767fc1f5
root@ubuntu:/# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                     NAMES
b0be1fdf3f47   tomcat    "catalina.sh run"   3 seconds ago    Up 2 seconds    0.0.0.0:49158->8080/tcp   tomcat_test_001
5f4e4e8dc075   tomcat    "catalina.sh run"   18 minutes ago   Up 17 minutes   0.0.0.0:49157->8080/tcp   tomcat_test02
8eed2ec3c79d   tomcat    "catalina.sh run"   18 minutes ago   Up 18 minutes   0.0.0.0:49156->8080/tcp   tomcat_test01
root@ubuntu:/# docker exec tomcat_test_001 ping tomcat_test01
ping: tomcat_test01: Name or service not known

 

发现ping不通

 

未完待续

 

 

 

 

 

 

###

posted @ 2021-01-28 13:52  张京墨  阅读(154)  评论(0编辑  收藏  举报