iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0

建立 instance 的時候,我們希望對 instance 進行一些額外的配置,比如:添加 SSH 金鑰、配置 hostname 等等。這可以透過metadata service完成。Instance 啟動時,先會向 Metadata Service 請求並獲取自己的 metadata,instance 的 cloud-init會根據 metadata 完成這些額外的配置工作。而metadata service 所用的 IP是169.254.169.254。但是169.254.0.0/16是屬於保留的網段,VM正常是無法存取這個IP,今天就讓我們研究OpenStack是如何讓VM存取這個IP。


路由分析

查看instance裡的route, 發覺往metadata server169.254.169.254,是透過instance的eth0往同一個網段的172.16.100.2

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.100.1    0.0.0.0         UG    1002   0        0 eth0
169.254.169.254 172.16.100.2    255.255.255.255 UGH   1002   0        0 eth0
172.16.100.0    0.0.0.0         255.255.255.0   U     1002   0        0 eth0

檢查Openstack有 172.16.100.2 IP的port, 其實會對應至OpenStack的Network裡其中一個device owner為 network:distributed 的port.

$ openstack port list --network n1 --device-owner network:distributed

+--------+------+-------------------+----------------------------------------+--------+
| ID     | Name | MAC Address       | Fixed IP Addresses                     | Status |
+--------+------+-------------------+----------------------------------------+--------+
| 06ff4f |      | fa:16:3e:9d:cc:52 | ip_address='172.16.100.2', subnet_id=' | DOWN   |
|        |      |                   | 1dd3a923-6366-4754-9db2-1b65eb8391ee'  |        |
+--------+------+-------------------+----------------------------------------+--------+

還記得在Day-10: OpenStack-OVN-主機 三者間的關係裡曾經查過 tap76af9baf-90 和logical switch port 06ff4f是透過veth pair,將ovnmeta-76af9baf-9fa4-4631-8f1d-5610ef87a036 namespace綁定到logical switch port。其實就像下圖所表示的。

gh

最後再到ovnmeta-76af9baf-9fa4-4631-8f1d-5610ef87a036 namespace確認,172.16.100.2與169.254.169.254都在同一個interface上。因此,instance可以和位在Linux Namespace裡的metadata server溝通。

ip netns exec ovnmeta-76af9baf-9fa4-4631-8f1d-5610ef87a036 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tap53f016af-91@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:16:3e:9d:cc:52 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.16.100.2/24 brd 172.16.100.255 scope global tap53f016af-91
       valid_lft forever preferred_lft forever
    inet 169.254.169.254/32 brd 169.254.169.254 scope global tap53f016af-91
       valid_lft forever preferred_lft forever

連通性驗證

在instance嘗試透過metadata service取得instance 的hostname

$ curl http://169.254.169.254/2009-04-04/meta-data/local-hostname

vm-1.novalocal$

利用ovn-trace檢查instance和metadata server之間,會由06ff4f這個localport送出。

NETWORK_NAME=n1
VM_NAME=vm_1

lsw=neutron-`openstack network list  --name ${NETWORK_NAME} -f value -c ID`
lsp=`openstack port list --network ${NETWORK_NAME} --server ${VM_NAME} -f value -c ID`
meta_mac=`openstack port list --device-owner network:distributed --network ${NETWORK_NAME} -f value -c mac_address`
vm_mac=`openstack port list --network ${NETWORK_NAME} --server ${VM_NAME} -f value -c mac_address`

ovn-trace --minimal  ${lsw} \
"inport == \"${lsp}\"   && 
 eth.src == ${vm_mac}   && 
 eth.dst == ${meta_mac}"
output("06ff4f");

取得metadata的流程

到目前,我們只是說明了在instance是可以和與169.254.169.254連通。原因是169.254.169.254和172.16.100.2這個IP其實是屬於同一個namespace的IP. 透過localport的特性,在同一個主機上的VM,可以和同一主機上的ovnmeta namespace通訊。但是ovnmeta namespace本身並不直接回傳VM所要的metadata,對metadata 的請求,是經過三層的轉發,由nova提供相關的資訊給VM本身。整體流程像下圖一樣。

gh

Step 1:

如今天一開始看到的,在VM裡查看route資訊,可以看到要往metadata service的request,都會被轉送至172.16.100.2

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.100.1    0.0.0.0         UG    1002   0        0 eth0
169.254.169.254 172.16.100.2    255.255.255.255 UGH   1002   0        0 eth0
172.16.100.0    0.0.0.0         255.255.255.0   U     1002   0        0 eth0

Step 2:

進一步查看ovnmeta namespace裡有那些TCP的服務正在listen,可以看到haproxy正在使用80 port.

ip netns exec ovnmeta-76af9baf-9fa4-4631-8f1d-5610ef87a036 netstat -lntp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 169.254.169.254:80      0.0.0.0:*               LISTEN      5801/haproxy

找出haproxy process, 查看這個haproxy使用的設定檔內容。

ps aux |grep 5801

neutron     5801  0.0  0.0 140304  2652 ?        Ss   02:56   0:00 haproxy -f /var/lib/neutron/ovn-metadata-proxy/76af9baf-9fa4-4631-8f1d-5610ef87a036.conf

果然,這個Haproxy 綁定至169.254.169.254:80,而後端的server是一個本機檔案/var/lib/neutron/metadata_proxy,其實就是一個UNIX socket。

cat /var/lib/neutron/ovn-metadata-proxy/76af9baf-9fa4-4631-8f1d-5610ef87a036.conf

...
listen listener
    bind 169.254.169.254:80
    server metadata /var/lib/neutron/metadata_proxy
    http-request add-header X-OVN-Network-ID 76af9baf-9fa4-4631-8f1d-5610ef87a036
file /var/lib/neutron/metadata_proxy

/var/lib/neutron/metadata_proxy: socket

Step 3:

最後,用lsof發覺neutron-ovn-metadata-agent 這個process在使用這個socket。再進一步檢視其所使用的設定檔 /etc/neutron/neutron_ovn_metadata_agent.ini,裡面有指定nova_matadata server的IP. 因而能透過nova metadata 取得VM的metadata.

lsof /var/lib/neutron/metadata_proxy

COMMAND    PID    USER   FD   TYPE             DEVICE SIZE/OFF  NODE NAME
neutron-o 1600 neutron   11u  unix 0xffff89bdf24d9b00      0t0 36875 /var/lib/neutron/metadata_proxy type=STREAM
neutron-o 3220 neutron   11u  unix 0xffff89bdf24d9b00      0t0 36875 /var/lib/neutron/metadata_proxy type=STREAM
neutron-o 3220 neutron   17u  unix 0xffff89bdf24d9b00      0t0 36875 /var/lib/neutron/metadata_proxy type=STREAM
ps 1600
 PID TTY      STAT   TIME COMMAND
   1600 ?        Ss     0:05 neutron-ovn-metadata-agent (/usr/bin/python3 /usr/bin/neutron-ovn-metadata-agent --config-file /etc/neutron/neutron_ovn_metadata_agent.ini
cat /etc/neutron/neutron_ovn_metadata_agent.ini |grep nova

nova_metadata_host=192.168.121.230

Reference

  1. OpenStack Metadata API and OVN
  2. OpenStack虚拟机如何获取metadata

上一篇
Day-12: OpenStack Network如何用DHCP分配IP
下一篇
Day-14: OpenStack Router連接二個Network
系列文
在OpenStack Neutron的ovn-networking裡挖呀挖呀挖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言