# Tenant Network Model Design **Date:** 2025-12-08 **Task:** T015 S2 **Status:** Design Complete ## 1. Overview PlasmaVMCのマルチテナントネットワーク分離モデル。OVNを基盤として、組織(org)とプロジェクト(project)の2階層でネットワークを分離する。 ## 2. Tenant Hierarchy ``` Organization (org_id) └── Project (project_id) └── VPC (Virtual Private Cloud) └── Subnet(s) └── VM Port(s) ``` ### 2.1 Organization Level - **目的**: 企業/組織レベルの分離 - **ネットワーク分離**: 完全に分離(デフォルトでは通信不可) - **用途**: マルチテナント環境での組織間分離 ### 2.2 Project Level - **目的**: プロジェクト/アプリケーションレベルの分離 - **ネットワーク分離**: プロジェクトごとに独立したVPC - **用途**: 同一組織内の異なるプロジェクト間の分離 ## 3. VPC (Virtual Private Cloud) Model ### 3.1 VPC per Project 各プロジェクトは1つのVPCを持つ(1:1関係)。 **VPC識別子:** ``` vpc_id = "{org_id}/{project_id}" ``` **OVNマッピング:** - OVN Logical Router: プロジェクトVPCのルーター - OVN Logical Switches: VPC内のサブネット(複数可) ### 3.2 VPC CIDR Allocation **戦略**: プロジェクト作成時に自動割り当て **CIDRプール:** - デフォルト: `10.0.0.0/8` を分割 - プロジェクトごと: `/16` サブネット(65,536 IP) - 例: - Project 1: `10.1.0.0/16` - Project 2: `10.2.0.0/16` - Project 3: `10.3.0.0/16` **割り当て方法:** 1. プロジェクト作成時に未使用の`/16`を割り当て 2. ChainFireに割り当て状態を保存 3. プロジェクト削除時にCIDRを解放 **CIDR管理キー(ChainFire):** ``` /networks/cidr/allocations/{org_id}/{project_id} = "10.X.0.0/16" /networks/cidr/pool/used = ["10.1.0.0/16", "10.2.0.0/16", ...] ``` ## 4. Subnet Model ### 4.1 Subnet per VPC 各VPCは1つ以上のサブネットを持つ。 **サブネット識別子:** ``` subnet_id = "{org_id}/{project_id}/{subnet_name}" ``` **デフォルトサブネット:** - プロジェクト作成時に自動作成 - 名前: `default` - CIDR: VPC CIDR内の`/24`(256 IP) - 例: VPC `10.1.0.0/16` → サブネット `10.1.0.0/24` **追加サブネット:** - ユーザーが作成可能 - VPC CIDR内で任意の`/24`を割り当て - 例: `10.1.1.0/24`, `10.1.2.0/24` **OVNマッピング:** - OVN Logical Switch: 各サブネット ### 4.2 Subnet Attributes ```rust pub struct Subnet { pub id: String, // "{org_id}/{project_id}/{subnet_name}" pub org_id: String, pub project_id: String, pub name: String, pub cidr: String, // "10.1.0.0/24" pub gateway_ip: String, // "10.1.0.1" pub dns_servers: Vec, // ["8.8.8.8", "8.8.4.4"] pub dhcp_enabled: bool, pub created_at: u64, } ``` ## 5. Network Isolation ### 5.1 Inter-Tenant Isolation **組織間:** - デフォルト: 完全に分離(通信不可) - 例外: 明示的なピアリング設定が必要 **プロジェクト間(同一組織):** - デフォルト: 分離(通信不可) - 例外: VPCピアリングまたは共有ネットワークで接続可能 ### 5.2 Intra-Tenant Communication **同一プロジェクト内:** - 同一サブネット: L2通信(直接) - 異なるサブネット: L3ルーティング(Logical Router経由) **OVN実装:** - Logical Switch内: L2 forwarding(MACアドレスベース) - Logical Router: L3 forwarding(IPアドレスベース) ## 6. IP Address Management (IPAM) ### 6.1 IP Allocation Strategy **VM作成時のIP割り当て:** 1. **自動割り当て(DHCP)**: デフォルト - サブネット内の未使用IPを自動選択 - DHCPサーバー(OVN統合)がIPを割り当て 2. **静的割り当て**: オプション - ユーザー指定のIPアドレス - サブネットCIDR内である必要がある - 重複チェックが必要 **IP割り当てキー(ChainFire):** ``` /networks/ipam/{org_id}/{project_id}/{subnet_name}/allocated = ["10.1.0.10", "10.1.0.11", ...] /networks/ipam/{org_id}/{project_id}/{subnet_name}/reserved = ["10.1.0.1", "10.1.0.254"] // gateway, broadcast ``` ### 6.2 DHCP Configuration **OVN DHCP Options:** ```rust pub struct DhcpOptions { pub subnet_id: String, pub gateway_ip: String, pub dns_servers: Vec, pub domain_name: Option, pub ntp_servers: Vec, pub lease_time: u32, // seconds } ``` **OVN実装:** - OVN Logical SwitchにDHCP Optionsを設定 - OVNがDHCPサーバーとして機能 - VMはDHCP経由でIP、ゲートウェイ、DNSを取得 ## 7. Security Groups ### 7.1 Security Group Model **セキュリティグループ識別子:** ``` sg_id = "{org_id}/{project_id}/{sg_name}" ``` **デフォルトセキュリティグループ:** - プロジェクト作成時に自動作成 - 名前: `default` - ルール: - Ingress: 同一セキュリティグループ内からの全トラフィック許可 - Egress: 全トラフィック許可 **セキュリティグループ構造:** ```rust pub struct SecurityGroup { pub id: String, // "{org_id}/{project_id}/{sg_name}" pub org_id: String, pub project_id: String, pub name: String, pub description: String, pub ingress_rules: Vec, pub egress_rules: Vec, pub created_at: u64, } pub struct SecurityRule { pub protocol: Protocol, // TCP, UDP, ICMP, etc. pub port_range: Option<(u16, u16)>, // (min, max) or None for all pub source_type: SourceType, pub source: String, // CIDR or security_group_id } pub enum Protocol { Tcp, Udp, Icmp, All, } pub enum SourceType { Cidr, // "10.1.0.0/24" SecurityGroup, // "{org_id}/{project_id}/{sg_name}" } ``` ### 7.2 OVN ACL Implementation **OVN ACL (Access Control List):** - Logical Switch PortにACLを適用 - 方向: `from-lport` (egress), `to-lport` (ingress) - アクション: `allow`, `drop`, `reject` **ACL例:** ``` # Ingress rule: Allow TCP port 80 from security group "web" from-lport 1000 "tcp && tcp.dst == 80 && ip4.src == $sg_web" allow-related # Egress rule: Allow all to-lport 1000 "1" allow ``` ## 8. NAT (Network Address Translation) ### 8.1 SNAT (Source NAT) **目的**: プライベートIPから外部(インターネット)への通信 **実装:** - OVN Logical RouterにSNATルールを設定 - プロジェクトVPCの全トラフィックを外部IPに変換 **設定:** ```rust pub struct SnatConfig { pub vpc_id: String, pub external_ip: String, // 外部IPアドレス pub enabled: bool, } ``` **OVN実装:** - Logical RouterにSNATルールを追加 - `ovn-nbctl lr-nat-add snat ` ### 8.2 DNAT (Destination NAT) **目的**: 外部から特定VMへの通信(ポートフォワーディング) **実装:** - OVN Logical RouterにDNATルールを設定 - 外部IP:ポート → 内部IP:ポートのマッピング **設定:** ```rust pub struct DnatConfig { pub vpc_id: String, pub external_ip: String, pub external_port: u16, pub internal_ip: String, pub internal_port: u16, pub protocol: Protocol, // TCP or UDP } ``` **OVN実装:** - `ovn-nbctl lr-nat-add dnat ` ## 9. Network Policies ### 9.1 Network Policy Model **ネットワークポリシー:** - セキュリティグループより細かい制御 - プロジェクト/サブネットレベルでのポリシー **ポリシータイプ:** 1. **Ingress Policy**: 受信トラフィック制御 2. **Egress Policy**: 送信トラフィック制御 3. **Isolation Policy**: ネットワーク間の分離設定 **実装:** - OVN ACLで実現 - セキュリティグループと組み合わせて適用 ## 10. API Sketch ### 10.1 Network Service API ```protobuf service NetworkService { // VPC operations rpc CreateVpc(CreateVpcRequest) returns (Vpc); rpc GetVpc(GetVpcRequest) returns (Vpc); rpc ListVpcs(ListVpcsRequest) returns (ListVpcsResponse); rpc DeleteVpc(DeleteVpcRequest) returns (Empty); // Subnet operations rpc CreateSubnet(CreateSubnetRequest) returns (Subnet); rpc GetSubnet(GetSubnetRequest) returns (Subnet); rpc ListSubnets(ListSubnetsRequest) returns (ListSubnetsResponse); rpc DeleteSubnet(DeleteSubnetRequest) returns (Empty); // Port operations (VM NIC attachment) rpc CreatePort(CreatePortRequest) returns (Port); rpc GetPort(GetPortRequest) returns (Port); rpc ListPorts(ListPortsRequest) returns (ListPortsResponse); rpc DeletePort(DeletePortRequest) returns (Empty); rpc AttachPort(AttachPortRequest) returns (Port); rpc DetachPort(DetachPortRequest) returns (Empty); // Security Group operations rpc CreateSecurityGroup(CreateSecurityGroupRequest) returns (SecurityGroup); rpc GetSecurityGroup(GetSecurityGroupRequest) returns (SecurityGroup); rpc ListSecurityGroups(ListSecurityGroupsRequest) returns (ListSecurityGroupsResponse); rpc UpdateSecurityGroup(UpdateSecurityGroupRequest) returns (SecurityGroup); rpc DeleteSecurityGroup(DeleteSecurityGroupRequest) returns (Empty); // NAT operations rpc CreateSnat(CreateSnatRequest) returns (SnatConfig); rpc DeleteSnat(DeleteSnatRequest) returns (Empty); rpc CreateDnat(CreateDnatRequest) returns (DnatConfig); rpc DeleteDnat(DeleteDnatRequest) returns (Empty); } ``` ### 10.2 Key Request/Response Types ```protobuf message CreateVpcRequest { string org_id = 1; string project_id = 2; string name = 3; string cidr = 4; // Optional, auto-allocated if not specified } message CreateSubnetRequest { string org_id = 1; string project_id = 2; string vpc_id = 3; string name = 4; string cidr = 5; // Must be within VPC CIDR bool dhcp_enabled = 6; repeated string dns_servers = 7; } message CreatePortRequest { string org_id = 1; string project_id = 2; string subnet_id = 3; string vm_id = 4; string mac_address = 5; // Optional, auto-generated if not specified string ip_address = 6; // Optional, DHCP if not specified repeated string security_group_ids = 7; } message CreateSecurityGroupRequest { string org_id = 1; string project_id = 2; string name = 3; string description = 4; repeated SecurityRule ingress_rules = 5; repeated SecurityRule egress_rules = 6; } ``` ### 10.3 Integration with PlasmaVMC VmService **VM作成時のネットワーク設定:** ```rust // VmSpecにネットワーク情報を追加(既存のNetworkSpecを拡張) pub struct NetworkSpec { pub id: String, pub network_id: String, // subnet_id: "{org_id}/{project_id}/{subnet_name}" pub mac_address: Option, pub ip_address: Option, // None = DHCP pub model: NicModel, pub security_groups: Vec, // security_group_ids } // VM作成フロー 1. VmService.create_vm() が呼ばれる 2. NetworkService.create_port() でOVN Logical Portを作成 3. OVNがIPアドレスを割り当て(DHCPまたは静的) 4. セキュリティグループをポートに適用 5. VMのNICにポートをアタッチ(TAPインターフェース経由) ``` ## 11. Data Flow ### 11.1 VM Creation Flow ``` 1. User → VmService.create_vm() └── NetworkSpec: {network_id: "org1/proj1/default", security_groups: ["sg1"]} 2. VmService → NetworkService.create_port() └── Creates OVN Logical Port └── Allocates IP address (DHCP or static) └── Applies security groups (OVN ACLs) 3. VmService → HypervisorBackend.create() └── Creates TAP interface └── Attaches to OVN port 4. OVN → Updates Logical Switch └── Port appears in Logical Switch └── DHCP server ready to serve IP ``` ### 11.2 Packet Flow (Intra-Subnet) ``` VM1 (10.1.0.10) → VM2 (10.1.0.11) 1. VM1 sends packet to 10.1.0.11 2. TAP interface → OVS bridge 3. OVS → OVN Logical Switch (L2 forwarding) 4. OVN ACL check (security groups) 5. Packet forwarded to VM2's TAP interface 6. VM2 receives packet ``` ### 11.3 Packet Flow (Inter-Subnet) ``` VM1 (10.1.0.10) → VM2 (10.1.1.10) 1. VM1 sends packet to 10.1.1.10 2. TAP interface → OVS bridge 3. OVS → OVN Logical Switch (L2, no match) 4. OVN → Logical Router (L3 forwarding) 5. Logical Router → Destination Logical Switch 6. OVN ACL check 7. Packet forwarded to VM2's TAP interface 8. VM2 receives packet ``` ## 12. Storage Schema ### 12.1 ChainFire Keys ``` # VPC /networks/vpcs/{org_id}/{project_id} = Vpc (JSON) # Subnet /networks/subnets/{org_id}/{project_id}/{subnet_name} = Subnet (JSON) # Port /networks/ports/{org_id}/{project_id}/{port_id} = Port (JSON) # Security Group /networks/security_groups/{org_id}/{project_id}/{sg_name} = SecurityGroup (JSON) # IPAM /networks/ipam/{org_id}/{project_id}/{subnet_name}/allocated = ["10.1.0.10", ...] (JSON) # CIDR Allocation /networks/cidr/allocations/{org_id}/{project_id} = "10.1.0.0/16" (string) ``` ## 13. Security Considerations ### 13.1 Tenant Isolation - **L2分離**: Logical Switchごとに完全分離 - **L3分離**: Logical Routerでルーティング制御 - **ACL強制**: OVN ACLでセキュリティグループを強制 ### 13.2 IP Spoofing Prevention - OVNが送信元IPアドレスの検証を実施 - ポートに割り当てられたIP以外からの送信をブロック ### 13.3 ARP Spoofing Prevention - OVNがARPテーブルを管理 - 不正なARP応答をブロック ## 14. Future Enhancements 1. **VPC Peering**: プロジェクト間のVPC接続 2. **VPN Gateway**: サイト間VPN接続 3. **Load Balancer Integration**: FiberLBとの統合 4. **Network Monitoring**: トラフィック分析と可観測性 5. **QoS Policies**: 帯域幅制限と優先度制御