Docker网络

Docker网络

Docker本身的技术依赖于Linux内核虚拟化技术的发展。所以Docker对Linux内核的特性有很强的依赖。本章主要介绍Docker所使用的Linux网络技术。

网络基础

其中Docker使用到的与Linux网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由。

网络名称空间

为了支持网络协议栈的多个实例,Linux在网络协议栈中引入了网络名称空间(Network Namespace),这些独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个“平行宇宙”。通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境,而Docker正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。在Linux的网络命名空间内可以有自己独立的Iptables来转发、NAT及IP包过滤等功能。

Linux的网络协议栈是十分复杂的,为了支持独立的协议栈,相关的这些全局变量都必须修改为协议栈私有。最好的办法就是让这些全局变量成为一个Net Namespace变量的成员,然后为了协议栈的函数调用加入一个Namespace参数。这就是Linux网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。当然,通常的物理网络设备只能关联到root这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空间中,而且可以在这些名称空间之间移动。

  • 创建一个命名空间
[root@instance-gvpb80ao docs]# ip netns add test01
[root@instance-gvpb80ao docs]# ip netns add test02
[root@instance-gvpb80ao docs]# ip netns list
test02
test01Copy to clipboardErrorCopied

Veth设备

引入Veth设备对是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间链接起来。由于要连接的两个网络命名空间,所以Veth设备是成对出现的,很像一对以太网卡,并且中间有一根直连的网线。既然是一对网卡,那么我们将其中一端称为另一端的peer。在Veth设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作。

Veth设备操作

  • 创建Veth设备对
[root@instance-gvpb80ao docs]# ip link add veth type veth peer name veth001
[root@instance-gvpb80ao docs]# ip link show
322: veth001@veth: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 0e:f1:bc:38:47:dc brd ff:ff:ff:ff:ff:ff
323: veth@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4a:1f:13:ef:9e:95 brd ff:ff:ff:ff:ff:ffCopy to clipboardErrorCopied

生成了两个veth设备, 互为对方的peer

  • 绑定命名空间
[root@instance-gvpb80ao docs]# ip link set veth001 netns test01
[root@instance-gvpb80ao docs]# ip link show | grep veth
323: veth@if322: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000Copy to clipboardErrorCopied

已经查看不到veth001,当我们进入test01命名空间之后,就可以查看到

[root@instance-gvpb80ao docs]# ip netns exec test01 bash
[root@instance-gvpb80ao docs]# ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
322: veth001@if323: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 0e:f1:bc:38:47:dc brd ff:ff:ff:ff:ff:ff link-netnsid 0Copy to clipboardErrorCopied
  • 将Veth分配IP
[root@instance-gvpb80ao docs]# ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001
[root@instance-gvpb80ao docs]# ip netns exec test01 ip link set dev veth001 up
[root@instance-gvpb80ao docs]# ip netns exec test01 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
322: veth001@if323: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether 0e:f1:bc:38:47:dc brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.16.0.111/20 scope global veth001
       valid_lft forever preferred_lft foreverCopy to clipboardErrorCopied

这个时候双方就同了。

  • 查看对端Veth设备
[root@instance-gvpb80ao docs]# ip netns exec test01 ethtool -S veth001
NIC statistics:
     peer_ifindex: 323
[root@instance-gvpb80ao docs]# ip a | grep 323
323: veth@if322: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000Copy to clipboardErrorCopied
  • 为对端Veth设备设置IP
[root@instance-gvpb80ao docs]# ip addr add 172.16.0.112/20 dev veth
[root@instance-gvpb80ao docs]# ip link set dev veth down
[root@instance-gvpb80ao docs]# ip link set dev veth up
[root@instance-gvpb80ao docs]# ping 172.16.0.111
PING 172.16.0.111 (172.16.0.111) 56(84) bytes of data.
64 bytes from 172.16.0.111: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 172.16.0.111: icmp_seq=2 ttl=64 time=0.074 ms
^C
--- 172.16.0.111 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.061/0.067/0.074/0.010 ms
[root@instance-gvpb80ao docs]# ping 172.16.0.112
PING 172.16.0.112 (172.16.0.112) 56(84) bytes of data.
64 bytes from 172.16.0.112: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 172.16.0.112: icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from 172.16.0.112: icmp_seq=3 ttl=64 time=0.055 msCopy to clipboardErrorCopied

网桥

Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥。 网桥是二层的虚拟网络设备,它是把若干个网络接口“连接”起来,从而报文能够互相转发。网桥能够解析收发的报文,读取目标 MAC 地址的信息,和自己记录的 MAC 表结合,来决定报文的转发目标网口。

网桥设备 brO 绑定了 eth0eth1 。对于网络协议械的上层来说,只看得到 brO 。因为桥接是在数据链路层实现的 ,上层不需要关心桥接的细节,于是协议枝上层需要发送的报文被送到 brO ,网桥设备的处理代码判断报文该被转发到 ethO 还是 ethl ,或者两者皆转发。反过来,从 ethO 或从 ethl 接收到的报文被提交给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是提交到协议枝上层。 而有时 ethl 也可能会作为报文的源地址或目的地址 直接参与报文的发送与接收,从而绕过网桥。

Iptables

我们知道, Linux 络协议樵非常高效,同时比较复杂 如果我们希望在数据的处理过程中对关心的数据进行一些操作该怎么做呢? Linux 提供了一套机制来为用户实现自定义的数据包处理过程。

在Linux网络协议棋中有一组回调函数挂接点,通过这些挂接点挂接的钩子函数可以在Linux 网络棋处理数据包的过程中对数据包进行 些操作,例如过滤、修改、丢弃等 整个挂接点技术叫作 Netfilter lptables

Netfilter 负责在内核中执行各种挂接的规则,运行在内核模式中:而 lptables 是在用户模式下运行的进程,负责协助维护内核中 Netfilter 的各种规则表 通过 者的配合来实现整个 Linux网络协议战中灵活的数据包处理机制。

总结

设备 作用总结
network namespace 主要提供了关于网络资源的隔离,包括网络设备、IPv4和IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、端口(socket)等。
linux Bridge 功能相当于物理交换机,为连在其上的设备(容器)转发数据帧。如docker0网桥。
iptables 主要为容器提供NAT以及容器网络安全。
veth pair 两个虚拟网卡组成的数据通道。在Docker中,用于连接Docker容器和Linux Bridge。一端在容器中作为eth0网卡,另一端在Linux Bridge中作为网桥的一个端口。

docker网络

docker网络的几种模式

 bridge模式:使--net =bridge指定,默认设置;启动一个docker会和docker0同一个网段,处于同一个二层网络中
 host模式:使--net =host指定;使用的都是宿主机的网络信息。
 none模式:使--net =none指定;需要run运行容器,自行指定ip
 container模式:使用--net =container:NAME orID指定。

参考:http://www.docker.org.cn/dockerppt/111.html

#host 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。

例如,我们在 10.10.101.105/24 的机器上用 host 模式启动一个含有 web 应用的 Docker 容器,监听 tcp 80 端口。当我们在容器中执行任何类似 ifconfig 命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用 10.10.101.105:80 即可,不用任何 NAT 转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

#container 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

#none模式
这个模式和前两个不同。在这种模式下,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。

#bridge模式
bridge 模式是 Docker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置 IP 等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配 IP 了,Docker 会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主机不同的IP地址和子网分配给 docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的 IP 使用。如一般 Docker 会使用 172.17.0.0/16 这个网段,并将 172.17.42.1/16 分配给 docker0 网桥(在主机上使用 ifconfig 命令是可以看到 docker0 的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)

docker0

linux的虚拟网桥
在OSI七层模型中的数据链路层

# 特点:
可以设置ip地址
相当于拥有一个隐藏的虚拟网卡
docker0的地址划分:
IP:172.17.42.1 子网掩码:255.255.0.0
MAC:02:42:ac:11:00:00到02:42:ac:11:ff:ff
总共提供了65534个地址

# 查看veth*与容器通信
· 安装网桥管理工具:
yum install bridge-utils -y
brctl show 可以查看到有一个docker0的网桥设备,下面有很多接口,每个接口都表示一个启动的docker容器,如下所示:
[root@node1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024283d7bcd8	no		veth8d3e3ee

# 添加虚拟网桥,并使docker生效
- 添加虚拟网桥
brctl addbr br0

- 查看宿主机网络
ifconfig br0 172.16.1.1 netmask 255.255.0.0(我的宿主机docker0地址是172.17.42.1)

- 更改docker守护进程的启动配置:
/etc/sysconfig/docker 中添加
other_args="-b=br0"

- 重启docker
service docker restart

- 查看
ps -ef | grep docker 可以看见br0这个参数

- 验证
docker run -it centos:6.9 /bin/bash
ifconfig可以看见ip地址是172.16.0.1

- 说明:
也就是说们启动docker时,在/etc/sysconfig/docker里修改other_args="-b=br0",在创建docker容器的时候,容器的ip就是172.16.*.*,也就是我们新建立的网桥

通过veth*与容器通信

容器互联方式

# 默认不指定,使用docker0方式二层互联
- 启动容器test1,并查看ip
docker run -itd --name test1 centos 

- 启动容器test2,直接ping test1(不上图,但是能ping通)
docker run -itd --name test2 centos /bin/bash

# 如上问题:
test1一旦重启,ip地址改变,test2无法得知test1的ip,所以引出下面容器起代号方式,重启不影响容器互联

- 启动容器test1 
docker run -itd --name test1 centos 

- 启动容器test2,关联test1并起别名
docker run --name test2 -itd --link=test1:webtest centos /bin/bash

- 重启test1
docker restart test1

- 进入容器test2,ping别名webtest
当然没问题啦,这里不上图了

拒绝容器互联(拒绝容器互相访问)

# docker守护进程启动项
--icc=false

# 修改启动项配置文件
vim /etc/sysconfig/docker
在最后一行添加如下参数:
other_args="-icc=false"
重启docker容器配置生效,然后分别运行test3,test5,在test5上ping test3的ip(webtest),会发现ping不通
posted @ 2020-10-17 21:02  元气少女郭德纲!!  阅读(237)  评论(0编辑  收藏  举报