Docker容器网络实操教程

虚拟技术和云飞速发展的今天,云和容器已经深入人心,每个IT人都或多或少的使用容器和云 。但是用归用,很多人对其底层的原理确实知之甚少 。很多人想把容器当成虚拟机来用,却遭遇大大的阻碍,如果理解容器原理的话,你就会发现容器实际上是孤立且受限制的linux进程,和其他进程也一样 。运行容器实际上并不需要镜像,相反,要构建镜像,则必须要运行一些容器 。但是不敢怎么着,容器是要用来使用的,必然要联网的,所以容器联网的原理是有限需要了解的,为此本文我们就来一起学习容器的网络原理 。

Docker容器网络实操教程

文章插图
 
网络命名空间大家可能都知道Linux网络实际上是在内存空间的堆栈数据,包括Linux网络设备的集合、路由规则、netfilter hook集等(包括iptables规则定义的) 。为了获取Linux的这些网络堆栈数据,需要用到几个工具,包括netstat –ie ,ifconfig,ip link,ip route和iptables –list-rules等 。
ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:e3:2a:77 brd ff:ff:ff:ff:ff:ff
ip routedefault via 10.0.2.2 dev eth0 proto dhcp metric 100
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100
iptables –list-rules-P INPUT ACCEPT-P FORWARD ACCEPT-P OUTPUT ACCEPT用于容器隔离的Linux命名空间之一称为网络命名空间 。从逻辑上讲,网络命名空间是网络堆栈的另一个副本,有其自己的路由,防火墙规则和网络设备 。为了简单起见,这是我们将在本文中使用的唯一命名空间 。与其创建完全隔离的容器,不如将范围限制为仅网络堆栈 。ip工具在现在OS默认自带的iproute2集合的一部分,这些工具可以用来创建网络命名空间 。
sudo ip netns add netns0ip netnsnetns0为了使用这个刚新建的的命名空间netns0,可以使用Linux命令称nsenter 。它输入一个或多个指定的命名空间,然后执行给定的程序:
sudo nsenter --net=/var/run/netns/netns0 baship link1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00从上面的输出中可以明显看出,在命名空间内运行的bash进程netns0看到了完全不同的网络堆栈 。没有路由规则,也没有自定义iptables链,只有一个环回网络设备 。
Docker容器网络实操教程

文章插图
 
链接容器网络和主机网络如果不能与专用网络堆栈通信,那么容器也就没啥用 。为此Linux提供了合适的工具,虚拟以太网设备veth,这个设备是虚拟以太网设备,可以用来充当网络命名空间之间的隧道,以创建到另一个命名空间中的物理网络设备的桥梁,但也可以用作独立的网络设备 。”
虚拟以太网设备需要成对使用,用下面命令创建一组互连的虚拟以太网设备veth0和ceth0:
sudo ip link add veth0 type veth peer name ceth0然后查看网络信息
ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff5: ceth0@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether 66:2d:24:e3:49:3f brd ff:ff:ff:ff:ff:ff6: veth0@ceth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether 96:e8:de:1d:22:e0 brd ff:ff:ff:ff:ff:ff双方veth0并ceth0创建所在的主机的网络堆栈后(也称为根网络命名空间) 。要将根命名空间与该netns0命名空间连接,需要将其中一台设备保留在根命名空间中,然后将另一台设备移至netns0:
sudo ip link set ceth0 netns netns0网络信息:
ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff6: veth0@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether 96:e8:de:1d:22:e0 brd ff:ff:ff:ff:ff:ff link-netns netns0


推荐阅读