Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OVSとLinuxネットワークで実現するHVの透過的プロキシとセキュアなVPCネットワーク

 OVSとLinuxネットワークで実現するHVの透過的プロキシとセキュアなVPCネットワーク

プライベートクラウド新規リージョンのIaaS基盤におけるVPCネットワークにおいて、高いテナントネットワーク分離性とVMからDHCP/metadataへの到達性をいかに両立するかが課題となりました。この課題に対してOVSやLinuxネットワーク機能を活用し、それらのVMの通信をHVで透過的に中継する仕組みを構築しました。ネットワーク分離性を維持しながら基盤サービスへの到達性を確保するOVS Flow設計や、HV上のパケット処理の知見を、OpenStackやIaaS基盤の運用者向けに共有します。

Avatar for Tomofumi Kondo

Tomofumi Kondo

July 26, 2026

More Decks by Tomofumi Kondo

Other Decks in Programming

Transcript

  1. 自己紹介 近藤 智文 • サイバーエージェント24新卒 • プライベートクラウド IaaS 基盤の 開発・運用をやってます

    • OpenStack/OVS/Kubernetes /Go/Python https://github.com/TOMOFUMI-KONDO/ https://x.com/tomokon_0314
  2. プライベートクラウドの概要 社内ユーザに以下の機能を提供 • IaaS (OpenStackベース) • PaaS/SaaS ◦ Kubernetes as

    a Service ◦ Serverless Computing ◦ ML Platform ◦ GitHub Actions Self-Hosted Runner ◦ DB/Storage, etc.
  3. VM が undercloud のサービスにアクセスできない Tenant A HV 😔 undercloud VM

    Metadata DHCP LDAP DNS NTP VM Tenant B 一応 HV の管理用 NW は undercloud 疎通がある
  4. VM が undercloud のサービスにアクセスできない Tenant A HV VM 😔 undercloud

    Metadata が取れないので cloud-init が動かない! DHCP DNS NTP VM Tenant B 一応 HV の管理用 NW は undercloud 疎通がある Metadata LDAP
  5. VM が undercloud のサービスにアクセスできない Tenant A HV 😔 undercloud というかそもそも

    DHCP が 返ってこないのでアドレスが 振られない😇 VM DHCP DNS NTP VM Tenant B 一応 HV の管理用 NW は undercloud 疎通がある Metadata LDAP
  6. Neutron の DHCP/Metadata 構成 Controller Node metadata agent nova metadata

    api dhcp agent テナントごとにプロセス作成 metadata proxy (tenant A) metadata proxy (tenant B) qemu (tenant A) (Neutron: OpenStack のネットワークサービス) dnsmasq (tenant A) qemu (tenant B) dnsmasq (tenant B)
  7. DHCP Neutron の DHCP/Metadata 構成 Controller Node metadata agent nova

    metadata api テナントごとにプロセス作成 metadata proxy (tenant A) qemu (tenant A) dhcp agent metadata proxy (tenant B) dnsmasq (tenant A) qemu (tenant B) dnsmasq (tenant B)
  8. Metadata Neutron の DHCP/Metadata 構成 Controller Node metadata agent nova

    metadata api テナントごとにプロセス作成 metadata proxy (tenant A) qemu (tenant A) dhcp agent metadata proxy (tenant B) dnsmasq (tenant A) qemu (tenant B) dnsmasq (tenant B)
  9. Metadata Neutron ではどうしているのか (Metadata) Controller Node metadata agent nova metadata

    api dhcp agent テナントごとにプロセス作成 Control Plane が 全テナントに疎通する 必要がある! metadata proxy (tenant A) qemu (tenant A) metadata proxy (tenant B) dnsmasq (tenant A) qemu (tenant B) dnsmasq (tenant B)
  10. Neutron 標準構成の課題 • agent を集約すると Control Plane が全テナントに L2 接続する必要がある

    ❌ ◦ 別途 Network Node を用意したりするのは運用 コスト的に厳しい • DHCP/Metadata 以外の通信に対応できない ❌ ◦ DNS, NTP, LDAP, etc. 😔
  11. 我々には OVS がある Open vSwitch • Linux で動作する仮想スイッチ OSS •

    Neutron のデータプレーンとして既に導入済みだった • 通過するパケットに対して任意のフォワーディングや 中身の書き換えが可能 👏
  12. DHCP OVS 詳細(行き) HV tap ovs bridge VM dest hwaddr

    FF:FF:FF:FF:FF:FF src hwaddr <VM hwaddr> dest ipaddr 255.255.255.255 DHCP Discover/Request (UDP) src ipaddr 0.0.0.0 dest port 67 src port 68 dhcp gw dhcp api ovs bond Tenant network DHCP Message
  13. DHCP OVS 詳細(行き) HV tap in_port=<VM port>, udp,udp_src=68,udp_dst=67, nw_dst=255.255.255.255, dest

    hwaddr FF:FF:FF:FF:FF:FF ovs bond ovs bridge src hwaddr <VM hwaddr> dest ipaddr 255.255.255.255 DHCP Discover/Request (UDP) src ipaddr 0.0.0.0 dhcp api DHCP のみ tap へ曲げる actions=output:<dhcp-gw tap> VM dhcp gw dest port 67 src port 68 DHCP Message Tenant network
  14. DHCP OVS 詳細(行き) HV tap dhcp gw dhcp api VM

    hwaddr と VLAN ID を抽出して送信 VM ovs bridge ovs bond Tenant network
  15. DHCP OVS 詳細(帰り) HV tap dhcp gw dhcp api VM

    に割り当てる ipaddr を返却 VM ovs bridge ovs bond Tenant network
  16. DHCP OVS 詳細(帰り) HV tap ovs bridge VM dest hwaddr

    <VM hwaddr> src hwaddr <tap hwaddr> DHCP Offer/Ack (UDP) dest ipaddr <VM ipaddr> src ipaddr x.x.x.2 dest port 68 src port 67 dhcp gw dhcp api ovs bond Tenant network DHCP Message
  17. DHCP OVS 詳細(帰り) HV tap in_port=<dhcp-gw tap>, udp,udp_src=67,udp_dst=68, dhcp gw

    dhcp api ovs bond Tenant network actions=output:<VM port> ovs bridge VM dest hwaddr <VM hwaddr> src hwaddr <tap hwaddr> DHCP Offer/Ack (UDP) dest ipaddr <VM ipaddr> src ipaddr x.x.x.2 dest port 68 src port 67 DHCP Message
  18. Metadata OVS 詳細(ARP / 行き) HV veth $ ip route

    show metadata gw metadata proxy ovs bond Tenant network 169.254.169.254 dev enp1s0 proto dhcp scope link ovs bridge VM vlan id <tenant vlan_id> arp op ARP Request 1 sender hwaddr <VM hwaddr> veth sender ipaddr <VM ipaddr> target hwaddr 00:00:00:00:00:00 target ipaddr 169.254.169.254
  19. Metadata OVS 詳細(ARP / 行き) HV veth table=0,in_port=<VM port>, vlan_tci=0x1000/0x1000,

    arp,arp_tpa=169.254.169.254,arp_op=1, actions=resubmit(,20) ovs bridge VM vlan id <tenant vlan_id> arp op ARP Request 1 sender hwaddr <VM hwaddr> metadata proxy 169.254.169.254 当ての ARP Request だけ曲げる veth sender ipaddr <VM ipaddr> metadata gw target hwaddr 00:00:00:00:00:00 ovs bond target ipaddr 169.254.169.254 Tenant network
  20. Metadata OVS 詳細(ARP / 行き) HV table=20, veth arp,arp_tpa=169.254.169.254,arp_op=1, actions=

    move:vlan_vid[0..11]->NXM_NX_REG2[0..11], <Learn ARP>, resubmit(,25) ovs bridge VM vlan id <tenant vlan_id> arp op ARP Request 1 sender hwaddr <VM hwaddr> metadata proxy 帰りのパケット用に 一時的なフローを作成 veth sender ipaddr <VM ipaddr> metadata gw target hwaddr 00:00:00:00:00:00 ovs bond target ipaddr 169.254.169.254 Tenant network
  21. Metadata OVS 詳細(ARP / 行き) <Learn ARP> 詳細 HV #learn(

    veth table=15,idle_timeout=10,eth_type=0x0806, arp_tpa=NXM_OF_ARP_SPA[],arp_op=2, load:NXM_NX_REG2[0..11]->vlan_vid[0..11], output:in_port), ... ovs bridge VM vlan id <tenant vlan_id> arp op ARP Request 1 sender hwaddr <VM hwaddr> metadata proxy 帰りのパケット用に 一時的なフローを作成 veth sender ipaddr <VM ipaddr> metadata gw target hwaddr 00:00:00:00:00:00 ovs bond target ipaddr 169.254.169.254 Tenant network
  22. Metadata OVS 詳細(ARP / 行き) HV veth table=25, vlan_tci=0x1000/0x1000,actions=pop_vlan, output:<metadata-gw

    veth> ovs bridge VM arp op 1 sender hwaddr <VM hwaddr> ARP Request sender ipaddr <VM ipaddr> metadata gw metadata proxy Tenant network の VLAN を除去して metadata-gw へ veth target hwaddr 00:00:00:00:00:00 ovs bond target ipaddr 169.254.169.254 Tenant network
  23. Metadata OVS 詳細(ARP / 帰り) HV veth ovs bridge VM

    arp op 2 sender hwaddr <metadata-gw veth hwaddr> ARP Reply sender ipaddr 169.254.169.254 veth target hwaddr <VM hwaddr> target ipaddr <VM ipaddr> metadata gw metadata proxy ovs bond Tenant network
  24. Metadata OVS 詳細(ARP / 帰り) HV veth table=0,in_port=<metadata-gw veth>, arp,arp_spa=169.254.169.254,arp_op=2,

    actions=resubmit(,10) ovs bridge VM arp op 2 sender hwaddr <metadata-gw veth hwaddr> ARP Reply sender ipaddr 169.254.169.254 veth target hwaddr <VM hwaddr> target ipaddr <VM ipaddr> metadata gw metadata proxy ovs bond Tenant network
  25. Metadata OVS 詳細(ARP / 帰り) HV veth table=10, actions=push_vlan:0x8100,resubmit(,15) VM

    vlan id ARP Reply VLAN Header を復元 arp op 2 sender hwaddr <metadata-gw veth hwaddr> ovs bridge veth sender ipaddr 169.254.169.254 target hwaddr <VM hwaddr> metadata gw metadata proxy ovs bond Tenant network target ipaddr <VM ipaddr>
  26. Metadata OVS 詳細(ARP / 帰り) HV veth table=15,idle_timeout=10,eth_type=0x0806, arp_tpa=<VM ipaddr>,arp_op=2,

    load:<tenant vlan_id>->vlan_vid[0..11], output:<VM port> VM 先ほど学習したフローで VLAN ID を復元 vlan id <tenant vlan_id> ARP Reply arp op 2 sender hwaddr <metadata-gw veth hwaddr> ovs bridge veth sender ipaddr 169.254.169.254 target hwaddr <VM hwaddr> metadata gw metadata proxy ovs bond Tenant network target ipaddr <VM ipaddr>
  27. Metadata OVS 詳細(HTTP / 行き) HV veth $ ip route

    show metadata gw metadata proxy ovs bond Tenant network 169.254.169.254 dev enp1s0 proto dhcp scope link ovs bridge VM vlan id <tenant vlan_id> dest ipaddr 169.254.169.254 HTTP Request src ipaddr <VM ipaddr> veth dest port 80 src port * HTTP Body
  28. Metadata OVS 詳細(HTTP / 行き) HV veth table=0,in_port=<VM port>, vlan_tci=0x1000/0x1000,

    tcp,nw_dst=169.254.169.254,tcp_dst=80, actions=resubmit(,20) ovs bridge VM vlan id <tenant vlan_id> dest ipaddr 169.254.169.254 HTTP Request src ipaddr <VM ipaddr> metadata proxy 169.254.169.254 当ての HTTP Request だけ曲げる veth dest port 80 metadata gw ovs bond src port * HTTP Body Tenant network
  29. Metadata OVS 詳細(HTTP / 行き) HV table=20, veth tcp,nw_dst=169.254.169.254,tcp_dst=80, actions=

    move:vlan_vid[0..11]->NXM_NX_REG2[0..11], <Learn TCP>, resubmit(,25) ovs bridge VM vlan id <tenant vlan_id> dest ipaddr 169.254.169.254 HTTP Request src ipaddr <VM ipaddr> metadata proxy 帰りのパケット用に 一時的なフローを作成 veth dest port 80 metadata gw ovs bond src port * HTTP Body Tenant network
  30. Metadata OVS 詳細(HTTP / 行き) HV # <Learn TCP> 詳細

    learn( table=15,idle_timeout=10,eth_type=0x0800, ip_dst=NXM_OF_IP_SRC[],ip_proto=6, tcp_dst=NXM_OF_TCP_SRC[], load:NXM_NX_REG2[0..11]->vlan_vid[0..11], output:in_port), ... ovs bridge VM vlan id <tenant vlan_id> dest ipaddr 169.254.169.254 HTTP Request src ipaddr <VM ipaddr> veth metadata proxy 帰りのパケット用に 一時的なフローを作成 veth dest port 80 metadata gw ovs bond src port * HTTP Body Tenant network
  31. Metadata OVS 詳細(HTTP / 行き) HV veth table=25, vlan_tci=0x1000/0x1000,actions=pop_vlan, output:<metadata-gw

    veth> ovs bridge VM dest ipaddr 169.254.169.254 src ipaddr <VM ipaddr> HTTP Request dest port 80 src port * metadata gw metadata proxy Tenant network の VLAN を除去して metadata-gw へ veth HTTP Body ovs bond Tenant network
  32. Metadata OVS 詳細(HTTP / 行き) HV veth metadata gw metadata

    proxy VM ipaddr と Request Body を抽出して送信 VM ovs bridge veth ovs bond Tenant network
  33. Metadata OVS 詳細(HTTP / 帰り) HV veth metadata gw metadata

    proxy VM の Metadata を返却 VM ovs bridge veth ovs bond Tenant network
  34. Metadata OVS 詳細(HTTP / 帰り) HV $ ip rule show

    table metadata veth 30000: from 169.254.169.254 lookup metadata proto static ovs bridge dest ipaddr <VM ipaddr> src ipaddr 169.254.169.254 HTTP Response dest port * src port 80 metadata proxy Linux の Source Routing により metadata-gw からの帰りのパケット を veth に曲げる $ ip route show table metadata default dev veth-meta-br proto static scope link VM metadata gw veth HTTP Body ovs bond Tenant network
  35. Metadata OVS 詳細(HTTP / 帰り) HV veth table=0,in_port=<metadata-gw veth>, tcp,ip_src=169.254.169.254,tcp_src=80,

    actions=resubmit(,10) ovs bridge VM dest ipaddr <VM ipaddr> src ipaddr 169.254.169.254 HTTP Response dest port * src port 80 veth HTTP Body metadata gw metadata proxy ovs bond Tenant network
  36. Metadata OVS 詳細(HTTP / 帰り) HV veth table=10, actions=push_vlan:0x8100,resubmit(,15) VM

    vlan id VLAN Header を復元 dest ipaddr <VM ipaddr> HTTP Response src ipaddr 169.254.169.254 ovs bridge veth dest port * src port 80 HTTP Body metadata gw metadata proxy ovs bond Tenant network
  37. sMetadata OVS 詳細(HTTP / 帰り) HV veth table=15,idle_timeout=10,eth_type=0x0800, ip_dst=<VM ipaddr>,ip_proto=6,

    tcp_dst=<VM ephemeral port>, load:<tenant vlan_id>->vlan_vid[0..11], output:<VM port> VM vlan id 先ほど学習したフローで VLAN ID を復元 <tenant vlan_id> dest ipaddr <VM ipaddr> HTTP Response src ipaddr 169.254.169.254 ovs bridge veth dest port * src port 80 HTTP Body metadata gw metadata proxy ovs bond Tenant network
  38. DNS / NTP / LDAP への横展開 HV veth 名前解決 VM

    ovs bridge DNS サーバ unbound 名前解決 veth veth veth veth NTP サーバ chronyd 時刻同期 時刻同期 veth haproxy プロキシ LDAP サーバ
  39. 設計振り返り • HV 上で通信を折り返すことで、テナント分離を崩さず VM からの undercloud 疎通を実現 • DHCP

    / Metadata / DNS / NTP / LDAP 等の様々な サービスを HV 上のプロキシで適切に処理 • OVS Flow Rule を用いて対象の通信だけを捕捉し、 VLAN 情報を保持・復元して返りの通信も可能に • Linux Source Routing で帰りの通信だけを OVS データパスへ誘導
  40. 本発表での学び • 高いテナント分離性を満たす必要がある制約の中で、 OVS と Linux Source Routing を用いて undercloud

    との疎通性を確保する手法 ◦ OVS による柔軟なフォワーディングやパケットの 書き換え、データパスの設計 ◦ Source Routing によって特定の通信を OVS の データパスに渡す手法
  41. We are hiring! 一緒に働く仲間を大募集しています! • プライベートクラウドや IaaS 基盤の開発・運用に 興味がある方 •

    仮想化基盤や仮想ネットワークの設計に携わること に意欲がある方 お気軽にお声がけください 👋 https://it.cyberagent.group/team/ciu/ https://www.cyberagent.co.jp/way/list/detail/id=31427 https://www.cyberagent.co.jp/way/list/detail/id=31367 https://www.cyberagent.co.jp/way/list/detail/id=29497