Docker 网络模式
文章目录
docker 默认安装的网络
- 安装 Docker 以后,会默认创建三种网络,可以通过
docker network ls
查看。
网络模式介绍
网络模式 | 简介 |
---|---|
none | 容器有独立的 Network namespace,但并没有对其进行任何网络设置。 |
host | 使用宿主机的端口和ip,容器不会虚拟出自己的网络,配置自己的ip等 |
bridge | 容器默认 使用该模式,会为每一个容器分配、设置 IP 等,并将容器连接到宿主机的docker0 虚拟网桥 |
container | 新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。 |
overlay | 后续再讲 |
1.none 网络模式
- 表示禁用网络,只有lo接口。在创建容器时通过参数 --net none 或者 --network none 指定。
可以通过docker inspect 【网络模式】
查看该模式的信息,在 Containers 节点中可以看到容器名称。我这里没有容器使用了none网络,所以没有containers节点。
2. host 网络模式
- host 网络模式需要在创建容器时通过参数 --net host 或者 --network host 指定。
- 此时容器共享宿主机的Network Namespace,容器内启动的端口直接是宿主机的端口,容器不会创建网卡和IP,直接使用宿主机的网卡和IP,但是容器内的其他资源是隔离的,如文件系统、用户和用户组。直接使用宿主机网络。同样启动一个nginx,此时共享主机网络,根据情况来使用,这样子也不用做端口转发,网络传输效率会比较高。
-
注意
的是,此时的-p 参数,也就是端口映射是无效的,host模式会默认把容器监听的端口映射到宿主机,可通过Dockerfile的EXPOSE来进行修改。
下面我使用了host运行了一个busybox容器
进入容器并查看容器的网络
查看宿主机的网络
返回的信息一摸一样,可以通过 docker inspect host
进一步验证
3. bridge 网络模式
- 在该模式中,Docker 守护进程创建了一个虚拟以太网桥 docker0,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。
- 默认情况下,守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。
- 关于bridge网络模式的使用,在创建容器时通过参数 --net bridge 或者 --network bridge 指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。
下面运行一个busybox容器为例:
容器内部发现了eth0这个接口,然后宿主机通过 ip addr 查看信息如下:
通过以上的比较可以发现,证实了之前所说的:守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名。
同时,守护进程还会从网桥 docker0 的私有地址空间中分配一个 IP 地址和子网给该容器,并设置 docker0 的 IP 地址为容器的默认网关。也可以安装 yum install -y bridge-utils 以后,通过 brctl show 命令查看网桥信息。
使用brctl show 命令查看网桥信息如下:
对于容器的信息,如它的gateway、ip等,可通过docker inspect [容器ID|名称]
来进行查看
Bridge 桥接模式的实现步骤主要如下:
- Docker Daemon 利用 veth pair 技术,在宿主机上创建一对对等虚拟网络接口设备,假设为 veth0 和 veth1。
- veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,宿主机的网络报文若发往 veth0,则立即会被 Container 的 eth0 接收,实现宿主机到 Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。
4.container 网络模式
- Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。
- 处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。
- 使用方式:创建容器时时通过参数 --net container:已运行的容器名称|ID 或者 --network container:已运行的容器名称|ID 指定
基于容器 busybox容器 创建了 container 网络模式新的容器 busybox2,查看 ip addr:
进去busybox 容器 查看网络:
宿主机网络:
自定义网络
使用docker 网络帮助命令
命令格式 docker network --help
1.创建网络
命令格式 docker network create
进一步查看帮助命令
创建一个基于 bridge 网络模式的自定义网络模式 my_network
使用 docker network inspect [network id |name]
进一步查看自定义出来的网络信息
通过自定义网络模式 my_network 创建容器:
通过docker container inspect [容器id|名称]
查看该容器具体信息
2. 连接网络
可以看到,busybox容器使用了自定义的my_network,那我再想连接新的bridge怎么办呢?使用docker network connect
命令就可以解决,查看帮助命令如下:
为busybox 增加新的网络连接
3. 断开网络
通过 docker network disconnect 网络名称 容器名称
命令断开网络。
4. 移除网络
-
可以通过
docker network rm 网络名称
命令移除自定义网络模式,网络模式移除成功会返回网络模式名称。 -
如果通过某个自定义网络模式创建了容器,则该网络模式无法删除。
容器间的通信
- 容器之间要互相通信,必须要有属于同一个网络的网卡。
使用默认的bridge创建两个容器:
使用docker network inspect bridge
查看两个容器的ip:
测试两个容器间是否可以进行通信
双方都可以ping 通,但ip可能是不固定的,有被更改的情况发生,容器内所有通信的ip也需要跟着改,这种情况下,可以通过容器名称进行通信。
使用容器名称进行通信的前提:
- 从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 --name 为容器命名即可。
- 但是使用 Docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。
先基于bridge网络模式创建自己的网络
运行容器,指定自定义的网络:
测试成功: