- 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)
14 KiB
14 KiB
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
- Project 1:
割り当て方法:
- プロジェクト作成時に未使用の
/16を割り当て - ChainFireに割り当て状態を保存
- プロジェクト削除時に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
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 forwarding(MACアドレスベース)
- Logical Router: L3 forwarding(IPアドレスベース)
6. IP Address Management (IPAM)
6.1 IP Allocation Strategy
VM作成時のIP割り当て:
-
自動割り当て(DHCP): デフォルト
- サブネット内の未使用IPを自動選択
- DHCPサーバー(OVN統合)がIPを割り当て
-
静的割り当て: オプション
- ユーザー指定の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
ネットワークポリシー:
- セキュリティグループより細かい制御
- プロジェクト/サブネットレベルでのポリシー
ポリシータイプ:
- Ingress Policy: 受信トラフィック制御
- Egress Policy: 送信トラフィック制御
- 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
- VPC Peering: プロジェクト間のVPC接続
- VPN Gateway: サイト間VPN接続
- Load Balancer Integration: FiberLBとの統合
- Network Monitoring: トラフィック分析と可観測性
- QoS Policies: 帯域幅制限と優先度制御