docker之network八股

72 阅读7分钟

参考链接

# Docker 学习笔记(九):Docker 网络原理,理解 docker0,虚拟网卡,容器互联,以及跨网络连通

docker系列视频

准备

在服务器不启动docker的时候,ifconfig如下:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.246.18  netmask 255.255.240.0  broadcast 172.16.255.255
        inet6 fe80::216:3eff:fe34:5d7e  prefixlen 64  scopeid 0x20<link>
        ether 00:16:3e:34:5d:7e  txqueuelen 1000  (Ethernet)
        RX packets 69604522  bytes 39147556348 (39.1 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 323889888  bytes 43639431108 (43.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 564477  bytes 50405358 (50.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 564477  bytes 50405358 (50.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker启动后,ifconfig如下:

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:e2ff:fe49:8500  prefixlen 64  scopeid 0x20<link>
        ether 02:42:e2:49:85:00  txqueuelen 0  (Ethernet)
        RX packets 1066530  bytes 1564182332 (1.5 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 757155  bytes 147096440 (147.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.246.18  netmask 255.255.240.0  broadcast 172.16.255.255
        inet6 fe80::216:3eff:fe34:5d7e  prefixlen 64  scopeid 0x20<link>
        ether 00:16:3e:34:5d:7e  txqueuelen 1000  (Ethernet)
        RX packets 69604522  bytes 39147556348 (39.1 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 323889888  bytes 43639431108 (43.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 564477  bytes 50405358 (50.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 564477  bytes 50405358 (50.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

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

当我们在 Linux 宿主机中安装了 Docker:

  • 宿主机中就会配置 docker0 网卡,docker0 使用的是 Linux 桥接模式,使用的技术是 Veth-pair 技术。
  • 每启动一个 Docker 容器,Docker 就会给该容器分配一个 ip,一对虚拟网卡。

docker network

root@td1:~/docker-compose# 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 ls

docker安装好以后会默认创建以下三种网络:

root@td1:~/docker-compose# docker network ls
NETWORK ID     NAME                        DRIVER    SCOPE
7dff37a7f30c   bridge                      bridge    local
d1f58e4a2d6f   host                        host      local
41a55fca9fde   none                        null      local

docker network inspect bridge查看所有使用bridge网络的容器

docker network的五种网络模式

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

bridge模式

  1. Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
  2. docker run的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是dockerO。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2...代表网卡一,网卡二,网卡三...…,lo代表127.0.0.1,即localhost,inetaddr用来表示网卡的lP地址
  3. 网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。

image.png

  1. 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
  2. 每个容器实例内部也有一块网卡,每个接口叫eth0;
  3. docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。

通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

在容器内部或容器外部运行ip addr查看网卡,验证上图所述内容

host模式

容器将不会获得一个独立的NetworkNamespace,而是和宿主机共用一个NetworkNamespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。

image.png

none模式

在none模式下,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo 需要我们自己为Docker容器添加网卡、配置IP等。

进入none网络模式的容器ip addr查看网卡只会有一个lo回环网卡,就是只能访问自己

container模式

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

image.png

# 默认是桥接模式
docker run -it --name alpine1 alpine /bin/sh
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh

在两个容器内部运行ip addr查看网卡情况发现是一致的,如下:

/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
3497: eth0@if3498: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

在停止alpine1容器后,在alpine2容器内部运行ip addr结果如下:

/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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

自定义模式

创建一个bridge模式的网络my_network

dokcer network create my_network

以my_network网络运行alpine容器

docker run -it --network my_network --name alpine2 alpine /bin/sh