分享

Neutron系列 : Neutron 是如何向 Nova 虚机分配固定IP地址的(9)

breaking 发表于 2015-12-17 13:49:09 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 0 15223
本帖最后由 eying 于 2016-1-13 16:54 编辑
问题导读:
1.怎么去理解Linux network namespace ?
2.怎么去区分netfilter/iptables 基本概念?






  Neutron 对虚拟三层网络的实现是通过其 L3 Agent (neutron-l3-agent)。该 Agent 利用 Linux IP 栈、route 和 iptables 来实现内网内不同网络内的虚机之间的网络流量,以及虚机和外网之间网络流量的路由和转发。为了在同一个Linux 系统上支持可能的 IP 地址空间重叠,它使用了 Linux network namespace 来提供隔离的转发上下文。

1. 基础知识1.1 Linux network namespace

1.1.1 概念和操作

    在二层网络上,VLAN 可以将一个物理交换机分割成几个独立的虚拟交换机。类似地,在三层网络上,Linux network namespace(netns) 可以将一个物理三层网络分割成几个独立的虚拟三层网络。

   Network namespace (netns)从 Linux 2.6.24 版本开始添加,直到 2.6.29 添加完成。每个 netns  拥有独立的 (virtual)network devices, IP addresses, IP routing tables, /proc/net directory, ports 等等。新创建的 netns 默认只包含 loopback device。除了这个设备,每个 network device,不管是物理的还是虚拟的网卡还是网桥等,都只能存在于一个 netns。而且,连接物理硬件的物理设备只能存在于 root netns。其它普通的网络设备可以被创建和添加到某个 netns。

   使用 ip 命令来操作 netns。


[mw_shl_code=bash,true]#添加 network namespace
ip netnas add <network namespace name>
#Example:
ip netns add nstest

#列表所有 netns
ip netns list

#删除某 netns
ip netns delete <network namespace name>

#在 network namespace 中运行命令
ip netns exec <network namespace name> <command>
#Example using the namespace from above:
ip netns exec nstest ip addr

#添加 virtual interfaces 到 network namespace
ip link add veth-a type veth peer name veth-b #创建一对虚拟网卡veth-a 和 veth-b,两者由一根虚拟网线连接
#将 veth-b 添加到 network namespace
ip link set veth-b netns nstest

#设置 VI 的 IP 地址
#defaut namespace 中
ip addr add 10.0.0.1/24 dev veth-a
ip link set dev veth-a up

# namespace nstest 中
ip netns exec nstest ip addr add 10.0.0.2/24 dev veth-b
ip netns exec nstest ip link set dev veth-b up
#互通
# ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.087 ms
  
# ip netns exec netns1 ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.054 ms
#查看路由表和 iptbales
# ip netns exec netns1 route
# ip netns exec netns1 iptables -L[/mw_shl_code]

1.1.2 namespace 间的通信
(1)一种简单的方式是使用 Linux veth pair 来实现两个 network namespace 之间的通信:



212246047218725.png


(2)当有两个以上的 network namespace 之间需要通信时,需要使用一个虚机交换机,和两个 veth pair。传统的方式是 Linux bridge:

linuxswitch-linuxbridge-veth1.png

你也可以使用 Open vSwitch:

linuxswitch-ovs-veth.png

(3)再一种方式是使用 Open vSwitch 和 OVS internal ports:

linuxswitch-ovs.png
(来源,可见详细的配置命令。)

veth (irtual Ethernet interfaces) 设备:这是一种成对出现的特殊网络设备,它们象一根管道一样连接在一起。VETH 设备总是成对出现,送到一端请求发送的数据总是从另一端以请求接受的形式出现。该设备不能被用户程序直接操作,但使用起来比较简单。创建并配置正确后,向其一端输入数据,VETH 会改变数据的方向并将其送入内核网络核心,完成数据的注入。在另一端能读到此数据。
关于几种方式的性能比较,这篇文章也给出了它的测试结论:
  • 使用 OVS patch ports:性能更好
  • 不要使用 Linux veth pairs:它会带来明显的性能下降
在 Neutron 中,可以使用配置项 ovs_use_veth 来配置是否使用 veth,默认为 false,表示默认使用 OVS internal port。

1.2 iptables

1.2.1 netfilter/iptables 基本概念


   netfilter/iptables(简称为iptables)组成 Linux 平台下的包过滤防火墙。其中,iptables 是一个 linux 用户空间(userspace)模块,位于/sbin/iptables,用户可以使用它来操作防火墙表中的规则。真正实现防火墙功能的是 netfilter,它是一个 linux 内核模块,做实际的包过滤。实际上,除了 iptables 以外,还有很多类似的用户空间工具。
  这篇文章 详细介绍了 iptables/netfilter 的概念:

241401231781716.jpg        netfilter_arch.png

  • Netfilter 是一套数据包过滤框架,在处理 IP 数据包时 hook 了5个关键钩子。通过这5个关键点来实现各种功能,比如firewall/ips。
  • ip_tables 是真正的内核防火墙模块,通过把自己的函数注入到 Netfilter 的框架中来实现的防火墙功能.
  • Netfilter 提供了最基本的底层支撑,具体的功能实现只要注册自己的函数就可以了,这样保证了协议栈的纯净与可扩展性.通过上图可以看出 netfilter 与 iptables是分离的.
数据包处理过程:
  • 数据包从左边进入IP协议栈,进行 IP 校验以后,数据包被第一个钩子函数 PRE_ROUTING 处理。
  • 然后就进入路由模块,由其决定该数据包是转发出去还是送给本机。
  • 若该数据包是送给本机的,则要经过钩子函数 LOCAL_IN 处理后传递给本机的上层协议;若该数据包应该被转发,则它将被钩子函数 FORWARD 处理,然后还要经钩子函数 POST_ROUTING 处理后才能传输到网络。
  • 本机进程产生的数据包要先经过钩子函数 LOCAL_OUT 处理后,再进行路由选择处理,然后经过钩子函数POST_ROUTING处理后再发送到网络。
netfilter 使用表(table)和 链(chain)来组织网络包的处理规则(rule)。它默认定义了以下表和链:

iptables01.png

表功能链功能
raw PREROUTING         
OUTPUT
RAW 拥有最高的优先级,它使用PREROUTING和OUTPUT两个链,因此 RAW 可以覆盖所有包。在raw表中支持一个特殊的目标:TRACE,使内核记录下每条匹配该包的对应iptables规则信息。使用raw表内的TRACE target 即可实现对iptables规则的跟踪调试。比如:
# iptables -t raw -A OUTPUT -p icmp -j TRACE
# ipt ables -t raw -A PREROUTING -p icmp -j TRACE
Filter包过滤FORWARD过滤目的地址和源地址都不是本机的包
INPUT过滤目的地址是本机的包
OUTPUT过滤源地址是本机的包
Nat网络地址转换               PREROUTING在路由前做地址转换,使得目的地址能够匹配上防火墙的路由表,常用于转换目的地址。
POSTROUTING在路由后做地址转换。这意味着不需要在路由前修改目的地址。常用语转换源地址。
OUTPUT
对防火墙产生的包做地址转换(很少量地用于 SOHO 环境中)
MangleTCP 头修改PREROUTINGPOSTROUTINGOUTPUTINPUTFORWARD在路由器修改 TCP 包的 QoS(很少量地用在 SOHO 环境中)

每个注册的 Hook 函数依次调用各表的链的规则来处理网络包:


bridge3b.png


(来源:Ethernet bridging hooks )
  • PREROUTING Hook 依次调用 Managle 和 Nat 的 PREOUTING 链中的规则来处理网络包
  • LOCAL_IN Hook 依次调用  MANGLE 和 Filter 的 INPUT 链中的规则来过滤网络包
  • LOCAL_OUT Hook 依次调用 Mangle,Nat,Filter 表的 Output 链中的规则来过滤网络包
  • FORWARD Hook 依次调用 Mangle 和 Filter 表的 FORWARD 链中的规则来过滤网络包
  • POST_ROUTING Hook 依次调用 Managle 和 Nat 表的 POSTROUTING 链中的规则来处理网络包
对 Neutron Virtual Router 所使用的 filter 表来说,它的三个链 INPUT, FORWARD, 和 OUTPUT 是分开的。一个数据包,根据其源和目的地址,只能被其中的某一个处理。
  • 如果数据包的目的地址是本机,那它被 INPUT 处理。
  • 如果数据包的源地址是本机,那它被 OUTPUT 处理。
  • 如果源地址和目的地址都是别的机器,那它被 FORWARD 链处理。
图中的 ”路由判断“ 即判断包的目的地址。如果目的地址不是本机的地址,那它就是需要被路由的包;如果目的地址是本机的,那么被filter 的 INPUT 处理后,被主机的某个程序处理。该程序如果需要发回响应包的话,其源地址肯定是本机的,所有它会被 filter 的 OUTPUT 链处理。该包不一定会出网卡,因为可能会走 loopback,它又会回到本机,重新走封包进入的过程。

1.2.2 iptables

   iptables 是一个 CLI 类型的 Linux 用户空间工具,它使得系统管理员能够配置netfile 表(tables)中的链和规则。Linux 使用不同的内核模块和应用来管理不同的网络协议iptable 适用于 ipv4,ip6tables 适用于 ipv6,arptables 适用于 ARP,ebtables 适用于网络帧。iptales 需要管理员权限。
   规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
操作 iptables 服务:
# /etc/init.d/iptables start/stop/restart
iptables 各命令选项:

iptables_usage.png

(引用自 http://fishcried.com/2014-08-29/iptable/)
  • -p, --protocol protocol: tcp, udp, udplite, icmp, esp, ah, sctp 之一
  • -s, --source address[/mask] a network name, a hostname, a network IP address (with /mask), or a plain IP address.
  • -d, --destination address[/mask][,...]:同 -s
  • -j, --jump target:match 后的 target。
  • -g, --goto chain
  • [!] -i, --in-interface name:连接进来的 interface 名称。!表示否。
  • [!] -o, --out-interface name
其中 -j:
    当数据包进入后,会依次比照 iptables 中的每条规则,直到有一条规则可以对该报文进行匹配,这时该报文将被执行"ACCEPT","DORP","REJECT" 或者其它动作,除 REDIRECT 外,执行完后停止跟余下的 iptables 规则匹配。
  • -ACCEPT: 将封包放行,进行完此处理动作后,将不再比对其它规则,直接跳往下一个规则链。
  • -REJECT:   拦阻该封包,并传送封包通知对方。
  • -DROP: 丢弃封包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。
  • -DNAT:DNAT 改写封包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将会直接跳往下一个规则链。
  • -REDIRECT:    将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。
  • -SNAT: 改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将直接跳往下一个规则链。
  • -RETURN:中断当前链,返回调用链或者默认的policy。
一些例子:
  • iptables -A INPUT -s 10.10.10.10 -j DROP #丢弃从 10.10.10.10 主机来的所有包
  • iptables -A INPUT -s 10.10.10.0/24 -j DROP #丢弃从 10.10.10.0/24 网段进来所有包
  • iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP # 如果协议是 tcp,目标端口是 ssh 端口,源IP 为 10.10.10.10,那么丢弃它
  • iptables -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT #接受从 virbr0 进来的所有目标端口 53 的 udp 包
  • iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT #接受 RELEASED 和 ESTABLISHED  状态的连接。Linux 3.7 以后,--state 被替换成了 --conntrack
  • iptables -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT #转发时接受这些包
  • iptables -A FORWARD -p icmp -j ACCEPT #转发时接受所有 ICMP 路由包。
  • iptables -A INPUT -i lo -j ACCEPT #使用 -i 过滤从 lo 设备进来的包
  • iptables -A INPUT -i eth0 -j ACCEPT #使用 -i  过滤从网卡 eth0 进来的包。不指定网卡的话表示所有网卡。
封包过滤实现的是针对安全方面的策略,通常我们遵循“凡是没有明确允许的都是禁止的”这样的原则来设计安全策略:首先禁止所有的东西,然后根据需要再开启必要的部分。
关于 iptables 的详细的说明,可以参考 这里,以及 这里 和 这里,以及 这里。
Neutron 主要用到 filter 表和 nat 表,其中, filter 用来实现安全组(Security Group)和 防火墙(FWaas);nat 主要用来实现 router。


1.2.3 NAT 的实现


可以使用 iptables nat 表来实现网络地址转换(NAT)。NAT 包括 SNAT (源地址转换)和 DNAT (目的地址转换)。两者的区别在于做地址转换是在路由前还是路由后:
(1)SNAT:路由 - 转换 - 发出
数据经过时, 源地址发生改变,目的地址不变。SNAT 的具体数据流向:
  • 封包先经过 PREROUTING,检查目的 IP 是不是本网段的地址。是的话,走路径A。
  • 如果不是,则开始查询路由表,查找到相应路由条目后(查找路由的过程在 PREROUTING 和 FORWARD 之间),经过 FORWARD 链进行转发,再通过 postrouting 时进行NAT转换。
从这里可以看出,SNAT转换的步骤在 POSTROUTING 链上实现, PREROUTING 只是用来做路由选择。因此,要做 SNAT 的话,需要添加 POSTROUTING 规则,使用 “-j SNAT -to-source”。比如:
iptables -t nat -A POSTROUTING -s 192.168.252.0/24 -j SNAT -to-source 100.100.100.1
(2)DNAT:转换 - 路由- 发出
DNAT 的功能正好和 SNAT 相反,源地址不变,目的地址发生改变。DNAT 可以用作 PNAT,可以将一个 IP 的端口转换成另一个IP的另外一个端口号,经常用于内网服务器映射到公网,用来隐藏服务器的真实地址。DNAT 的具体数据流向:
  • 在 DNAT 中,NAT 是在 PREROUTING 上做的。在数据进入主机后,路由选择过程是在 PREROUTING 和 FORWARD 之间的,所以应该先做地址转换之后,再进行路由选择,而后经过 FORWARD,最后从 POSTROUTING 出去。
  • 因此,要做 DNAT,需要添加 PREROUTING 规则,使用 “-j DNAT --to-destination”。比如:
iptables -t nat -A PREROUTING -d 100.100.100.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.252.1

101726487367786.jpg

有一类比较特殊的 DNAT 是使用 “-j REDIRECT” 做端口号转换:
## Send incoming port-80 web traffic to our squid (transparent) proxy# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80-j REDIRECT --to-port 3128
关于 SNAT 和 DNAT 的更多解释可以参考 这里 和 这里。


1.3 route (Linux 路由表)


Linux 系统的 route 命令用于显示和操作 IP 路由表,它的主要作用是创建一个静态路由来指定一个主机或者一个网络通过一个网络接口,如eth0。
[mw_shl_code=bash,true]route [-CFvnee]

route [-v] [-A family] add [-net|-host] target [netmask Nm] [gw Gw] [metric N] [mss M] [window W] [irtt I] [reject] [mod] [dyn] [rein-
state] [[dev] If]

route [-v] [-A family] del [-net|-host] target [gw Gw] [netmask Nm] [metric N] [[dev] If][/mw_shl_code]

例子:
  • route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 #增加一条经过 eth0 到达 244.0.0.0 的路由
  • route add -net 224.0.0.0 netmask 240.0.0.0 reject #增加一条屏蔽的路由,目的地址为224.x.x.x将被拒绝。
  • route del -net 224.0.0.0 netmask 240.0.0.0
  • route del -net 224.0.0.0 netmask 240.0.0.0 reject
  • route del default gw 192.168.120.240
  • route add default gw 192.168.120.240
这个命令比较简单,可以参考 这个。


1.4 路由器的辅助(Secondary) IP


先来看一个 Virutal Router 的 interface 的 ip 配置:
[mw_shl_code=bash,true]42: qg-3c8d6a68-97: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether fa:16:3e:2e:5b:23 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.110/24 brd 192.168.1.255 scope global qg-3c8d6a68-97
       valid_lft forever preferred_lft forever
    inet 192.168.1.104/32 brd 192.168.1.104 scope global qg-3c8d6a68-97
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe2e:5b23/64 scope link
       valid_lft forever preferred_lft forever[/mw_shl_code]

<BROADCAST,UP,LOWER_UP>:端口的各种状态
  • UP: device is functioning (enabled 状态,可通过 ip * up/down 设置。)
  • BROADCAST: device can send traffic to all hosts on the link (能够发广播)
  • MULTICAST: device can perform and receive multicast packets (能够发多播)
  • ALLMULTI: device receives all multicast packets on the link (能够接收多播)
  • PROMISC: device receives all traffic on the link (接收所有的traffic)
  • LOWER_UP:the state of the Ethernet link(表示线已接上)
inet/brd/scope:IP 地址及子网掩码,广播地址,作用域
scope:
  • global:valid everywhere
  • site:valid only within this site (IPv6)
  • link:valid only on this device
  • host:valid only inside this host (machine)
    注意到这个interface有两个静态 IP 地址。第一个是主要的(primary)IP,第二个是辅助的( secondary) 的 IP。当一个网卡配置了静态IP后,你可以添加secondary  IP 给它。这样它就拥有了多个 IP 地址了。Secondary IP 不可以通过 DHCP 分配。它所有的IP 地址都关联到它唯一的一个 MAC 地址上。那为什么需要 secondary IP 地址呢? 路由器有个 Secondary IP 的概念,这个特性可以创建逻辑子网,也就是说在一个物理网口上连接两个子网,比如这个网口接到一台交换机上,如 果这个网口没有配置Secondary IP的话,那么这台交换机只能连接一个网段的主机,比如 192.168.1.1/24,但是,如果它配置了Secondary IP,那么就可以连接两个网段的主机,比如 192.168.1.1/24 和 10.0.0.1/24。更详细的解释可以看这里 和 这里。
命令:
#增加 secondary IP
ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 ip a add dev qg-3c8d6a68-97 192.168.1.105/32 brd 192.168.1.105

#删除 secondar IP
ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 ip addr del 192.168.1.104/32 dev qg-3c8d6a68-97

1.5 Gratuitous ARP


  Gratuitous ARP也称为 免费ARP,无故ARP。Gratuitous ARP不同于一般的ARP请求,它并非期待得到IP对应的MAC地址,而是当主机启动的时候,将发送一个Gratuitous arp请求,即请求自己的IP地址的MAC地址。它常用于三个用途:
  • Change of L2 address:改变 MAC 地址。当一个网络设备的 MAC 地址发生改变时,发送该设备的 Gratuitous ARP,通知所在广播域内的已经包含该 IP 地址在其 ARP 表中的机器去更新它的 ARP 条目。
  • Duplicate address detection:重复 MAC 地址检测。一个主机可以通过它来确定另一个主机是否设置了相同的IP地址。发送主机并不需要一定收到此请求的回答。如果收到一个回答,表示网络中存在与自身IP相同的主机。如果没有收到应答,则表示本机所使用的IP与网络中其它主机并不冲突。
  • Virtual IP:用于一组服务器做 failover 时通知周围的机器新生效的 IP 地址的 MAC。

具体可以参见 这篇文章 和 这篇文章。


原文链接:http://www.cnblogs.com/sammyliu/p/4636091.html


相关内容:


neutron系列:Neutron 所实现的虚拟化网络(1)


neutron系列:Neutron 所实现的虚拟化网络(2)

neutron系列:使用 Open vSwitch + VLAN 组网(3)

neutron系列:使用 Open vSwitch + VLAN 组网(4)

Neutron系列 : 使用Open vSwitch + GRE/VxLAN 组网 (5)

Neutron系列 : 使用Open vSwitch + GRE/VxLAN 组网(6)

Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(7)

Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(8)

Neutron系列 : Neutron 是如何向 Nova 虚机分配固定IP地址的(9)

Neutron系列 : Neutron 是如何向 Nova 虚机分配固定IP地址的(10)

Neutron 系列 (11): Neutron 是如何实现负载均衡器虚拟化的【基础篇】

Neutron 系列 (12): Neutron 是如何实现负载均衡器虚拟化的【提高篇】

Neutron 系列 (13): Neutron 是如何实现虚机防火墙的 【上】

Neutron 系列 (14): Neutron 是如何实现虚机防火墙的 【下】

Neutron 系列 (15): OpenStack 是如何实现 Neutron 网络 和 Nova虚机 防火墙的

Neutron 系列(16):虚拟专用网(VPN)虚拟化

Neutron 系列 (17): Neutron 分布式虚拟路由【上】

Neutron 系列 (18): Neutron 分布式虚拟路由【下】

Neutron系列(19):Neutron L3 Agent HA 之 虚拟路由冗余协议(VRRP)【上】

Neutron系列(20):Neutron L3 Agent HA 之 虚拟路由冗余协议(VRRP)【下】

Neutron系列(21):OpenStack 高可用和灾备方案 [OpenStack HA and DR]【上】

Neutron系列(22):OpenStack 高可用和灾备方案 [OpenStack HA and DR]【下】







没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条