> 文章列表 > docker网络详解,自定义docker网络

docker网络详解,自定义docker网络

docker网络详解,自定义docker网络

文章目录

  • 一、初识docker网络
    • 1、docker0虚拟网桥
    • 2、docker网络常用基本命令
    • 3、docker网络可以解决的问题
  • 二、docker网络模式
    • 1、四种网络模式
    • 2、容器实例内默认网络IP生产规则
    • 3、bridge模式
    • 4、host模式
    • 5、none模式
    • 6、container模式
  • 五、自定义网络模式
    • 1、过时的docker link
    • 2、使用自定义网络前
    • 3、使用自定义网络
    • 4、总结

一、初识docker网络

1、docker0虚拟网桥

docker启动之后,在本机网络中会出现一个docker0的虚拟网桥,docker就是在这个网桥的基础上进行网络通讯的。

[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255inet6 fe80::42:55ff:fe91:27de  prefixlen 64  scopeid 0x20<link>ether 02:42:55:91:27:de  txqueuelen 0  (Ethernet)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 5  bytes 446 (446.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.56.10  netmask 255.255.255.0  broadcast 192.168.56.255inet6 fe80::a00:27ff:fedd:f690  prefixlen 64  scopeid 0x20<link>ether 08:00:27:dd:f6:90  txqueuelen 1000  (Ethernet)RX packets 24575  bytes 1971420 (1.8 MiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 20128  bytes 2203182 (2.1 MiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::1  prefixlen 128  scopeid 0x10<host>loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2、docker网络常用基本命令

# 查看网络(安装docker会默认创建3大网络模式)
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ff578279c4c5   bridge    bridge    local
83c25282c4d8   host      host      local
6451c3243251   none      null      local# 查看网络源数据
docker network inspect  XXX网络名字
# 查看 bridge 网络的详细信息
[root@localhost ~]# docker network inspect bridge# 删除网络
docker network rm XXX网络名字# 查看帮助
[root@localhost ~]# docker network --help
Usage:  docker network COMMAND
Manage networks
Commands:connect     Connect a container to a networkcreate      Create a networkdisconnect  Disconnect a container from a networkinspect     Display detailed information on one or more networksls          List networksprune       Remove all unused networksrm          Remove one or more networks

3、docker网络可以解决的问题

容器间的互联和通信以及端口映射。

容器IP变动时候可以通过服务名直接网络通信而不受到影响。

二、docker网络模式

1、四种网络模式

docker总共有四种网络模式:

bridge模式:使用--network  bridge指定,默认使用docker0
host模式:使用--network host指定
none模式:使用--network none指定
container模式:使用--network container:NAME或者容器ID指定
网路模式 简介
bridge 为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,默认为该模式
host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等
container 新建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP,端口范围等

2、容器实例内默认网络IP生产规则

(1)我们分别启动两个ubuntu容器,并且使用ctrl + p + q退出使其后台运行

docker run -it --name u1 ubuntu bash
docker run -it --name u2 ubuntu bash[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED              STATUS              PORTS     NAMES
6bb36da63758   ubuntu    "bash"    56 seconds ago       Up 55 seconds                 u2
ade32205d652   ubuntu    "bash"    About a minute ago   Up About a minute             u1

(2)我们分别查看u1和u2的网络情况

[root@localhost ~]# docker inspect u1 | tail -n 20"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "ff578279c4c58fa49282cbc08832a43eab6ce13d3490fb3c92be3d5d269559d1","EndpointID": "cdb142d2f794f59fdfb1ac3f43ce16875c9de5e6ede5507c0bb255caff5c4063","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
]
[root@localhost ~]# docker inspect u2 | tail -n 20"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "ff578279c4c58fa49282cbc08832a43eab6ce13d3490fb3c92be3d5d269559d1","EndpointID": "10c4b59a121375c0345b5488148b18f0833f62f0726e9eec38482569ddc0e374","Gateway": "172.17.0.1","IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:03","DriverOpts": null}}}}
]

我们可以看出,u1的ip是172.17.0.2,u2的ip是172.17.0.3,并且都使用bridge的模式。

(3)我们删掉u2,再启动一个u3

docker rm -f 6bb36da63758
docker run -it --name u3 ubuntu bash[root@localhost ~]# docker inspect u3 | tail -n 20"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "ff578279c4c58fa49282cbc08832a43eab6ce13d3490fb3c92be3d5d269559d1","EndpointID": "9643672d66cd69ed297556f3b2345199eeff3d77e8af977d0946be67a52a82ee","Gateway": "172.17.0.1","IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:03","DriverOpts": null}}}}
]

我们查看u3的网络,发现u3的网络和原来的u2是一样的,对于这种变化不定的网络,我们是需要进行配置的。

3、bridge模式

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

1 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

2 docker run 的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址

3 网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
3.1 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
3.2 每个容器实例内部也有一块网卡,每个接口叫eth0;
3.3 docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

docker网络详解,自定义docker网络

我们分别启动两个容器,对网络进行验证,发现确实是容器中eth0和宿主机veth一一对应的。
docker网络详解,自定义docker网络

4、host模式

host模式直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 网桥转换。

容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
docker网络详解,自定义docker网络

# 使用host模式启动tomcat,如果仍然指定端口的话,会出现警告
docker run -d -p 8083:8080 --network host --name tomcat tomcat
# WARNING: Published ports are discarded when using host network mode# 不需要指定端口
docker run -d --network host --name tomcat tomcat# 使用host模式不会有端口映射
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                       NAMES
d8d2e6b0dd23   tomcat    "catalina.sh run"   2 seconds ago    Up 1 second     0.0.0.0:8083->8080/tcp, :::8083->8080/tcp   tomcat2
afca1328da50   tomcat    "catalina.sh run"   3 minutes ago    Up 3 minutes                                                tomcat

docker启动时指定–network=host或-net=host,如果还指定了-p映射端口,那这个时候就会有此警告,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。

此时,不管是在宿主机还是容器中,使用ip addr显示的内容是一样的,因为都是使用的宿主机的网卡。

5、none模式

禁用网络功能,只有lo标识(就是127.0.0.1表示本地回环)

# 使用none模式
docker run -d -p 8084:8080 --network none --name tomcatnone tomcat

此时,进入容器之后,使用ip addr命令,只有127.0.0.1网络。

none模式几乎很少用。

6、container模式

新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
docker网络详解,自定义docker网络

# 启动一个unbutu
docker run -it --name u1 ubuntu bash# 启动第二个
docker run -it --network container:u1 --name u2  ubuntu bash

我们分别在两个容器中使用ip addr查看网络,发现是一致的:
docker网络详解,自定义docker网络
此时我们关闭u1容器,发现u2容器之后一个lo回环地址了,再启动u1也不会出现新的网络。

五、自定义网络模式

1、过时的docker link

官网提示,link模式在后续版本可能会被移除掉。
官网:https://docs.docker.com/network/links/
docker网络详解,自定义docker网络

2、使用自定义网络前

# 启动一个unbutu,默认使用网桥模式bridge
docker run -it --name u1 ubuntu bash# 启动第二个,默认使用网桥模式bridge
docker run -it --name u2  ubuntu bash

通过ip addr我们发现,u1的ip是172.17.0.2,u2的ip是172.17.0.3,使用ping命令可以互相ping通。
docker网络详解,自定义docker网络
docker网络详解,自定义docker网络
但是互相ping名字的话,会出现服务找不到的问题。
docker网络详解,自定义docker网络

3、使用自定义网络

# 新建自定义桥接网络,自定义网络默认使用的是桥接网络bridge
[root@localhost /]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ff578279c4c5   bridge    bridge    local
83c25282c4d8   host      host      local
6451c3243251   none      null      local
[root@localhost /]# docker network create my_network
a83033be4cba946e5bd8795401a0710aac368f71989e247bebe2a32b4b80e6a7
[root@localhost /]# docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
ff578279c4c5   bridge       bridge    local
83c25282c4d8   host         host      local
a83033be4cba   my_network   bridge    local
6451c3243251   none         null      local
# 启动ubuntu容器,并指定自定义的网络
docker run -it --network my_network --name u3 ubuntu
docker run -it --network my_network --name u4 ubuntu
# ping ip 可以ping通
ping 172.19.0.2# ping服务名,也可以ping通!
ping u4

4、总结

自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)