声明:
本博客欢迎转发,但请保留原作者信息!
新浪微博:@孔令贤HW;
博客地址:http://blog.csdn.net/lynn_kong
内容系本人学习、研究和总结,如有雷同,实属荣幸!
版本:Grizzly master分支 2013.6.17
部署:三节点(controller + network + compute)
网络类型:vlan
之前的一篇blog中碰到了虚拟机访问169.254.169.254的问题,在F版中,会在网络节点上做NAT转换,直接访问nova的metadata服务,但这种方法,在使用namespace时就不生效了,因为namespace支持IP地址重叠,这样nova就无法区分到底是哪个虚拟机请求metadata。
该问题在G版得到解决,blueprint在此。采取的方法是在HTTP头部识别是哪个虚拟机。同时,G版在Quantum中加入了两个服务:namespace metadata proxy和metadata agent。一个虚拟机访问169.254.169.254的流程如下图:
在细讲流程之前,估计很多人并不清楚metadata的作用和由来。不懂的童鞋看这里。
ubuntu@ubuntu-test:~$ curl http://169.254.169.254/2009-04-04/meta-data
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
kernel-id
local-hostname
local-ipv4
placement/
public-hostname
public-ipv4
public-keys/
ramdisk-id
那么这些内容是如何获取到的?因为虚拟机内部没有特殊的路由,所以数据包会直接发送到虚拟机的默认网关,而默认网关是在network node上。虚拟机的网卡信息如下:
ubuntu@ubuntu-test:~$ ip -4 address show dev eth0
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 10.1.1.2/24 brd 10.1.1.255 scope global eth0
虚拟机的路由信息:
ubuntu@ubuntu-test:~$ ip route
default via 10.1.1.1 dev eth0 metric 100
10.1.1.0/24 dev eth0 proto kernel scope link src 10.1.1.2
-A quantum-l3-agent-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697
-A quantum-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT
虚拟机默认网关设备信息的地址信息,可以看到虚拟机网关的IP(10.1.1.1):
root@network232:~# ip netns exec qrouter-b147a74b-39bb-4c7a-aed5-19cac4c2df13 ip addr show qr-f7ec0f5c-2e
12: qr-f7ec0f5c-2e: mtu 1500 qdisc noqueue state UNKNOWN
link/ether fa:16:3e:81:9c:69 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.1/24 brd 10.1.1.255 scope global qr-f7ec0f5c-2e
inet6 fe80::f816:3eff:fe81:9c69/64 scope link
valid_lft forever preferred_lft forever
iptables规则中,会把目的地址169.254.169.254的数据包,重定向到本地端口9697,那么看一下network node上,在该端口的监听进程:
root@network232:~# ip netns exec qrouter-b147a74b-39bb-4c7a-aed5-19cac4c2df13 netstat -nlpt | grep 9697
tcp 0 0 0.0.0.0:9697 0.0.0.0:* LISTEN 13249/python
进程号13249,看一下这个进程:
root@network232:~# ps -f --pid 13249 | fold -s -w 85
UID PID PPID C STIME TTY TIME CMD
root 13249 1 0 16:30 ? 00:00:00 python
/usr/bin/quantum-ns-metadata-proxy
--pid_file=/var/lib/quantum/external/pids/b147a74b-39bb-4c7a-aed5-19cac4c2df13.pid
--router_id=b147a74b-39bb-4c7a-aed5-19cac4c2df13 --state_path=/var/lib/quantum
--metadata_port=9697 --debug --verbose
--log-file=quantum-ns-metadata-proxyb147a74b-39bb-4c7a-aed5-19cac4c2df13.log
--log-dir=/var/log/quantum
可能很多人想知道,这个进程从何而来,解释这个问题,可能要贴点代码:
def _spawn_metadata_proxy(self, router_info):
def callback(pid_file):
proxy_cmd = ['quantum-ns-metadata-proxy',
'--pid_file=%s' % pid_file,
'--router_id=%s' % router_info.router_id,
'--state_path=%s' % self.conf.state_path,
'--metadata_port=%s' % self.conf.metadata_port]
proxy_cmd.extend(config.get_log_args(
cfg.CONF, 'quantum-ns-metadata-proxy-%s.log' %
router_info.router_id))
return proxy_cmd
pm = external_process.ProcessManager(
self.conf,
router_info.router_id,
self.root_helper,
router_info.ns_name())
pm.enable(callback)
可见,启用namespace场景下,对于每一个router,都会创建这样一个进程。该进程监听9697端口,其主要功能:
root@network232:~# netstat -lxp | grep metadata
unix 2 [ ACC ] STREAM LISTENING 46859 21025/python /var/lib/quantum/metadata_proxy
root@network232:~# ps -f --pid 21025 | fold -s
UID PID PPID C STIME TTY TIME CMD
quantum 21025 1 0 16:31 ? 00:00:00 python
/usr/bin/quantum-metadata-agent --config-file=/etc/quantum/quantum.conf
--config-file=/etc/quantum/metadata_agent.ini
--log-file=/var/log/quantum/metadata-agent.log
该进程的功能是,根据请求头部的X-Forwarded-For和X-Quantum-Router-ID参数,向Quantum service查询虚拟机ID,然后向Nova Metadata服务发送请求(默认端口8775),消息头:X-Forwarded-For,X-Instance-ID、X-Instance-ID-Signature分别表示虚拟机的fixedIP,虚拟机ID和虚拟机ID的签名。
root@controller231:~# netstat -nlpt | grep 8775
tcp 0 0 0.0.0.0:8775 0.0.0.0:* LISTEN 1714/python
root@controller231:~# ps -f --pid 1714
UID PID PPID C STIME TTY TIME CMD
nova 1714 1 0 16:40 ? 00:00:01 /usr/bin/python /usr/bin/nova-api --config-file=/etc/nova/nova.conf