> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nebius.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exposing services with load balancers

You can expose a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) in your Managed Service for Kubernetes cluster using a *load balancer*. The load balancer receives traffic on a public or private IP address, depending on how you [set it up](#how-to-set-up-a-load-balancer), and distributes the traffic between the service's Pods automatically.

<Warning>
  **Requirements to connect to a VM with private IP address**

  To connect to a Managed Service for Kubernetes cluster from a Compute VM using a [private IP address](/compute/virtual-machines/network#private-ip) or another cluster using a private load balancer, both must be in the same [region](/overview/regions) and subnet.
</Warning>

## Prerequisites

Before you start setting up a load balancer, you need to [create a Managed Kubernetes cluster](/kubernetes/clusters/manage#how-to-create-clusters) and [connect to it](/kubernetes/connect) using kubectl.

## Load balancers types

By default, load balancers are created with public IP addresses. To expose your service on a private IP address instead, add `nebius.com/load-balancer-type: internal` to the annotations of the service.

<Note>
  To retain an IP address that was automatically allocated to a load balancer and reuse it after deleting or recreating the service, follow the [How to convert a dynamically assigned public IP address to a reusable allocation](/kubernetes/networking/dynamic-to-static) guide.
</Note>

If you have created an IP address allocation ([example for public IP addresses](/compute/virtual-machines/network#public-ip-addresses)) and want to use it to allocate an IP address to a load balancer, add its ID to the service annotation `nebius.com/load-balancer-allocation-id`. The allocation type (public or private) must match the load balancer type.

The table below explains how these two annotations work together:

| Type is `internal` | Allocation ID is set | Result                                                                       |
| ------------------ | -------------------- | ---------------------------------------------------------------------------- |
| Yes                | Yes                  | Load balancer gets a **private** IP address from the **provided** allocation |
| Yes                | No                   | Load balancer gets a **private** IP address from a **new** allocation        |
| No                 | Yes                  | Load balancer gets a **public** IP address from the **provided** allocation  |
| No                 | No                   | Load balancer gets a **public** IP address from a **new** allocation         |

To allocate a public IP address from a specific IP pool, add the pool ID to the `nebius.com/load-balancer-pool-id` service annotation. When this annotation is set, the IP address is allocated from the specified pool instead of the default user subnet pool. For more information about IP pools, see the [Virtual Networks overview](/vpc/overview#pool).

```yaml theme={null}
annotations:
  nebius.com/load-balancer-pool-id: "<pool_ID>"
```

## How to set up a load balancer

<Tabs>
  <Tab title="With a private IP address">
    1. Create the manifest to set up the internal load balancer service with a private IP address (we will refer to it later as `service.yaml`):

       ```yaml theme={null}
       apiVersion: v1
       kind: Service
       metadata:
         name: nginx
         annotations:
           nebius.com/load-balancer-type: "internal"
       spec:
         selector:
           app: nginx
         ports:
           - protocol: TCP
             port: 80
             targetPort: 80
         type: LoadBalancer
       ```

    2. Create the manifest for nginx deployment (we will refer to it later as `deployment.yaml`):

       ```yaml theme={null}
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: nginx-deployment
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: nginx
         template:
           metadata:
             labels:
               app: nginx
           spec:
             containers:
             - name: nginx
               image: nginx:latest
               ports:
               - containerPort: 80
       ```

    3. Apply the configurations:

       ```bash theme={null}
       kubectl apply -f deployment.yaml
       kubectl apply -f service.yaml
       ```

    4. Check the service and the allocated IP address:

       ```bash theme={null}
       kubectl get svc nginx
       ```

       You will receive an output like the one below:

       ```bash theme={null}
       NAME         TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
       nginx        LoadBalancer   10.158.250.188   192.168.0.112   80:30512/TCP   4s
       ```
  </Tab>

  <Tab title="With a public IP address">
    1. Create the manifest to set up the internal load balancer service with a public IP address (we will refer to it later as `service.yaml`):

       ```yaml theme={null}
       apiVersion: v1
       kind: Service
       metadata:
         name: nginx
       spec:
         selector:
           app: nginx
         ports:
           - protocol: TCP
             port: 80
             targetPort: 80
         type: LoadBalancer
       ```

    2. Create the manifest for nginx deployment (we will refer to it later as `deployment.yaml`):

       ```yaml theme={null}
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: nginx-deployment
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: nginx
         template:
           metadata:
             labels:
               app: nginx
           spec:
             containers:
             - name: nginx
               image: nginx:latest
               ports:
               - containerPort: 80
       ```

    3. Apply the configurations:

       ```bash theme={null}
       kubectl apply -f deployment.yaml
       kubectl apply -f service.yaml
       ```

    4. Check the service and the allocated IP address:

       ```bash theme={null}
       kubectl get svc nginx
       ```

       You will see an output like the one below:

       ```bash theme={null}
       NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
       nginx   LoadBalancer   10.158.105.48   195.242.8.219   80:30816/TCP   13s
       ```

    5. Use the `EXTERNAL-IP` from the previous command output to connect to the service from outside of the Kubernetes cluster:

       ```bash theme={null}
       curl -i <EXTERNAL-IP>
       ```

       You will see an output like the one below:

       ```bash theme={null}
       HTTP/1.1 200 OK
       Server: nginx/1.27.1
       ```
  </Tab>
</Tabs>
