自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenStack虛擬機如何獲取metadata

云計算 虛擬化 OpenStack
cloud-init是運行在虛擬機內(nèi)部的一個進程,它通過datasource獲取虛擬機的配置信息(即metadata)。

 1. 關(guān)于OpenStack metadata服務(wù)

我們知道OpenStack虛擬機是通過cloud-init完成初始化配置,比如網(wǎng)卡配置、hostname、初始化密碼以及密鑰配置等。cloud-init是運行在虛擬機內(nèi)部的一個進程,它通過datasource獲取虛擬機的配置信息(即metadata)。cloud-init實現(xiàn)了很多不同的datasource,不同的datasource實現(xiàn)原理不一樣。比較常用的datasource主要有以下兩種:

  • ConfigDriver: Nova把所有配置信息寫入到本地的一個raw文件中,然后通過cdrom形式掛載到虛擬機中。此時在虛擬機內(nèi)部可以看到類似/dev/sr0(注:sr代表 scsi + rom)的虛擬設(shè)備。cloud-init只需要讀取/dev/sr0文件信息即可獲取虛擬機配置信息。
  • Metadata: Nova在本地啟動一個HTTP metadata服務(wù),虛擬機只需要通過HTTP訪問該metadata服務(wù)獲取相關(guān)的虛擬機配置信息。

ConfigDriver的實現(xiàn)原理比較簡單,本文不再介紹。這里重點介紹Metadata,主要解決以下兩個問題:

  1. Nova Metadata服務(wù)啟動在宿主機上(nova-api所在的控制節(jié)點),虛擬機內(nèi)部租戶網(wǎng)絡(luò)和宿主機的物理網(wǎng)絡(luò)是不通的,虛擬機如何訪問Nova的Metadata服務(wù)。
  2. 假設(shè)問題1已經(jīng)解決,那么Nova Metadata服務(wù)如何知道是哪個虛擬機發(fā)起的請求。

[[236018]]

2. Metadata服務(wù)配置

2.1 Nova配置

Nova的metadata服務(wù)名稱為nova-api-metadata,不過通常會把服務(wù)與nova-api服務(wù)合并:

  1. [DEFAULT
  2. enabled_apis = osapi_compute,metadata 

另外虛擬機訪問Nova的Metadata服務(wù)需要Neutron轉(zhuǎn)發(fā),原因后面講,這里只需要注意在nova.conf配置:

  1. [neutron] 
  2. service_metadata_proxy = true 

2.2 Neutron配置

前面提到虛擬機訪問Nova的Metadata服務(wù)需要Neutron轉(zhuǎn)發(fā),可以通過l3-agent轉(zhuǎn)發(fā),也可以通過dhcp-agent轉(zhuǎn)發(fā),如何選擇需要根據(jù)實際情況:

  • 通過l3-agent轉(zhuǎn)發(fā),則虛擬機所在的網(wǎng)絡(luò)必須關(guān)聯(lián)了router。
  • 通過dhcp-agent轉(zhuǎn)發(fā),則虛擬機所在的網(wǎng)絡(luò)必須開啟dhcp功能。

Metadata默認是通過l3-agent轉(zhuǎn)發(fā)的,不過由于在實際情況下,虛擬機的網(wǎng)絡(luò)通常都會開啟dhcp功能,但不一定需要router,因此我更傾向于選擇通過dhcp-agent轉(zhuǎn)發(fā),配置如下:

  1. # /etc/neutron/dhcp_agent.ini [DEFAULT
  2. force_metadata = true 
  3.  
  4. # /etc/neuron/l3_agent.ini [DEFAULT
  5. enable_metadata_proxy = false 

本文接下來的所有內(nèi)容均基于以上配置環(huán)境。

3 OpenStack虛擬機如何訪問Nova Metadata服務(wù)

3.1 從虛擬機訪問Metadata服務(wù)說起

cloud-init訪問metadata服務(wù)的URL地址是http://169.254.169.254,這個IP很特別,主要是效仿了AWS的Metadata服務(wù)地址,它的網(wǎng)段是169.254.0.0/16,這個IP段其實是保留的,即IPv4 Link Local Address,它和私有IP(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)類似,不能用于互聯(lián)網(wǎng)路由,通常只用于直連網(wǎng)絡(luò)。如果操作系統(tǒng)(Windows)獲取IP失敗,也有可能自動配置為169.254.0.0/16網(wǎng)段的一個IP。

那AWS為什么選擇169.254.169.254這個IP呢,這是因為選擇Link Local IP可以避免與用戶的IP沖突,至于為什么選擇169.254.169.254這個IP而不是169.254.0.0/24的其它IP,大概是為了好記吧。

另外AWS還有幾個很有趣的地址:

  • 169.254.169.253: DNS服務(wù)。
  • 169.254.169.123: NTP服務(wù)。

更多關(guān)于169.254.169.254信息,可以參考whats-special-about-169-254-169-254-ip-address-for-aws。

OpenStack虛擬機也是通過http://169.254.169.254獲取虛擬機的初始化配置信息:

  1. $ curl -sL 169.254.169.254/openstack/latest/meta_data.json {"uuid""daf32a70-42c9-4d30-8ec5-3a5d97582cff""availability_zone""nova""hostname""int32bit-test-1.novalocal""launch_index": 0, "devices": [], "project_id""ca17d50f6ac049928cc2fb2217dab93b""name""int32bit-test-1"

從以上輸出可見從metadata服務(wù)中我們獲取了虛擬機的uuid、name、project id、availability_zone、hostname等。

虛擬機怎么通過訪問169.254.169.254這個地址就可以獲取Metadata信息呢,我們首先查看下虛擬機的路由表:

  1. # route -n 
  2. Kernel IP routing table 
  3. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface 
  4. 0.0.0.0         10.0.0.126      0.0.0.0         UG    0      0        0 eth0 
  5. 10.0.0.64       0.0.0.0         255.255.255.192 U     0      0        0 eth0 
  6. 169.254.169.254 10.0.0.66       255.255.255.255 UGH   0      0        0 eth0 

我們可以看到169.254.169.254的下一跳為10.0.0.66。10.0.0.66這個IP是什么呢?我們通過Neutron的port信息查看下:

  1. # neutron port-list -c network_id -c device_owner -c mac_address -c fixed_ips -f csv | grep 10.0.0.66 
  2. "2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a","network:dhcp","fa:16:3e:b3:e8:38","[{u'subnet_id': u'6f046aae-2158-4882-a818-c56d81bc8074', u'ip_address': u'10.0.0.66'}]" 

可看到10.0.0.66正好是網(wǎng)絡(luò)2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a的dhcp地址,可以進一步驗證:

  1. # ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a ifconfig 
  2. tap1332271e-0d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450 
  3.         inet 10.0.0.66  netmask 255.255.255.192  broadcast 10.0.0.127 
  4.         inet6 fe80::f816:3eff:feb3:e838  prefixlen 64  scopeid 0x20<link> 
  5.         ether fa:16:3e:b3:e8:38  txqueuelen 1000  (Ethernet) 
  6.         RX packets 662  bytes 58001 (56.6 KiB) 
  7.         RX errors 0  dropped 0  overruns 0  frame 0 
  8.         TX packets 410  bytes 55652 (54.3 KiB) 
  9.         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

由此,我們可以得出結(jié)論,OpenStack虛擬機訪問169.254.169.254會路由到虛擬機所在網(wǎng)絡(luò)的DHCP地址,DHCP地址與虛擬機IP肯定是可以互通的,從而解決了虛擬機內(nèi)部到宿主機外部的通信問題。那DHCP又如何轉(zhuǎn)發(fā)到Nova Metadata服務(wù)呢,下一節(jié)將介紹如何解決這個問題。

3.2 Metadata請求***次轉(zhuǎn)發(fā)

前面介紹了虛擬機訪問Metadata服務(wù)地址169.254.169.254,然后轉(zhuǎn)發(fā)到DHCP地址。我們知道Neutron的DHCP port被放到了namespace中,我們不妨進入到虛擬機所在網(wǎng)絡(luò)的namespace:

  1. ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a bash 

首先查看該namespace的路由:

  1. # route -n 
  2. Kernel IP routing table 
  3. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface 
  4. 0.0.0.0         10.0.0.126      0.0.0.0         UG    0      0        0 tap1332271e-0d 
  5. 10.0.0.64       0.0.0.0         255.255.255.192 U     0      0        0 tap1332271e-0d 
  6. 169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 tap1332271e-0d 

從路由表中看出169.254.0.0/16是從網(wǎng)卡tap1332271e-0d發(fā)出去的,我們查看網(wǎng)卡地址信息:

  1. # ip a 
  2. 18: tap1332271e-0d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000 
  3.     link/ether fa:16:3e:b3:e8:38 brd ff:ff:ff:ff:ff:ff 
  4.     inet 10.0.0.66/26 brd 10.0.0.127 scope global tap1332271e-0d 
  5.        valid_lft forever preferred_lft forever 
  6.     inet 169.254.169.254/16 brd 169.254.255.255 scope global tap1332271e-0d 
  7.        valid_lft forever preferred_lft forever 
  8.     inet6 fe80::f816:3eff:feb3:e838/64 scope link 
  9.        valid_lft forever preferred_lft forever 

我們發(fā)現(xiàn),169.254.169.254其實是配在網(wǎng)卡tap1332271e-0d的一個虛擬IP。虛擬機能夠訪問169.254.169.254這個地址也就不足為奇了。需要注意的是,本文的metadata轉(zhuǎn)發(fā)配置是通過dhcp-agent實現(xiàn)的,如果是l3-agent,則169.254.169.254是通過iptables轉(zhuǎn)發(fā)。

我們能夠訪問curl http://169.254.169.254,說明這個地址肯定開放了80端口:

  1. # netstat -lnpt 
  2. Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name 
  3. tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      11334/haproxy 
  4. tcp        0      0 10.0.0.66:53            0.0.0.0:*               LISTEN      11331/dnsmasq 
  5. tcp        0      0 169.254.169.254:53      0.0.0.0:*               LISTEN      11331/dnsmasq 
  6. tcp6       0      0 fe80::f816:3eff:feb3:53 :::*                    LISTEN      11331/dnsmasq 

從輸出中看,所在的環(huán)境除了開啟了DHCP服務(wù)(53端口),確實監(jiān)聽了80端口,進程pid為11334/haproxy。

我們看到haproxy這個進程就可以猜測是負責請求的代理與轉(zhuǎn)發(fā),即OpenStack虛擬機首先會把請求轉(zhuǎn)發(fā)到DHCP所在namespace的haproxy監(jiān)聽端口80。

問題又來了,DHCP所在的namespace網(wǎng)絡(luò)仍然和Nova Metadata是不通的,那haproxy如何轉(zhuǎn)發(fā)請求到Nova Metadata服務(wù)呢,我們下一節(jié)介紹。

3.3 Metadata請求第二次轉(zhuǎn)發(fā)

前面我們介紹了OpenStack虛擬機訪問http://169.254.169.254會被轉(zhuǎn)發(fā)到DHCP所在namespace的haproxy監(jiān)聽的80端口中。但是,namespace中仍然無法訪問Nova Metadata服務(wù)。

為了研究解決辦法,我們首先看下這個haproxy進程信息:

  1. cat /proc/11334/cmdline | tr '\0' ' ' 
  2. haproxy -f /opt/stack/data/neutron/ns-metadata-proxy/2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a.conf 

其中2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a.conf配置文件部分內(nèi)容如下:

  1. listen listener 
  2.     bind 0.0.0.0:80 
  3.     server metadata /opt/stack/data/neutron/metadata_proxy 
  4.     http-request add-header X-Neutron-Network-ID 2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a 

我們發(fā)現(xiàn)haproxy綁定的端口為80,后端地址為一個文件/opt/stack/data/neutron/metadata_proxy。后端不是一個IP/TCP地址,那必然是一個UNIX Socket文件:

  1. # ll /opt/stack/data/neutron/metadata_proxy 
  2. srw-r--r-- 1 stack stack 0 Jul  1 13:30 /opt/stack/data/neutron/metadata_proxy 

因此我們得出結(jié)論,haproxy進程會把OpenStack虛擬機Metadata請求轉(zhuǎn)發(fā)到本地的一個socket文件中。

UNIX Domain Socket是在socket架構(gòu)上發(fā)展起來的用于同一臺主機的進程間通訊(IPC),它不需要經(jīng)過網(wǎng)絡(luò)協(xié)議棧實現(xiàn)將應(yīng)用層數(shù)據(jù)從一個進程拷貝到另一個進程,有點類似于Unix管道(pipeline)。

問題又來了:

  • 我們從haproxy配置看,監(jiān)聽的地址是0.0.0.0:80,那如果有多個網(wǎng)絡(luò)同時都監(jiān)聽80端口豈不是會出現(xiàn)端口沖突嗎?
  • socket只能用于同一主機的進程間通信,如果Nova Metadata服務(wù)與Neutron dhcp-agent不在同一個主機,則顯然還是無法通信。

***個問題其實前面已經(jīng)解決了,haproxy是在虛擬機所在網(wǎng)絡(luò)的DHCP namespace中啟動的,我們可以驗證:

  1. # lsof -i :80 
  2. COMMAND   PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME 
  3. haproxy 11334 stack    4u  IPv4 65729753      0t0  TCP *:http (LISTEN) 
  4. # ip netns identify 11334 
  5. qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a 

關(guān)于第二個問題,顯然還需要一層轉(zhuǎn)發(fā),具體內(nèi)容請看下一小節(jié)內(nèi)容。

另外需要注意的是,新版本的OpenStack是直接使用haproxy代理轉(zhuǎn)發(fā)的,在一些老版本中則使用neutron-ns-metadata-proxy進程負責轉(zhuǎn)發(fā),實現(xiàn)的代碼位于neutron/agent/metadata/namespace_proxy.py:

  1. def _proxy_request(self, remote_address, method, path_info, 
  2.                        query_string, body): 
  3.     headers = { 
  4.         'X-Forwarded-For': remote_address, 
  5.     } 
  6.  
  7.     if self.router_id: 
  8.         headers['X-Neutron-Router-ID'] = self.router_id 
  9.     else
  10.         headers['X-Neutron-Network-ID'] = self.network_id 
  11.  
  12.     url = urlparse.urlunsplit(( 
  13.         'http'
  14.         '169.254.169.254'
  15.         path_info, 
  16.         query_string, 
  17.         '')) 
  18.  
  19.     h = httplib2.Http() 
  20.     resp, content = h.request( 
  21.         url, 
  22.         method=method, 
  23.         headers=headers, 
  24.         body=body, 
  25.         connection_type=agent_utils.UnixDomainHTTPConnection) 

大家可能對請求URL為169.254.169.254有疑問,怎么轉(zhuǎn)發(fā)給自己呢? 這是因為這是一個UNIX Domain Socket請求,其實這個URL只是個參數(shù)占位,填什么都無所謂,這個請求相當于:

  1. curl -H "X-Neutron-Network-ID: ${network_uuid}" \ 
  2.      -H "X-Forwarded-For: ${request_ip}" \ 
  3.      -X GET \ 
  4.      --unix /var/lib/neutron/metadata_proxy \ 
  5.      http://169.254.169.254 

3.4 Metadata請求第三次轉(zhuǎn)發(fā)

前面說到,haproxy會把Metadata請求轉(zhuǎn)發(fā)到本地的一個socket文件中,那么,到底是哪個進程在監(jiān)聽/opt/stack/data/neutron/metadata_proxysocket文件呢?我們通過lsof查看下:

  1. # lsof /opt/stack/data/neutron/metadata_proxy 
  2. COMMAND     PID  USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME 
  3. neutron-m 11085 stack    3u  unix 0xffff8801c8711c00      0t0 65723197 /opt/stack/data/neutron/metadata_proxy 
  4. neutron-m 11108 stack    3u  unix 0xffff8801c8711c00      0t0 65723197 /opt/stack/data/neutron/metadata_proxy 
  5. neutron-m 11109 stack    3u  unix 0xffff8801c8711c00      0t0 65723197 /opt/stack/data/neutron/metadata_proxy 
  6. # cat /proc/11085/cmdline  | tr '\0' ' ' 
  7. /usr/bin/python /usr/bin/neutron-metadata-agent --config-file /etc/neutron/neutron.conf 

可見neutron-metadata-agent監(jiān)聽了這個socket文件,相當于haproxy把Metadata服務(wù)通過socket文件轉(zhuǎn)發(fā)給了neutron-metadata-agent服務(wù)。

  1. def run(self): 
  2.     server = agent_utils.UnixDomainWSGIServer('neutron-metadata-agent'
  3.     server.start(MetadataProxyHandler(self.conf), 
  4.                  self.conf.metadata_proxy_socket, 
  5.                  workers=self.conf.metadata_workers, 
  6.                  backlog=self.conf.metadata_backlog, 
  7.                  mode=self._get_socket_mode()) 
  8.     self._init_state_reporting() 
  9.     server.wait() 

進一步驗證了neutron-metadata-agent監(jiān)聽了/opt/stack/data/neutron/metadata_proxysocket文件。

由于neutron-metadata-agent是控制節(jié)點上的進程,因此和Nova Metadata服務(wù)肯定是通的, OpenStack虛擬機如何訪問Nova Metadata服務(wù)問題基本就解決了。

  1. curl 169.254.169.254 -> haproxy(80端口) -> UNIX Socket文件 -> neutron-metadata-agent -> nova-api-metadata 

即一共需要三次轉(zhuǎn)發(fā)。

但是Nova Metadata服務(wù)如何知道是哪個虛擬機發(fā)送過來的請求呢?換句話說,如何獲取該虛擬機的uuid,我們將在下一章介紹。

4 Metadata服務(wù)如何獲取虛擬機信息

前一章介紹了OpenStack虛擬機如何通過169.254.169.254到達Nova Metadata服務(wù),那到達之后如何判斷是哪個虛擬機發(fā)送過來的呢?

OpenStack是通過neutron-metadata-agent獲取虛擬機的uuid的。我們知道,在同一個Neutron network中,即使有多個subnet,也不允許IP重復(fù),即通過IP地址能夠唯一確定Neutron的port信息。而neutron port會設(shè)置device_id標識消費者信息,對于虛擬機來說,即虛擬機的uuid。

因此neutron-metadata-agent通過network uuid以及虛擬機ip即可獲取虛擬機的uuid。

不知道大家是否還記得在haproxy配置文件中存在一條配置項:

  1. http-request add-header X-Neutron-Network-ID 2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a 

即haproxy轉(zhuǎn)發(fā)之前會把network id添加到請求頭部中,而IP可以通過HTTP的頭部X-Forwarded-For中獲取。因此neutron-metadata-agent具備獲取虛擬機的uuid以及project id(租戶id)條件,我們可以查看neutron-metadata-agent獲取虛擬機uuid以及project id實現(xiàn),代碼位于neutron/agent/metadata/agent.py:

  1. def _get_instance_and_tenant_id(self, req): 
  2.     remote_address = req.headers.get('X-Forwarded-For'
  3.     network_id = req.headers.get('X-Neutron-Network-ID'
  4.     router_id = req.headers.get('X-Neutron-Router-ID'
  5.  
  6.     ports = self._get_ports(remote_address, network_id, router_id) 
  7.     if len(ports) == 1: 
  8.         return ports[0]['device_id'], ports[0]['tenant_id'
  9.     return None, None 

如果誰都可以偽造Metadata請求獲取任何虛擬機的metadata信息,顯然是不安全的,因此在轉(zhuǎn)發(fā)給Nova Metadata服務(wù)之前,還需要發(fā)一個secret:

  1. def _sign_instance_id(self, instance_id): 
  2.     secret = self.conf.metadata_proxy_shared_secret 
  3.     secret = encodeutils.to_utf8(secret) 
  4.     instance_id = encodeutils.to_utf8(instance_id) 
  5.     return hmac.new(secret, instance_id, hashlib.sha256).hexdigest() 

metadata_proxy_shared_secret需要管理員配置,然后組合虛擬機的uuid生成一個隨機的字符串作為key。

最終,neutron-metadata-agent會把虛擬機信息放到頭部中,發(fā)送到Nova Metadata服務(wù)的頭部信息如下:

  1. headers = { 
  2.     'X-Forwarded-For': req.headers.get('X-Forwarded-For'), 
  3.     'X-Instance-ID': instance_id, 
  4.     'X-Tenant-ID': tenant_id, 
  5.     'X-Instance-ID-Signature': self._sign_instance_id(instance_id) 

此時Nova Metadata就可以通過虛擬機的uuid查詢metadata信息了,代碼位于nova/api/metadata/base.py:

  1. def get_metadata_by_instance_id(instance_id, address, ctxt=None): 
  2.     ctxt = ctxt or context.get_admin_context() 
  3.     attrs = ['ec2_ids''flavor''info_cache'
  4.              'metadata''system_metadata'
  5.              'security_groups''keypairs'
  6.              'device_metadata'
  7.     try: 
  8.         im = objects.InstanceMapping.get_by_instance_uuid(ctxt, instance_id) 
  9.     except exception.InstanceMappingNotFound: 
  10.         LOG.warning('Instance mapping for %(uuid)s not found; ' 
  11.                     'cell setup is incomplete', {'uuid': instance_id}) 
  12.         instance = objects.Instance.get_by_uuid(ctxt, instance_id, 
  13.                                                 expected_attrs=attrs) 
  14.         return InstanceMetadata(instance, address) 
  15.  
  16.     with context.target_cell(ctxt, im.cell_mapping) as cctxt: 
  17.         instance = objects.Instance.get_by_uuid(cctxt, instance_id, 
  18.                                                 expected_attrs=attrs) 
  19.         return InstanceMetadata(instance, address) 

5 在虛擬機外部如何獲取虛擬機metadata

前面已經(jīng)介紹了OpenStack虛擬機從Nova Metadata服務(wù)獲取metadata的過程。有時候我們可能需要調(diào)試虛擬機的metadata信息,驗證傳遞的數(shù)據(jù)是否正確,而又嫌麻煩不希望進入虛擬機內(nèi)部去調(diào)試。有什么方法能夠直接調(diào)用nova-api-metadata服務(wù)獲取虛擬機信息呢。

根據(jù)前面介紹的原理,我寫了兩個腳本實現(xiàn):

***個Python腳本sign_instance.py用于生成secret:

  1. sign_instance.py 
  2.  
  3. import six 
  4. import sys 
  5. import hmac 
  6. import hashlib 
  7.  
  8. def sign_instance_id(instance_id, secret=''): 
  9.     if isinstance(secret, six.text_type): 
  10.         secret = secret.encode('utf-8'
  11.     if isinstance(instance_id, six.text_type): 
  12.         instance_id = instance_id.encode('utf-8'
  13.     return hmac.new(secret, instance_id, hashlib.sha256).hexdigest() 
  14. print(sign_instance_id(sys.argv[1])) 

第二個bash腳本get_metadata.py實現(xiàn)獲取虛擬機metadata:

  1. #!/bin/bash 
  2. metadata_server=http://192.168.1.16:8775 
  3. metadata_url=$metadata_server/openstack/latest 
  4. instance_id=$1 
  5. data=$2 
  6. if [[ -z $instance_id ]]; then echo "Usage: $0 <instance_id>" 
  7.     exit 1 
  8. fi tenant_id=$(nova show $instance_id | awk '/tenant_id/{print $4}'
  9. sign_instance_id=$(python sign_instance.py $instance_id) 
  10. curl -sL -H "X-Instance-ID:$instance_id" -H "X-Instance-ID-Signature:$sign_instance_id" -H "X-Tenant-ID:$tenant_id"  $metadata_url/$data 

其中metadata_server為Nova Metadata服務(wù)地址。

用法如下:

  1. # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff 
  2. meta_data.json 
  3. password 
  4. vendor_data.json 
  5. network_data.json 
  6. # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff network_data.json | python -m json.tool 
  7.     "links": [ 
  8.         { 
  9.             "ethernet_mac_address""fa:16:3e:e8:81:9b"
  10.             "id""tap28468932-9e"
  11.             "mtu": 1450, 
  12.             "type""ovs"
  13.             "vif_id""28468932-9ea0-43d0-b699-ba19bf65cae3" 
  14.         } 
  15.     ], 
  16.     "networks": [ 
  17.         { 
  18.             "id""network0"
  19.             "link""tap28468932-9e"
  20.             "network_id""2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a"
  21.             "type""ipv4_dhcp" 
  22.         } 
  23.     ], 
  24.     "services": [] 

5 總結(jié)

***通過一張工作流圖總結(jié):

OpenStack Metadata Workflow

源碼:

  1. title OpenStack Metadata WorkFlow  
  2.   
  3. participant vm  
  4. participant haproxy  
  5. participant UNIX Socket  
  6. participant neutron-metadata-agent  
  7. participant nova-api-metadata  
  8.   
  9. vm -> haproxy: curl 169.254.169.254(***次轉(zhuǎn)發(fā))   
  10. note over haproxy: Add header X-Neutron-Network-ID  
  11. haproxy -> UNIX Socket: 第二次轉(zhuǎn)發(fā)  
  12. UNIX Socket -> neutron-metadata-agent: 第二次轉(zhuǎn)發(fā)  
  13. note over neutron-metadata-agent: get_instance_and_tenant_id  
  14. note over neutron-metadata-agent: sign_instance_id  
  15. neutron-metadata-agent -> nova-api-metadata: 第三次轉(zhuǎn)發(fā)   
  16. note over nova-api-metadata: get_metadata_by_instance_id  
  17. nova-api-metadata -> neutron-metadata-agent: metadata  
  18. neutron-metadata-agent -> UNIX Socket: metadata  
  19. UNIX Socket -> haproxy: metadata  
  20. haproxy -> vm: metadata  

 【本文是51CTO專欄作者“付廣平”的原創(chuàng)文章,如需轉(zhuǎn)載請通過51CTO獲得聯(lián)系】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2016-09-01 12:37:13

OpenStack虛擬機Metadata

2011-12-12 09:08:48

OpenStack虛擬機監(jiān)控

2015-09-18 10:40:04

OpenStackMetadata虛擬機配置

2014-04-16 13:22:29

虛擬機OpenStack命令行

2014-04-16 10:44:56

OpenStack命令行工具虛擬機

2012-04-10 10:29:29

2010-12-23 14:05:12

虛擬機

2017-09-14 10:11:24

OpenStack虛擬機過程分析

2022-08-14 09:11:13

Kubernetes容器云原生

2012-05-18 10:22:23

2015-07-08 14:33:23

虛擬機OpenStack

2015-05-15 10:36:13

2010-07-26 09:02:38

2013-07-17 09:32:58

2010-02-26 15:28:15

Python虛擬機

2009-06-12 16:15:42

死鎖Java虛擬機

2012-04-27 09:29:57

虛擬化虛擬機

2009-06-29 19:36:07

虛擬機備份虛擬環(huán)境

2013-11-19 14:05:08

VDP虛擬機

2013-04-07 09:52:40

Ubuntu虛擬機虛擬化軟件
點贊
收藏

51CTO技術(shù)棧公眾號