Docker之十七: 高级网络功能

Docker之十七: 高级网络功能Docker 网络基本原理Docker 的网络模式Docker 支持的网络模式Docker 默认的网络模式HOST 模式CONTAINER 模式NONE 模式自定义网络模式网络启动与配置参数配置容器 DNS 和主机名容器内修改配置文件通过参数指定容器访问控制容器访问外部网络容器之间访问访问所有端口访问指定端口映射容器端口到宿主主机的实现容器访问外部实现外部访问容器实现配置容器网桥自定义网桥使用 OpenvSwitch 网桥创建一个点到点的连接Docker 网络基本原理D
摘要由CSDN通过智能技术生成

Docker 网络基本原理

Docker 的本地网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备(特别是 veth pair)。

要实现网络通信,需要至少一个物理或虚拟网络接口与外界相通,收发数据,如需在不同子网之间进行通信,还需要路由机制。

Docker 中的网络接口默认都是虚拟接口。其基本原理是:Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将直接复制到接收接口的接受缓存中,而无需通过外部网络设备进行交换。所以虚拟接口的转发效率极高。

Docker 容器网络利用了 Linux 虚拟网络技术,它在本地主机和容器内分别建立一个虚拟接口 veth,并连通(这样的一对虚拟接口叫做 veth pair)。

在这里插入图片描述

Docker 创建容器的时候,按照如下步骤操作:

  1. 创建一对虚拟接口,分别放到本地主机和新容器的命名空间中;
  2. 本地主机一端的虚拟接口连接到默认的 docker0 网桥或指定网桥上,并且有一个以 veth 开头的唯一名字,如 veth1234
  3. 容器一端的虚拟接口将放到新创建的容器中,并修改名字作为 eth0U。这个接口只在容器命名空间可见;
  4. 从网桥可用地址段中获取一个空闲的地址分配给容器的 eth0(例如 172.17.0.2/16),并配置默认路由网关为 docker0 网卡的内部接口 docker0 的 IP 地址(例如 172.17.42.1/16)。

这样,容器就可以使用它所能看到的 eth0 虚拟网卡来连接其他容器和访问外部网络。

Docker 的网络模式

Docker 支持的网络模式

docker容器的网络有五种模式:

  1. bridge 模式,–net=bridge (默认)
    这是 Dokcer 网络的默认设置,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。
    docker run 启动容器的时候,如果不加 –net 参数,就默认采用这种网络模式。安装完 Docker,系统会自动添加一个供 Docker 使用的网桥 docker0,我们创建一个新的容器时,容器通过 DHCP 获取一个与 docker0 同网段的 IP 地址,并默认连接到 docker0 网桥,以此实现容器与宿主机的网络互通。

  2. host 模式,–net=host
    这个模式下创建出来的容器,直接使用容器宿主机的网络命名空间。
    容器将不拥有自己独立的 Network Namespace,即没有独立的网络环境。它使用宿主机的 IP 和端口。

  3. none 模式,–net=none
    为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有 lo,用户可以在此基础上,对容器网络做任意定制。
    这个模式下,Dokcer 不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置 IP
    因此,若想使用 pipework 配置 Docker 容器的 IP 地址,必须要在 none 模式下才可以。

  4. 其他容器模式(即 container 模式),–net=container:NAME_or_ID
    host 模式类似,只是容器将与指定的容器共享网络命名空间。
    这个模式就是指定一个已有的容器,共享该容器的 IP 和端口。除了网络方面两个容器共享,其他的如文件系统,进程等还是隔离开的。

  5. 用户自定义:Docker 1.9 版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的 bridge 网络,提供网络隔离能力。

Docker 默认的网络模式

bridge 模式是 Docker 默认的网络模式,也是开发者最常使用的网络模式。在这种模式下,Docker 为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的 docker0 网桥,容器可以与宿主机乃至外界进行网络通信。

其网络模型如下图所示:
在这里插入图片描述
从上面的网络模型可以看出,容器从原理上是可以与宿主机乃至外界的其他机器通信的。

同一宿主机上,容器之间都是连接到 docker0 这个网桥上的,它可以作为虚拟交换机使容器可以相互通信。然而,由于宿主机的 IP 地址与容器 veth pairIP 地址均不在同一个网段,故仅仅依靠 veth pairnamespace 的技术,还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以访问容器中的进程,Docker 采用了端口绑定的方式,也就是通过 iptablesNAT,将宿主机上的端口端口流量转发到容器内的端口上。

# 使用 run 命令创建容器,并将宿主机的 3306 端口绑定到容器的 3306 端口
$ docker run -itd --name db -p 3306:3306 MySQL

# 宿主机上,通过下面命令可以查到一条 DNAT 规则
$ iptables -t nat -L -n
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306

上面的 172.17.0.5 即为 bridge 模式下,创建的容器 IP

很明显,bridge 模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,对宿主机端口的管理会是一个比较大的问题。同时,由于容器与外界通信是基于三层上 iptables NAT,性能和效率上的损耗是可以预见的。

# 列出当前主机网桥
$ brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242369ab552       no              vethef56aac

# 查看当前 docker0 ip
$ 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
        ether 02:42:36:9a:b5:52  txqueuelen 0  (Ethernet)
        RX packets 36626  bytes 1544566 (1.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 41832  bytes 142181730 (142.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
...

# 在容器运行时,每个容器都会分配一个特定的虚拟机口并桥接到docker0。
# 每个容器都会配置同 docker0 ip 相同网段的专用ip 地址
# docker0的IP地址被用于所有容器的默认网关。
$ docker ps
CONTAINER ID	IMAGE		 COMMAND	  			 CREATED		STATUS	 	PORTS	                            NAMES
b5f03e866505	mysql:latest "docker-entrypoint.s…"  3 hours ago Up 3 hours     0.0.0.0:3306->3306/tcp, 33060/tcp   mysql-test
$ docker inspect b5f03e866505 | grep IPAddress 
  "SecondaryIPAddresses": null,
  "IPAddress": "172.17.0.2",
           "IPAddress": "172.17.0.2",

# 宿主机的ip路由转发功能一定要打开,否则所创建的容器无法联网
# 查看宿主机网络转发是否开启 1,开启 0,关闭
$ cat /proc/sys/net/ipv4/ip_forward
1
# 或
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

HOST 模式

容器和宿主机共享同一个网络命名空间,换言之,容器的 IP 地址即为宿主机的 IP 地址。所以容器可以和宿主机一样,使用宿主机的任意网卡,实现和外界的通信。其网络模型可以参照下图:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二流人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值