OpenStack仮想マシンのメタデータを取得する方法

OpenStack仮想マシンのメタデータを取得する方法

1. OpenStackメタデータサービスについて

OpenStack 仮想マシンは、ネットワーク カード構成、ホスト名、初期化パスワード、キー構成などの初期化構成を cloud-init を通じて完了することがわかっています。 Cloud-init は仮想マシン内で実行されるプロセスです。データソースを通じて仮想マシンの構成情報 (メタデータ) を取得します。 Cloud-init はさまざまなデータソースを実装しており、異なるデータソースの実装原則はそれぞれ異なります。最も一般的に使用されるデータソースは主に次の 2 つです。

  • ConfigDriver: Nova はすべての構成情報をローカルの raw ファイルに書き込み、それを CDROM の形式で仮想マシンにマウントします。この時点で、仮想マシン内に /dev/sr0 (注: sr は scsi + rom の略) のような仮想デバイスが表示されます。 Cloud-init は、仮想マシンの構成情報を取得するために、/dev/sr0 ファイル情報を読み取るだけで済みます。
  • メタデータ: Nova は HTTP メタデータ サービスをローカルで開始します。仮想マシンは、関連する仮想マシン構成情報を取得するために、HTTP 経由でメタデータ サービスにアクセスするだけで済みます。

ConfigDriver の実装原理は比較的単純なので、この記事では紹介しません。ここでは、主に次の 2 つの問題を解決するメタデータに焦点を当てます。

  1. Nova メタデータ サービスは、ホスト (nova-api が配置されている制御ノード) 上で開始されます。仮想マシン内のテナントネットワークとホストの物理ネットワークが接続されていません。仮想マシンはどのようにして Nova メタデータ サービスにアクセスできますか?
  2. 質問 1 が解決されたと仮定すると、Nova メタデータ サービスはどの仮想マシンがリクエストを開始したかをどのように知るのでしょうか?

[[236018]]

2. メタデータサービスの構成

2.1 Novaの設定

Nova のメタデータ サービスの名前は nova-api-metadata ですが、このサービスは通常 nova-api サービスと統合されます。

  1. [デフォルト]
  2. enabled_apis = osapi_compute、メタデータ

さらに、仮想マシンは、Nova のメタデータ サービスにアクセスするために Neutron を転送する必要があります。理由は後ほど説明します。ここでは、nova.conf の設定にのみ注意する必要があります。

  1. [中性子]
  2. サービスメタデータプロキシ = true  

2.2 中性子の構成

前述のように、仮想マシンは Neutron を介して Nova のメタデータ サービスへのアクセスを転送する必要があります。 l3-agent または dhcp-agent を介して転送できます。選択は実際の状況によって異なります。

  • 転送が l3-agent を介して行われる場合、仮想マシンが配置されているネットワークをルーターに関連付ける必要があります。
  • dhcp-agent を介して転送を行う場合は、仮想マシンが配置されているネットワークで DHCP 機能を有効にする必要があります。

メタデータはデフォルトで l3-agent によって転送されます。ただし、実際の状況では、仮想マシンのネットワークでは DHCP 機能が有効になっていることがほとんどですが、必ずしもルーターが必要なわけではありません。したがって、私は dhcp-agent 経由で転送することを選択することを好みます。構成は次のとおりです。

  1. # /etc/neutron/dhcp_agent.ini [デフォルト]
  2. 強制メタデータ = true  
  3.  
  4. # /etc/neuron/l3_agent.ini [デフォルト]
  5. enable_metadata_proxy = false  

この記事の以下の内容はすべて上記の構成環境に基づいています。

3 OpenStack VMからNovaメタデータサービスにアクセスする方法

3.1 仮想マシンからのメタデータ サービスへのアクセス

cloud-init がメタデータ サービスにアクセスするための URL アドレスは http://169.254.169.254 です。この IP は非常に特別です。主にAWSのメタデータサービスアドレスを模倣します。ネットワークセグメントは 169.254.0.0/16 です。この IP セグメントは実際には予約済みです。つまり、IPv4 リンク ローカル アドレスです。プライベート IP (10.0.0.0/8、172.16.0.0/12、192.168.0.0/16) と同様であり、インターネット ルーティングには使用できません。通常、直接接続されたネットワークにのみ使用されます。オペレーティング システム (Windows) が IP アドレスを取得できない場合、169.254.0.0/16 ネットワーク セグメント内の IP アドレスとして自動的に構成されることがあります。

では、なぜ AWS は IP 169.254.169.254 を選択したのでしょうか?これは、リンク ローカル IP を選択すると、ユーザーの IP との競合を回避できるためです。 169.254.0.0/24 で他の IP ではなく 169.254.169.254 という IP が選ばれたのは、おそらく覚えやすくするためでしょう。

さらに、AWS には興味深いアドレスがいくつかあります。

  • 169.254.169.253: DNS サービス。
  • 169.254.169.123: NTP サービス。

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" : "daf​​32a70-42c9-4d30-8ec5-3a5d97582cff" "availability_zone" : "nova" "hostname" : "int32bit-test-1.novalocal" "launch_index" : 0、 "devices" : []、 "project_id" : "ca17d50f6ac049928cc2fb2217dab93b" "name" : "int32bit-test-1" }

上記の出力から、メタデータ サービスから仮想マシンの uuid、名前、プロジェクト ID、availability_zone、ホスト名などを取得したことがわかります。

仮想マシンは、アドレス 169.254.169.254 にアクセスしてメタデータ情報を取得するにはどうすればよいですか?まず、仮想マシンのルーティング テーブルを確認しましょう。

  1. # ルート -n
  2. カーネル IP ルーティングテーブル 
  3. 宛先ゲートウェイ Genmask フラグ メトリック参照 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 うわぁ 0 0 0 eth0

169.254.169.254 の次のホップは 10.0.0.66 であることがわかります。 IP 10.0.0.66 とは何ですか? Neutron のポート情報を確認します。

  1. # neutron ポートリスト -c ネットワーク ID -c デバイス所有者 -c MAC アドレス -c 固定 IP -f csv | grep 10.0.0.66
  2. "2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a" "ネットワーク:dhcp" "fa:16:3e:b3:e8:38" "[{u'サブネットID': u'6f046aae-2158-4882-a818-c56d81bc8074'、u'IPアドレス': u'10.0.0.66'}]"  

10.0.0.66 はネットワーク 2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a の DHCP アドレスとまったく同じであることがわかります。これはさらに次のように確認できます。

  1. # ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a ifconfig
  2. tap1332271e-0d: flags=4163<UP、ブロードキャスト、実行中、マルチキャスト> mtu 1450
  3. inet 10.0.0.66 ネットマスク 255.255.255.192 ブロードキャスト 10.0.0.127
  4. inet6 fe80::f816:3eff:feb3:e838 プレフィックス長 64 スコープID 0x20<リンク>
  5. ether fa:16:3e:b3:e8:38 txqueuelen 1000 (イーサネット)
  6. RXパケット 662 バイト 58001 (56.6 KiB)
  7. RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0
  8. TXパケット 410 バイト 55652 (54.3 KiB)
  9. TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0

このことから、OpenStack 仮想マシンが 169.254.169.254 にアクセスすると、仮想マシンが配置されているネットワークの DHCP アドレスにルーティングされることがわかります。 DHCP アドレスと仮想マシンの IP は相互運用可能である必要があり、これにより仮想マシンの内部からホスト マシンの外部への通信の問題が解決されます。 DHCP を Nova メタデータ サービスに転送するにはどうすればよいですか?次のセクションでは、この問題を解決する方法を紹介します。

3.2 メタデータ要求の最初の転送

前述のように、仮想マシンはメタデータ サービス アドレス 169.254.169.254 にアクセスし、それを DHCP アドレスに転送します。 Neutron の DHCP ポートが名前空間に配置されていることがわかります。仮想マシンが配置されているネットワークの名前空間を入力しましょう。

  1. ip netns exec qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a バッシュ

まず、名前空間のルーティングを確認します。

  1. # ルート -n
  2. カーネル IP ルーティングテーブル 
  3. 宛先ゲートウェイ Genmask フラグ メトリック参照 Iface の使用
  4. 0.0.0.0 10.0.0.126 0.0.0.0 UG 0 0 0 タップ1332271e-0d
  5. 10.0.0.64 0.0.0.0 255.255.255.192 U 0 0 0 タップ1332271e-0d
  6. 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 タップ1332271e-0d

ルーティング テーブルから、169.254.0.0/16 がネットワーク カード tap1332271e-0d から送信されていることがわかります。ネットワーク カードのアドレス情報を確認しましょう。

  1. # IPアドレス
  2. 18: tap1332271e-0d: <BROADCAST、MULTICAST、UP、LOWER_UP> mtu 1450 qdisc noqueue 状態 不明 qlen 1000
  3. リンク/イーサ 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 スコープグローバルtap1332271e-0d
  5. valid_lft 永久に preferred_lft 永久に
  6. inet 169.254.169.254/16 brd 169.254.255.255 スコープグローバルtap1332271e-0d
  7. valid_lft 永久に preferred_lft 永久に
  8. inet6 fe80::f816:3eff:feb3:e838/64 スコープ リンク
  9. valid_lft 永久に preferred_lft 永久に

169.254.169.254 は実際にはネットワーク カード tap1332271e-0d に割り当てられた仮想 IP であることがわかりました。仮想マシンがアドレス 169.254.169.254 にアクセスできるのは当然のことです。この記事のメタデータ転送構成は、dhcp-agent を通じて実装されていることに注意してください。 l3-agent の場合、169.254.169.254 は iptables を通じて転送されます。

curl http://169.254.169.254 にアクセスでき、このアドレスではポート 80 が開いている必要があることがわかります。

  1. # ネットスタット -lnpt
  2. プロトコル 受信Q 送信Qローカルアドレス外部アドレス 状態 PID/プログラム 
  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

出力から、DHCP サービス (ポート 53) が有効になっていることに加えて、環境がポート 80 を監視しており、プロセス pid が 11334/haproxy であることがわかります。

haproxy プロセスを見ると、それがプロキシとリクエストの転送を担当していることが推測できます。つまり、OpenStack 仮想マシンはまず、DHCP が配置されている名前空間の haproxy リスニング ポート 80 に要求を転送します。

問題が再び発生します。 DHCP が配置されている名前空間ネットワークはまだ Nova Metadata に接続されていません。では、haproxy はどのようにしてリクエストを Nova メタデータ サービスに転送するのでしょうか?次のセクションで紹介します。

3.3 メタデータ要求の2回目の転送

先ほど、OpenStack 仮想マシンが http://169.254.169.254 にアクセスすると、DHCP が配置されている名前空間で haproxy がリッスンしているポート 80 に転送されることを紹介しました。ただし、Nova メタデータ サービスはまだ名前空間内でアクセスできません。

解決策を検討するために、まず haproxy プロセス情報を見てみましょう。

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

2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a.conf 構成ファイルの内容は次のとおりです。

  1. 聞く リスナー
  2. 0.0.0.0:80 をバインド
  3. サーバーメタデータ /opt/stack/data/neutron/metadata_proxy
  4. http-リクエストにヘッダー X-Neutron-ネットワーク ID 2c4b658c-f2a0-4a17-9ad2-c07e45e13a8aを追加します

haproxy にバインドされているポートは 80 であり、バックエンド アドレスはファイル /opt/stack/data/neutron/metadata_proxy であることがわかりました。バックエンドは IP/TCP アドレスではなく、UNIX ソケット ファイルである必要があります。

  1. # ll /opt/stack/data/neutron/metadata_proxy
  2. srw -r --r-- 1 スタック スタック 0 7月1日 13:30 /opt/stack/data/neutron/metadata_proxy  

したがって、haproxy プロセスは OpenStack 仮想マシンのメタデータ要求をローカル ソケット ファイルに転送すると結論付けられます。

UNIX ドメイン ソケットはソケット アーキテクチャに基づいて開発され、同じホスト上のプロセス間通信 (IPC) に使用されます。アプリケーション層データをあるプロセスから別のプロセスにコピーするためにネットワーク プロトコル スタックを経由する必要がないため、Unix パイプラインに多少似ています。

ここで再び質問です:

  • haproxy 設定から、リスニング アドレスが 0.0.0.0:80 であることがわかります。複数のネットワークが同時にポート 80 をリッスンすると、ポートの競合は発生しませんか?
  • ソケットは、同じホスト上のプロセス間通信にのみ使用できます。 Nova メタデータ サービスと Neutron dhcp-agent が同じホスト上にない場合、当然通信できません。

最初の問題は実は以前に解決されていました。 HAProxy は、仮想マシンが配置されているネットワークの DHCP 名前空間で起動されます。確認できること:

  1. # lsof -i :80
  2. コマンド PIDユーザーFD タイプ デバイスサイズ/オフノード 
  3. haproxy 11334 スタック 4u IPv4 65729753 0t0 TCP *:http (LISTEN)
  4. # IPネット識別11334
  5. qdhcp-2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a

2 番目の質問に関しては、別の転送レイヤーが必要であることは明らかです。詳細については次のセクションを参照してください。

また、新しいバージョンの OpenStack では転送に haproxy プロキシを直接使用しますが、一部の古いバージョンでは転送に neutron-ns-metadata-proxy プロセスを使用することにも注意してください。実装コードは neutron/agent/metadata/namespace_proxy.py にあります。

  1. def _proxy_request(self, リモートアドレス, メソッド, パス情報,
  2. クエリ文字列、本文):
  3. ヘッダー = {
  4. 'X-Forwarded-For' : リモートアドレス、
  5. }
  6.  
  7. self.router_idの場合:
  8. ヘッダー[ 'X-Neutron-Router-ID' ] = self.router_id
  9. それ以外
  10. ヘッダー[ 'X-Neutron-Network-ID' ] = self.network_id
  11.  
  12. url = urlparse.urlunsplit((
  13. 'http'
  14. '169.254.169.254'
  15. パス情報、
  16. クエリ文字列、
  17. '' ))
  18.  
  19. h = httplib2.Http()
  20. 応答、コンテンツ = h.request(
  21. URL、
  22. メソッド=メソッド、
  23. ヘッダー=ヘッダー、
  24. 本文=本文、
  25. 接続タイプ=agent_utils.UnixDomainHTTPConnection)

リクエスト URL 169.254.169.254 について質問があるかもしれません。自分自身に転送するにはどうすればいいでしょうか?これは UNIX ドメイン ソケット要求であるためです。実際、この URL は単なるパラメータ プレースホルダーです。何を記入しても構いません。このリクエストは次のものと同等です:

  1. curl -H "X-Neutron ネットワーク ID: ${network_uuid}" \
  2. -H "X-Forwarded-For: ${request_ip}" \
  3. -X ゲット \
  4. --unix /var/lib/neutron/metadata_proxy \  
  5. http://169.254.169.254

3.4 メタデータ要求が3回目に転送される

前述したように、haproxy はメタデータ要求をローカル ソケット ファイルに転送するので、どのプロセスが /opt/stack/data/neutron/metadata_proxysocket ファイルをリッスンしているのでしょうか? lsof で確認します:

  1. # lsof /opt/stack/data/neutron/metadata_proxy
  2. コマンド PIDユーザーFD タイプ デバイスサイズ/オフノード 
  3. neutron-m 11085 スタック 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
  4. neutron-m 11108 スタック 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
  5. neutron-m 11109 スタック 3u unix 0xffff8801c8711c00 0t0 65723197 /opt/stack/data/neutron/metadata_proxy
  6. # cat /proc/11085/cmdline | '\0' を  ' '  
  7. /usr/bin/python /usr/bin/neutron-metadata-agent --config-file /etc/neutron/neutron.conf  

neutron-metadata-agent がこのソケット ファイルをリッスンしていることがわかります。これは、haproxy がソケット ファイルを介してメタデータ サービスを neutron-metadata-agent サービスに転送することと同じです。

  1. def run(self):
  2. サーバー = agent_utils.UnixDomainWSGIServer( 'neutron-metadata-agent' )
  3. server.start(MetadataProxyHandler(self.conf),
  4. self.conf.metadata_proxy_socket、
  5. ワーカー=self.conf.metadata_workers、
  6. バックログ=self.conf.metadata_backlog、
  7. モード=self._get_socket_mode())
  8. 自己._init_state_reporting()
  9. サーバー.wait()

さらに、neutron-metadata-agent が /opt/stack/data/neutron/metadata_proxysocket ファイルをリッスンしていることが検証されます。

neutron-metadata-agent は制御ノード上のプロセスであるため、Nova Metadata サービスに確実に接続されます。 OpenStack 仮想マシンが Nova メタデータ サービスにアクセスする方法の問題は基本的に解決されています。

  1. curl 169.254.169.254 -> haproxy (ポート 80) -> UNIX ソケット ファイル -> neutron-metadata-agent -> nova-api-metadata

つまり、合計 3 回の転送が必要になります。

しかし、Nova メタデータ サービスはどの仮想マシンがリクエストを送信したかをどうやって知るのでしょうか?つまり、仮想マシンの uuid を取得する方法については次の章で紹介します。

4 メタデータ サービスはどのようにして仮想マシンの情報を取得しますか?

前の章では、OpenStack 仮想マシンが 169.254.169.254 を介して Nova メタデータ サービスに到達する方法について説明しました。サービスに到達した後、どの仮想マシンがメッセージを送信したかをどのように判断しますか?

OpenStack は、neutron-metadata-agent を通じて仮想マシンの uuid を取得します。同じ Neutron ネットワーク内で、複数のサブネットが存在する場合でも、IP の重複は許可されない、つまり、Neutron ポート情報は IP アドレスによって一意に決定できることがわかっています。 neutron ポートは、コンシューマー情報を識別するために device_id を設定します。仮想マシンの場合、これは仮想マシンの UUID です。

したがって、neutron-metadata-agent は、ネットワーク UUID と仮想マシンの IP を通じて仮想マシンの UUID を取得できます。

haproxy 構成ファイルに構成項目があることをまだ覚えていますか?

  1. http-request に-header X-Neutron-Network-ID 2c4b658c-f2a0-4a17-9ad2-c07e45e13a8aを追加します

つまり、haproxy は転送前にリクエスト ヘッダーにネットワーク ID を追加し、HTTP ヘッダー X-Forwarded-For を通じて IP を取得できます。そのため、neutron-metadata-agent には仮想マシンの uuid とプロジェクト ID (テナント ID) を取得するための条件があります。 neutron-metadata-agent の実装を表示して、仮想マシンの uuid とプロジェクト ID を取得できます。コードは neutron/agent/metadata/agent.py にあります:

  1. def _get_instance_and_tenant_id(self, req):
  2. リモートアドレス = req.headers.get( 'X-Forwarded-For' )
  3. network_id = req.headers.get( 'X-Neutron-ネットワークID' )
  4. router_id = req.headers.get( 'X-Neutron-ルーターID' )
  5.  
  6. ポート = self._get_ports(リモートアドレス、ネットワークID、ルーターID)
  7. len(ポート) == 1の場合:
  8. ポート[0][ 'device_id' ]、ポート[0][ 'tenant_id' ]を返します
  9. None、Noneを返す

誰かがメタデータ要求を偽造して仮想マシンのメタデータ情報を取得できる場合、それは明らかに安全ではないため、Nova メタデータ サービスに転送する前に、秘密を送信する必要があります。

  1. _sign_instance_id(自分自身、インスタンスID):
  2. シークレット = self.conf.metadata_proxy_shared_secret
  3. シークレット = encodeutils.to_utf8(シークレット)
  4. インスタンスID = encodeutils.to_utf8(インスタンスID)
  5. hmac.new(secret, instance_id, hashlib.sha256).hexdigest()を返します

metadata_proxy_shared_secret は管理者が設定する必要があり、その後、仮想マシンの uuid と組み合わせてキーとしてランダムな文字列を生成します。

最後に、neutron-metadata-agent は仮想マシン情報をヘッダーに配置し、Nova Metadata サービスに送信されるヘッダー情報は次のようになります。

  1. ヘッダー = {
  2. 'X-Forwarded-For' : req.headers.get( 'X-Forwarded-For' ),
  3. 'X-インスタンスID' : インスタンスID、
  4. 'X-テナントID' : テナントID、
  5. 'XインスタンスID署名' : self._sign_instance_id(instance_id)
  6. }

この時点で、Nova Metadata は仮想マシンの uuid を通じてメタデータ情報を照会できます。コードは nova/api/metadata/base.py にあります:

  1. def get_metadata_by_instance_id(instance_id, address, ctxt=なし):
  2. ctxt = ctxtまたはcontext.get_admin_context()
  3. attrs = [ 'ec2_ids' , 'flavor' , 'info_cache' ,
  4. 'メタデータ' 'システムメタデータ'
  5. 'security_groups' 'keypairs'
  6. ['デバイスメタデータ' ]
  7. 試す:
  8. im = オブジェクト.InstanceMapping.get_by_instance_uuid(ctxt、instance_id)
  9. 例外を除く。InstanceMappingNotFound:
  10. LOG.warning( '%(uuid)s のインスタンス マッピングが見つかりません。'  
  11. 'セルのセットアップが不完全です' 、{ 'uuid' :instance_id})
  12. インスタンス = objects.Instance.get_by_uuid(ctxt, インスタンスID,
  13. 予想される属性=属性)
  14. InstanceMetadata(インスタンス、アドレス)を返す
  15.  
  16. context.target_cell(ctxt, im.cell_mapping)cctxtとして:
  17. インスタンス = objects.Instance.get_by_uuid(cctxt, インスタンスID,
  18. 予想される属性=属性)
  19. InstanceMetadata(インスタンス、アドレス)を返す

5 仮想マシンの外部から仮想マシンのメタデータを取得する方法

前のセクションでは、OpenStack 仮想マシンが Nova メタデータ サービスからメタデータを取得する方法について説明しました。送信されたデータが正しいかどうかを確認するために、仮想マシンのメタデータ情報をデバッグする必要がある場合がありますが、面倒すぎるため、仮想マシンにアクセスしてデバッグしたくない場合があります。 nova-api-metadata サービスを直接呼び出して仮想マシンの情報を取得する方法はありますか?

上記で紹介した原則に従って、実装する 2 つのスクリプトを作成しました。

*** シークレットを生成するには、Python スクリプト sign_instance.py を使用します。

  1. サインインスタンス.py
  2.  
  3. 6を輸入
  4. インポートシステム
  5. hmac をインポートする
  6. ハッシュライブラリをインポートする
  7.  
  8. sign_instance_id を定義します(instance_id、シークレット = '' ):
  9. isinstance(secret, six.text_type):の場合
  10. secret = secret.encode( 'utf-8' )
  11. インスタンスIDがinstance_id、テキストタイプがsixの場合:
  12. インスタンスID = インスタンスID.encode( 'utf-8' )
  13. hmac.new(secret, instance_id, hashlib.sha256).hexdigest()を返します
  14. 印刷(sign_instance_id(sys.argv[1]))

2 番目の bash スクリプト get_metadata.py は、仮想マシンのメタデータの取得を実装します。

  1. #!/bin/bash
  2. メタデータサーバー=http://192.168.1.16:8775
  3. メタデータURL = $metadata_server/openstack/latest
  4. インスタンスID=$1
  5. データ=$2
  6. [[ -z $instance_id ]]の場合;次に「使用方法: $0 <instance_id>」をエコーし​​ます 
  7. 出口1
  8. fi tenant_id=$(nova s​​how $instance_id | awk '/tenant_id/{print $4}' )
  9. sign_instance_id=$(python sign_instance.py $instance_id)
  10. curl -sL -H "XインスタンスID:$instance_id" -H "XインスタンスID署名:$sign_instance_id" -H "XテナントID:$tenant_id" $metadata_url/$data

metadata_server は Nova メタデータ サービスのアドレスです。

使用方法は次のとおりです。

  1. # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff
  2. メタデータ
  3. パスワード 
  4. ベンダーデータ.json
  5. ネットワークデータ
  6. # ./get_metadata.sh daf32a70-42c9-4d30-8ec5-3a5d97582cff ネットワークデータ.json | python -m json.tool
  7. {
  8. 「リンク」 : [
  9. {
  10. "イーサネットMACアドレス" : "fa:16:3e:e8:81:9b" ,
  11. 「id」 : 「tap28468932-9e」
  12. "mtu" : 1450,
  13. 「タイプ」 : 「ovs」
  14. "vif_id" : "28468932-9ea0-43d0-b699-ba19bf65cae3"  
  15. }
  16. ]、
  17. 「ネットワーク」 : [
  18. {
  19. 「id」 : 「ネットワーク0」
  20. 「リンク」 : 「tap28468932-9e」
  21. "ネットワークID" : "2c4b658c-f2a0-4a17-9ad2-c07e45e13a8a" ,
  22. 「タイプ」 : 「ipv4_dhcp」  
  23. }
  24. ]、
  25. 「サービス」 : []
  26. }

5 結論

***ワークフロー図でまとめると次のようになります:

OpenStack メタデータ ワークフロー

ソースコード:

  1. タイトル OpenStack メタデータ ワークフロー
  2.   
  3. 参加者VM
  4. 参加者の代理
  5. 参加者 UNIX ソケット
  6. 参加者neutron-メタデータ-エージェント
  7. 参加者 nova-api-メタデータ
  8.   
  9. vm -> haproxy: curl 169.254.169.254 (*** 転送)
  10. haproxyに関する注意:ヘッダーX-Neutron-Network-IDを追加
  11. haproxy -> UNIXソケット: 2番目の転送
  12. UNIX ソケット -> neutron-metadata-agent: 2 回目の転送
  13. neutron-metadata-agent に関するメモ: get_instance_and_tenant_id
  14. neutron-metadata-agent に関するメモ: sign_instance_id
  15. neutron-metadata-agent -> nova-api-metadata: 3番目の転送
  16. nova-api-metadata に関するメモ: get_metadata_by_instance_id
  17. nova-api-metadata -> neutron-metadata-agent: メタデータ
  18. neutron-metadata-agent -> UNIX ソケット: メタデータ
  19. UNIX ソケット -> haproxy: メタデータ
  20. haproxy -> vm:メタデータ

【この記事は51CTOコラムニスト「Fu Guangping」によるオリジナル記事です。転載が必要な場合は51CTOまでご連絡ください]

この著者の他の記事を読むにはここをクリックしてください

<<:  仮想化を選択する理由は何ですか?ネットワーク管理業務にどのような効果がありますか?各メーカーの仮想化技術を比較!

>>:  清華紫光集団は、12のカテゴリーで267のクラウドサービス製品を含む清華紫光集団パブリッククラウドの商用試験を開始したと発表した。

推薦する

インターネット後半では、ARM クラウドが新たな活路となるでしょうか?

2018年を振り返ると、寒くて忘れられない年でした。過去 20 年間で、インターネット従事者をこれほ...

インターネット大手が銀行業に参入:テンセントとアリババは最初のライセンス取得を逃す可能性も

民間資本が銀行業界に参入できるという警鐘が鳴らされるやいなや、アリババ、テンセント、蘇寧などのネット...

SEO ウェブマスターに必須のスキル。あなたはいくつ知っていますか?

最近、Baidu のアルゴリズムが継続的にアップグレードされるにつれて、SEO 作業者のスキルも大幅...

Weiboのプロモーションメカニズムを分析し、プロモーションコンセプトを人々に啓蒙する

今では、私の周りの誰もが自分のWeiboを持っています。 Weiboはあらゆる人々の空間に浸透しまし...

垂直採用は伝統的な採用ネットワークを救い、精密採用が発展のトレンドになる

最近、多くの伝統的な求人サイトが営業損失に直面しています。Zhaopin.comや51job.com...

ウェブサイトは情報システムセキュリティレベル保護期限修正通知ソリューションを受け取りました

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています2018年...

企業ウェブサイトのユーザーエクスペリエンスに影響を与える要因: 400 の電話番号

企業ウェブサイトが百度プロモーションを行うにせよ、SEOを行うにせよ、最終的な目標は受注を獲得するこ...

PinduoduoはTaobaoトラフィックの上流になりつつある

私のような老人にとって、 Pinduoduo を理解するのはまだ少し難しいですが、業界では、Alib...

金融クラウド市場の優位性はまだ形成されていない

現在、ビッグデータの急速な発展は、世界中のさまざまな産業の情報化と高度化を推進しています。クラウドコ...

取引方法の合理化によりウェブサイトをより高いレベルに導く

インターネットの拡大に​​伴い、今年のタオバオ11フェスティバルも取引高の記録を更新しました。しかし...

5G時代のクラウドコンピューティングは企業の情報技術革新を支援

2019年10月31日、工業情報化部と3大通信事業者は5Gサービスの開始を正式に発表し、中国は正式に...

量的変化から質的変化へ:新しいブログサイトは贅沢なダブルフライトを実現

本日の Google グローバル アップデートは、すべてのウェブマスターの間で議論の的となることは間...

Baiduの検索障害が復旧しました。コードは宇宙カプセルに眠っていました

さらに読む: Baidu の PC 検索結果が異常、モバイル検索の調整による可能性あり百度の検索エン...

プロトタイプなしでブランドマーケティングをしたいですか?冗談はやめてください!

ブランドとしてユーザーの心を掴むには、ユニークで際立ったイメージが必要です。歴史を振り返ると、成功し...