photoncloud-monorepo/docs/por/T015-overlay-networking/tenant-network-model.md
centra a7ec7e2158 Add T026 practical test + k8shost to flake + workspace files
- Created T026-practical-test task.yaml for MVP smoke testing
- Added k8shost-server to flake.nix (packages, apps, overlays)
- Staged all workspace directories for nix flake build
- Updated flake.nix shellHook to include k8shost

Resolves: T026.S1 blocker (R8 - nix submodule visibility)
2025-12-09 06:07:50 +09:00

14 KiB
Raw Blame History

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内の/24256 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

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<String>, // ["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 forwardingMACアドレスベース
  • Logical Router: L3 forwardingIPアドレスベース

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:

pub struct DhcpOptions {
    pub subnet_id: String,
    pub gateway_ip: String,
    pub dns_servers: Vec<String>,
    pub domain_name: Option<String>,
    pub ntp_servers: Vec<String>,
    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: 全トラフィック許可

セキュリティグループ構造:

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<SecurityRule>,
    pub egress_rules: Vec<SecurityRule>,
    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に変換

設定:

pub struct SnatConfig {
    pub vpc_id: String,
    pub external_ip: String,    // 外部IPアドレス
    pub enabled: bool,
}

OVN実装:

  • Logical RouterにSNATルールを追加
  • ovn-nbctl lr-nat-add <router> snat <external_ip> <internal_cidr>

8.2 DNAT (Destination NAT)

目的: 外部から特定VMへの通信ポートフォワーディング

実装:

  • OVN Logical RouterにDNATルールを設定
  • 外部IP:ポート → 内部IP:ポートのマッピング

設定:

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 <router> dnat <external_ip> <internal_ip>

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

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

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作成時のネットワーク設定:

// VmSpecにネットワーク情報を追加既存のNetworkSpecを拡張
pub struct NetworkSpec {
    pub id: String,
    pub network_id: String,        // subnet_id: "{org_id}/{project_id}/{subnet_name}"
    pub mac_address: Option<String>,
    pub ip_address: Option<String>, // None = DHCP
    pub model: NicModel,
    pub security_groups: Vec<String>, // 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: 帯域幅制限と優先度制御