Docker网络详解
Docker网路基础理论
docker使用Linux桥接网卡,在宿主机虚拟一个docker容器网桥(docker0),docker启动一个容器时会根据docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网络网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。
如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过-p或-P参数来启用,访问容器的时候就通过宿主机IP:容器端口
访问容器。
Docker网络模式
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | –net=host | 容器和宿主机共享Network namespace 。 容器将不会虚拟出自己的网卡,配置自己的IP 等,而是使用宿主机的IP和端口。 |
container模式 | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace 。kubernetes中的pod就是多个容器共享一个Network namespace。 创建的容器不会创建自己的网卡,配置自己的 IP, 而是和 一个指定的容器共享IP、端口范围 。 |
none模式 | –net=none | 容器有独立的Network namespace,并没有对其进行任何网络设置,如分配veth pair和网桥连接,配置IP等。该模式关闭了容器的网络功能。 |
bridge模式 | –net=bridge | (默认模式)。此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥 ,通过docker0网桥 以及Iptable nat 表配置与宿主机通信 |
Macvlan network |
无 | 容器具备Mac地址,使其显示为网络上的物理 设备 |
Overlay | 无 | (覆盖网络): 利用VXLAN实现的bridge模式 |
bridge模式
默认的网络模式。bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的,但容器通过宿主机的NAT规则后可以访问外网。
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则立即会被eth0接收,实现宿主机到Docker Container网络的联通性;同时也保证Docker Container单独使用eth0,实现容器网络环境的隔离性。
Bridge桥接模式的缺陷
Docker Container不具有一个公有IP,即和宿主机eth0不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。
注意
eth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth(通常命名为veth),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。
Host网络模式
host模式相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址
。
启动容器使用host模式,容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。
容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。除此之外容器的其他方面,比如文件系统、进程列表等还是和宿主机隔离
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好
,docker host上已经使用的端口就不能再用了,网络的隔离性不好。
host网络模式需要在容器创建时指定–network=host
host模式是bridge桥接模式很好的补充。采用host模式的Docker Container,可以直接使用宿主机的IP地址与外界进行通信,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换。
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。
Host网络模式的缺陷
使用Host模式的容器不再拥有隔离、独立的网络环境。虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用; 另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以bridge网络模式容器的端口映射。
Container网络模式
一种特殊host网络模式, ontainer网络模式是Docker中一种较为特别的网络的模式。在容器创建时使用– network=container:vm1指定。(vm1指定的是运行的容器名)处于这个模式下的 Docker 容器会共享一个网络环境,这样两个容器之间可以使用localhost高效快速通信。
Container网络模式的缺陷
Container网络模式没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过-- network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
网络基本用法
作为演示,使用nginx景象进行
镜像的相关操作
- 拉取镜像
docker pull nginx:1.19.3-alpine
复制代码
- 运行镜像
docker run -itd --name nginx1 nginx:1.19.3-alpine
复制代码
- 容器创建时IP地址的分配
使用docker network inspect bridge
效果如下图
docker容器创建流程
-
创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;
-
本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 vetha596da4;
-
容器一端放到新容器中,并修改名字作为 eth0,这个网卡/接口只在容器的名字空间可见;
-
从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 vetha596da4。
-
容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。 如果不指定--network,创建的容器默认都会挂到 docker0 上,使用本地主机上 docker0 接口的 IP 作为 所有容器的默认网关。
-
进入容器查看网络地址
第一种方式:
docker exec -it nginx1 sh
ip a
第二种方式:
docker exec -it nginx1 ip a
复制代码
安装brctl
yum install -y bridge-utils
复制代码
运行brctl
brctl show
复制代码
容器连接图
多容器之间通讯
docker run -itd --name nginx1 nginx:1.19.3-alpine
docker run -itd --name nginx2 nginx:1.19.3-alpine
docker network inspect bridge
docker exec -it nginx1 sh
ping 172.17.0.2
docker exec -it nginx2 sh
ping 172.17.0.2
ping www.baidu.com
ping nginx1
复制代码
重启容器IP地址会发生变化
docker stop nginx1 nginx2
先启动nginx2,在启动
nginx1 docker start nginx2
docker start nginx1
docker network inspect bridge
复制代码
解决容器IP地址变化(新建bridge网络)
docker network create -d bridge test-bridge
复制代码
上面命令参数-d 是指DRIVER的类型,后面的test-bridge是network的自定义名称,这个和docker0是类似的。下面开始介绍,如何把容器连接到test-bridge这个网络。
启动一个nginx的容器nginx3,并通过参数network connect来连接lagou-bridge网络。在启动容器 nginx3之前,我们查看目前还没有容器连接到了test-bridge这个网络上。
brctl show
docker network ls
docker network inspect test-bridge
docker run -itd --name nginx3 --network test-bridge nginx:1.19.3-alpine
brctl show
docker network inspect test-bridg
复制代码
- 把一个运行中容器连接到test-bridge网络
docker network connect test-bridge nginx2
docker network inspect test-bridge
docker exec -it nginx2 sh
ping nginx3
docker exec -it nginx3 sh
ping nginx2
复制代码
none网络
启动一个ngnix的容器nginx1,并且连接到none网络。然后执行docker network inspect none,看看容器信息
docker run -itd --name nginx1 --network none nginx:1.19.3-alpine
docker network inspect none
复制代码
注意
容器使用none模式,是没有物理地址和IP地址。我们可以进入到nginx1容器里,执行ip a命令看 看。只有一个lo接口,没有其他网络接口,没有IP。也就是说,使用none模式,这个容器是不能被其他 容器访问。这种使用场景很少,只有项目安全性很高的功能才能使用到。
docker exec -it nginx1 sh
ip a
复制代码
docker网络命令汇总
查看网络(docker network ls)
查看已经建立的网络对象
- 语法
docker network ls [OPTIONS]
复制代码
-
常用参数
-f
- --filter filter 过滤条件(如 'driver=bridge’)
- --format string
- --no-trunc
-q, --quiet 格式化打印结果 不缩略显示 只显示网络对象的ID
-
基本使用
docker network ls
docker network ls --no-trunc
docker network ls -f 'driver=host'
复制代码
创建网络(docker network create)
创建新的网络对象
- 语法
docker network create [OPTIONS] NETWORK
复制代码
-
常用参数
-
--driver string 指定网络的驱动(默认 "bridge")
-
--subnet strings 指定子网网段(如192.168.0.0/16、172.88.0.0/24)
--ip-range strings 执行容器的IP范围,格式同subnet参数
-
--gateway strings 子网的IPv4 or IPv6网关,如(192.168.0.1)
-
-
基本使用
docker network ls
docker network create -d bridge my-bridge
docker network ls
复制代码
网络删除(docker network rm)
删除一个或多个网络
- 语法
docker network rm NETWORK [NETWORK...]
复制代码
查看网络详细信息(docker network inspect)
查看一个或多个网络的详细信息
- 语法
docker network inspect [OPTIONS] NETWORK [NETWORK...]
docker inspect [OPTIONS] NETWORK [NETWORK...]
复制代码
-
常见参数
- -f, --format string 根据format输出结果
使用网络(docker run –-network)
为启动的容器指定网络模式
- 语法
docker run/create --network NETWORK
复制代码
网络连接与断开(docker network connect/disconnect)
docker network connect/disconnect
- 语法
docker network connect [OPTIONS] NETWORK CONTAINER
docker network disconnect [OPTIONS] NETWORK CONTAINER
复制代码
-
常见参数
-
-f, --force 强制断开连接(用于disconnect)
-
到此Docker网络相关的知识和语法就分享到这里。希望自己能够熟练使用docker