1. 程式人生 > >【OpenStack】metadata在OpenStack中的使用(一)

【OpenStack】metadata在OpenStack中的使用(一)

宣告:

本部落格歡迎轉發,但請保留原作者資訊!

新浪微博:@孔令賢HW

內容系本人學習、研究和總結,如有雷同,實屬榮幸!

版本: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的作用和由來。不懂的童鞋看這裡

1、虛擬機發出請求

虛擬機器啟動時會訪問169.254.169.254獲取一些內容。這個從我之前出錯的日誌中就可以看出來:
'http://169.254.169.254/2009-04-04/meta-data/instance-id' failed [0/120s]: http error [404]

在虛擬機器內部訪問169.254.169.254,看一下都有什麼:
[email protected]
:~$ 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上。虛擬機器的網絡卡資訊如下:
[email protected]
:~$ ip -4 address show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 10.1.1.2/24 brd 10.1.1.255 scope global eth0
虛擬機器的路由資訊:
[email protected]:~$  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

2、namespace-metadata-proxy

因為使用了namespace,在network node上每個namespace裡都會有相應的iptables規則和網路裝置。
先來看看對應的iptables規則:
-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):
[email protected]:~# ip netns exec qrouter-b147a74b-39bb-4c7a-aed5-19cac4c2df13 ip addr show qr-f7ec0f5c-2e
12: qr-f7ec0f5c-2e: <BROADCAST,MULTICAST,UP,LOWER_UP> 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上,在該埠的監聽程序:
[email protected]:~# 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,看一下這個程序:
[email protected]:~# 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埠,其主要功能:
1、向請求頭部新增X-Forwarded-For和X-Quantum-Router-ID,分別表示虛擬機器的fixedIP和router的ID
2、將請求代理至Unix domain socket(/var/lib/quantum/metadata_proxy)

3、Quantum Metadata Agent

network node上的metadata agent監聽/var/lib/quantum/metadata_proxy:
[email protected]:~# netstat -lxp | grep metadata
unix  2      [ ACC ]     STREAM     LISTENING     46859    21025/python        /var/lib/quantum/metadata_proxy
[email protected]:~# 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的簽名。

4、Nova Metadata Service

Nova的metadata service是隨著nova-api啟動的,會同時啟動三個服務:ec2, osapi_compute, metadata。虛擬機器訪問169.254.169.254的返回內容,其實就是metadata服務向nova-conductor查詢後,返回給network node的metadata agent,再由metadata agent返回給metadata proxy,然後返回給虛擬機器的。
[email protected]:~# netstat -nlpt | grep 8775
tcp        0      0 0.0.0.0:8775            0.0.0.0:*               LISTEN      1714/python     
[email protected]:~# 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