> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ibee.co.in/docs/network-security/vpc-ip-management/virtual-ips/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ibee.co.in/_mcp/server. # Virtual IPs > Reserve a specific private IP inside a VPC subnet for MetalLB and Kubernetes LoadBalancer services, announced by nodes you authorize. A Virtual IP (VIP) is a private address that **you choose** from a VPC subnet and reserve as a floating endpoint. Unlike a VM's private address — which belongs to one VM's interface once the VM attaches to a subnet — a Virtual IP is not bound to any single VM's interface. Instead, you authorize one or more NAT-connected nodes to *announce* it, so traffic for that address is served by whichever announcer is healthy. This is the mechanism behind bare-metal **MetalLB** and **Kubernetes `LoadBalancer`** services: MetalLB advertises the reserved private address from the announcer nodes, giving your service a stable in-VPC IP. > **Info** > > A Virtual IP claims an address for MetalLB and authorizes the nodes that may > announce it. IPAM will not assign the address to a VM, so the same address is > never handed out as a node's interface IP. ## Prerequisites * A VPC with at least one **NAT-connected node** to act as an announcer. Announcers are the VMs that advertise the Virtual IP. * The subnet you want the address to live in (any subnet of the VPC). ## Choose the private IP You pick the exact address. It must be a host address **inside the selected subnet's CIDR** that is currently free. The backend validates the address and rejects it when it is: | Rejected | Reason | | -------------------------------- | -------------------------------------------------------- | | Outside the subnet CIDR | The address must be a host in the chosen subnet's range. | | The subnet gateway | The gateway address is reserved for routing. | | The network or broadcast address | Neither is a usable host address. | | Already allocated | Another node or Virtual IP already holds it. | > **Tip** > > Check the **Private IP ledger** on the VPC's **Subnets** tab, or list the > subnet's existing allocations with > `GET /networking/vpcs/{vpc_id}/network-allocations?workspace_id=607005`, to see > which host addresses are already taken before choosing one. ## Reserve a Virtual IP ### Open Reserved VIPs Open the VPC's detail page and select the **Reserved VIPs** tab, then click **Reserve Virtual IP**. The button is available once the VPC has a subnet. ### Pick a subnet and a free host address Select a **Subnet** and enter the **Private IP** — an unused host address inside its CIDR (for example `10.144.4.17`). ### Choose the announcer nodes Under **MetalLB announcer nodes**, tick the NAT-connected VMs that may announce the address. ### Reserve the address Click **Reserve Virtual IP**. The **Reserved VIPs** tab lists each reservation with its private IP, purpose, announcers, attached public IP, and status. ### Reserve with the API Provide the announcer VM IDs in `announcer_vm_ids`: ```bash curl -X POST \ "https://api.ibee.ai/v1/networking/vpcs/vpc-example/virtual-ips?workspace_id=607005" \ -H "Authorization: Bearer $IBEE_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "subnet_id": "subnet-example", "private_ip": "10.144.4.17", "purpose": "metallb", "announcer_vm_ids": ["vm-example-a", "vm-example-b"] }' ``` #### Request fields | Field | Required | Description | | ------------------ | -------- | ----------------------------------------------------------------------------- | | `subnet_id` | Yes | Subnet of the VPC that the address belongs to. | | `private_ip` | Yes | The specific, unused host address to reserve, inside the subnet CIDR. | | `purpose` | Yes | `metallb` for a MetalLB / Kubernetes `LoadBalancer` Virtual IP. | | `announcer_vm_ids` | Yes | One or more VM IDs of NAT-connected nodes authorized to announce the address. | ## List and inspect ```bash # List every Virtual IP in the VPC curl "https://api.ibee.ai/v1/networking/vpcs/vpc-example/virtual-ips?workspace_id=607005" \ -H "Authorization: Bearer $IBEE_TOKEN" # Inspect a single Virtual IP curl "https://api.ibee.ai/v1/networking/vpcs/vpc-example/virtual-ips/vip-example?workspace_id=607005" \ -H "Authorization: Bearer $IBEE_TOKEN" ``` Each Virtual IP reports its `private_ip`, `subnet_id`, `purpose`, and the `announcer_vm_ids` currently authorized to advertise it. ## Expose a Virtual IP publicly A Virtual IP is private by design. To make the service it fronts reachable from the internet, attach a [Reserved IP](/docs/network-security/vpc-and-ip-management/reserved-ips) to it: 1. On the **Reserved VIPs** tab, click **Attach** on the Virtual IP's row. 2. Select an unattached Reserved IP in the VPC's location. 3. Click **Attach Reserved IP**. This creates a one-to-one public mapping: inbound and return traffic use the Reserved IP, while the announcers continue to serve the traffic inside the VPC. To remove public access, click **Detach** on the row and confirm **Detach Reserved IP**. The Virtual IP stays reserved, and the Reserved IP returns to your workspace pool for reuse. On a NAT VPC you can instead forward a single NAT gateway port to the Virtual IP with a [port forwarding rule](/docs/network-security/vpc-and-ip-management#nat-port-forwarding) (destination type **MetalLB VIP**). ## Release a Virtual IP Releasing a Virtual IP returns the private address to the subnet pool. Remove the address from your MetalLB configuration first. Any Reserved IP attached to it must be detached first — deletion is blocked while one is attached. In the portal, click the delete icon on the Virtual IP's row on the **Reserved VIPs** tab, then click **Delete Reservation**. With the API: ```bash curl -X DELETE \ "https://api.ibee.ai/v1/networking/vpcs/vpc-example/virtual-ips/vip-example?workspace_id=607005" \ -H "Authorization: Bearer $IBEE_TOKEN" ``` ## Errors | Status | When | | ----------------- | ----------------------------------------------------------------------------------------- | | `400 Bad Request` | The address is outside the subnet CIDR, or is the gateway, network, or broadcast address. | | `404 Not Found` | The VPC, subnet, or Virtual IP ID does not exist in this workspace. | | `409 Conflict` | The address is already allocated to another node or Virtual IP. | ## Related pages * [VPC](/docs/network-security/vpc-and-ip-management) * [Reserved IPs](/docs/network-security/vpc-and-ip-management/reserved-ips) * [Networking for VMs](/docs/infrastructure/cloud-vms/networking-for-vms) * [API reference](/docs/api-reference) > Reserve a specific private IP inside a VPC subnet for MetalLB and Kubernetes LoadBalancer services, announced by nodes you authorize.