OpenStack虛擬機如何獲取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,主要解決以下兩個問題:
- Nova Metadata服務(wù)啟動在宿主機上(nova-api所在的控制節(jié)點),虛擬機內(nèi)部租戶網(wǎng)絡(luò)和宿主機的物理網(wǎng)絡(luò)是不通的,虛擬機如何訪問Nova的Metadata服務(wù)。
- 假設(shè)問題1已經(jīng)解決,那么Nova Metadata服務(wù)如何知道是哪個虛擬機發(fā)起的請求。
2. Metadata服務(wù)配置
2.1 Nova配置
Nova的metadata服務(wù)名稱為nova-api-metadata,不過通常會把服務(wù)與nova-api服務(wù)合并:
- [DEFAULT]
- enabled_apis = osapi_compute,metadata
另外虛擬機訪問Nova的Metadata服務(wù)需要Neutron轉(zhuǎn)發(fā),原因后面講,這里只需要注意在nova.conf配置:
- [neutron]
- 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ā),配置如下:
- # /etc/neutron/dhcp_agent.ini [DEFAULT]
- force_metadata = true
- # /etc/neuron/l3_agent.ini [DEFAULT]
- 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獲取虛擬機的初始化配置信息:
- $ 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信息呢,我們首先查看下虛擬機的路由表:
- # route -n
- Kernel IP routing table
- Destination Gateway Genmask Flags Metric Ref Use Iface
- 0.0.0.0 10.0.0.126 0.0.0.0 UG 0 0 0 eth0
- 10.0.0.64 0.0.0.0 255.255.255.192 U 0 0 0 eth0
- 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信息查看下:
- # neutron port-list -c network_id -c device_owner -c mac_address -c fixed_ips -f csv | grep 10.0.0.66
- "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地址,可以進一步驗證:
- # ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a ifconfig
- tap1332271e-0d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
- inet 10.0.0.66 netmask 255.255.255.192 broadcast 10.0.0.127
- inet6 fe80::f816:3eff:feb3:e838 prefixlen 64 scopeid 0x20<link>
- ether fa:16:3e:b3:e8:38 txqueuelen 1000 (Ethernet)
- RX packets 662 bytes 58001 (56.6 KiB)
- RX errors 0 dropped 0 overruns 0 frame 0
- TX packets 410 bytes 55652 (54.3 KiB)
- 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:
- ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a bash
首先查看該namespace的路由:
- # route -n
- Kernel IP routing table
- Destination Gateway Genmask Flags Metric Ref Use Iface
- 0.0.0.0 10.0.0.126 0.0.0.0 UG 0 0 0 tap1332271e-0d
- 10.0.0.64 0.0.0.0 255.255.255.192 U 0 0 0 tap1332271e-0d
- 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)卡地址信息:
- # ip a
- 18: tap1332271e-0d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000
- link/ether fa:16:3e:b3:e8:38 brd ff:ff:ff:ff:ff:ff
- inet 10.0.0.66/26 brd 10.0.0.127 scope global tap1332271e-0d
- valid_lft forever preferred_lft forever
- inet 169.254.169.254/16 brd 169.254.255.255 scope global tap1332271e-0d
- valid_lft forever preferred_lft forever
- inet6 fe80::f816:3eff:feb3:e838/64 scope link
- 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端口:
- # netstat -lnpt
- Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
- tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11334/haproxy
- tcp 0 0 10.0.0.66:53 0.0.0.0:* LISTEN 11331/dnsmasq
- tcp 0 0 169.254.169.254:53 0.0.0.0:* LISTEN 11331/dnsmasq
- 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進程信息:
- cat /proc/11334/cmdline | tr '\0' ' '
- haproxy -f /opt/stack/data/neutron/ns-metadata-proxy/2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a.conf
其中2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a.conf配置文件部分內(nèi)容如下:
- listen listener
- bind 0.0.0.0:80
- server metadata /opt/stack/data/neutron/metadata_proxy
- 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文件:
- # ll /opt/stack/data/neutron/metadata_proxy
- 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中啟動的,我們可以驗證:
- # lsof -i :80
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- haproxy 11334 stack 4u IPv4 65729753 0t0 TCP *:http (LISTEN)
- # ip netns identify 11334
- 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:
- def _proxy_request(self, remote_address, method, path_info,
- query_string, body):
- headers = {
- 'X-Forwarded-For': remote_address,
- }
- if self.router_id:
- headers['X-Neutron-Router-ID'] = self.router_id
- else:
- headers['X-Neutron-Network-ID'] = self.network_id
- url = urlparse.urlunsplit((
- 'http',
- '169.254.169.254',
- path_info,
- query_string,
- ''))
- h = httplib2.Http()
- resp, content = h.request(
- url,
- method=method,
- headers=headers,
- body=body,
- connection_type=agent_utils.UnixDomainHTTPConnection)
大家可能對請求URL為169.254.169.254有疑問,怎么轉(zhuǎn)發(fā)給自己呢? 這是因為這是一個UNIX Domain Socket請求,其實這個URL只是個參數(shù)占位,填什么都無所謂,這個請求相當于:
- curl -H "X-Neutron-Network-ID: ${network_uuid}" \
- -H "X-Forwarded-For: ${request_ip}" \
- -X GET \
- --unix /var/lib/neutron/metadata_proxy \
- 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查看下:
- # lsof /opt/stack/data/neutron/metadata_proxy
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- neutron-m 11085 stack 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
- neutron-m 11108 stack 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
- neutron-m 11109 stack 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
- # cat /proc/11085/cmdline | tr '\0' ' '
- /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ù)。
- def run(self):
- server = agent_utils.UnixDomainWSGIServer('neutron-metadata-agent')
- server.start(MetadataProxyHandler(self.conf),
- self.conf.metadata_proxy_socket,
- workers=self.conf.metadata_workers,
- backlog=self.conf.metadata_backlog,
- mode=self._get_socket_mode())
- self._init_state_reporting()
- server.wait()
進一步驗證了neutron-metadata-agent監(jiān)聽了/opt/stack/data/neutron/metadata_proxysocket文件。
由于neutron-metadata-agent是控制節(jié)點上的進程,因此和Nova Metadata服務(wù)肯定是通的, OpenStack虛擬機如何訪問Nova Metadata服務(wù)問題基本就解決了。
- 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配置文件中存在一條配置項:
- 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:
- def _get_instance_and_tenant_id(self, req):
- remote_address = req.headers.get('X-Forwarded-For')
- network_id = req.headers.get('X-Neutron-Network-ID')
- router_id = req.headers.get('X-Neutron-Router-ID')
- ports = self._get_ports(remote_address, network_id, router_id)
- if len(ports) == 1:
- return ports[0]['device_id'], ports[0]['tenant_id']
- return None, None
如果誰都可以偽造Metadata請求獲取任何虛擬機的metadata信息,顯然是不安全的,因此在轉(zhuǎn)發(fā)給Nova Metadata服務(wù)之前,還需要發(fā)一個secret:
- def _sign_instance_id(self, instance_id):
- secret = self.conf.metadata_proxy_shared_secret
- secret = encodeutils.to_utf8(secret)
- instance_id = encodeutils.to_utf8(instance_id)
- return hmac.new(secret, instance_id, hashlib.sha256).hexdigest()
metadata_proxy_shared_secret需要管理員配置,然后組合虛擬機的uuid生成一個隨機的字符串作為key。
最終,neutron-metadata-agent會把虛擬機信息放到頭部中,發(fā)送到Nova Metadata服務(wù)的頭部信息如下:
- headers = {
- 'X-Forwarded-For': req.headers.get('X-Forwarded-For'),
- 'X-Instance-ID': instance_id,
- 'X-Tenant-ID': tenant_id,
- 'X-Instance-ID-Signature': self._sign_instance_id(instance_id)
- }
此時Nova Metadata就可以通過虛擬機的uuid查詢metadata信息了,代碼位于nova/api/metadata/base.py:
- def get_metadata_by_instance_id(instance_id, address, ctxt=None):
- ctxt = ctxt or context.get_admin_context()
- attrs = ['ec2_ids', 'flavor', 'info_cache',
- 'metadata', 'system_metadata',
- 'security_groups', 'keypairs',
- 'device_metadata']
- try:
- im = objects.InstanceMapping.get_by_instance_uuid(ctxt, instance_id)
- except exception.InstanceMappingNotFound:
- LOG.warning('Instance mapping for %(uuid)s not found; '
- 'cell setup is incomplete', {'uuid': instance_id})
- instance = objects.Instance.get_by_uuid(ctxt, instance_id,
- expected_attrs=attrs)
- return InstanceMetadata(instance, address)
- with context.target_cell(ctxt, im.cell_mapping) as cctxt:
- instance = objects.Instance.get_by_uuid(cctxt, instance_id,
- expected_attrs=attrs)
- 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:
- sign_instance.py
- import six
- import sys
- import hmac
- import hashlib
- def sign_instance_id(instance_id, secret=''):
- if isinstance(secret, six.text_type):
- secret = secret.encode('utf-8')
- if isinstance(instance_id, six.text_type):
- instance_id = instance_id.encode('utf-8')
- return hmac.new(secret, instance_id, hashlib.sha256).hexdigest()
- print(sign_instance_id(sys.argv[1]))
第二個bash腳本get_metadata.py實現(xiàn)獲取虛擬機metadata:
- #!/bin/bash
- metadata_server=http://192.168.1.16:8775
- metadata_url=$metadata_server/openstack/latest
- instance_id=$1
- data=$2
- if [[ -z $instance_id ]]; then echo "Usage: $0 <instance_id>"
- exit 1
- fi tenant_id=$(nova show $instance_id | awk '/tenant_id/{print $4}')
- sign_instance_id=$(python sign_instance.py $instance_id)
- 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ù)地址。
用法如下:
- # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff
- meta_data.json
- password
- vendor_data.json
- network_data.json
- # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff network_data.json | python -m json.tool
- {
- "links": [
- {
- "ethernet_mac_address": "fa:16:3e:e8:81:9b",
- "id": "tap28468932-9e",
- "mtu": 1450,
- "type": "ovs",
- "vif_id": "28468932-9ea0-43d0-b699-ba19bf65cae3"
- }
- ],
- "networks": [
- {
- "id": "network0",
- "link": "tap28468932-9e",
- "network_id": "2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a",
- "type": "ipv4_dhcp"
- }
- ],
- "services": []
- }
5 總結(jié)
***通過一張工作流圖總結(jié):
OpenStack Metadata Workflow
源碼:
- title OpenStack Metadata WorkFlow
- participant vm
- participant haproxy
- participant UNIX Socket
- participant neutron-metadata-agent
- participant nova-api-metadata
- vm -> haproxy: curl 169.254.169.254(***次轉(zhuǎn)發(fā))
- note over haproxy: Add header X-Neutron-Network-ID
- haproxy -> UNIX Socket: 第二次轉(zhuǎn)發(fā)
- UNIX Socket -> neutron-metadata-agent: 第二次轉(zhuǎn)發(fā)
- note over neutron-metadata-agent: get_instance_and_tenant_id
- note over neutron-metadata-agent: sign_instance_id
- neutron-metadata-agent -> nova-api-metadata: 第三次轉(zhuǎn)發(fā)
- note over nova-api-metadata: get_metadata_by_instance_id
- nova-api-metadata -> neutron-metadata-agent: metadata
- neutron-metadata-agent -> UNIX Socket: metadata
- UNIX Socket -> haproxy: metadata
- haproxy -> vm: metadata
【本文是51CTO專欄作者“付廣平”的原創(chuàng)文章,如需轉(zhuǎn)載請通過51CTO獲得聯(lián)系】