---
title: "Балансировщик нагрузки Kubernetes"
---

> Полный индекс документации для ИИ-агентов: [llms.txt](https://timeweb.cloud/llms.txt).

Для обеспечения устойчивой работы приложений и равномерного распределения трафика между подами в Kubernetes используется балансировщик нагрузки. Он помогает избежать перегрузки отдельных подов, поддерживая высокую доступность и стабильность сервисов.

## Базовая конфигурация балансировщика нагрузки

Для создания балансировщика нагрузки в Kubernetes создадим ресурс типа Service с типом LoadBalancer. Пример базового манифеста:

```yml
apiVersion: v1
kind: Service
metadata:
  name: example-balancer
  namespace: kubernetes-dashboard
spec:
  selector:
    app.kubernetes.io/name: nginx
  ports:
    - port: 80            # Внешний порт для доступа к приложению
      targetPort: 80      # Порт пода, на который перенаправляется трафик
      appProtocol: k8s.timeweb.cloud/proto-http
  type: LoadBalancer
```

В этом примере балансировщик будет перенаправлять трафик с порта 80 на порт 80 внутри подов, соответствующих селектору `app.kubernetes.io/name: nginx`.

Если вам нужно добавить несколько правил для балансировки, обязательно указывайте атрибут `name` для каждого порта:

```yml
apiVersion: v1
kind: Service
metadata:
  name: example-balancer
  namespace: kubernetes-dashboard
spec:
  selector:
    app.kubernetes.io/name: nginx
  ports:
    - port: 80
      targetPort: 80
      appProtocol: k8s.timeweb.cloud/proto-http
      name: http
    - port: 443
      targetPort: 443
      appProtocol: k8s.timeweb.cloud/proto-https
      name: https
  type: LoadBalancer
```

Значение атрибута `name` может быть произвольным.

Для каждого порта можно указать протокол трафика с помощью атрибута `appProtocol`. Это позволяет явно задать, как будет обрабатываться трафик на стороне балансировщика. По умолчанию используется значение `proto-tcp`.

Поддерживаются следующие значения:

-   `k8s.timeweb.cloud/proto-http` — обычный HTTP-трафик.
-   `k8s.timeweb.cloud/proto-https` — HTTPS-трафик.
-   `k8s.timeweb.cloud/proto-tcp` — TCP-трафик.
-   `k8s.timeweb.cloud/proto-tcp-ssl` — TCP-трафик с поддержкой TLS.
-   `k8s.timeweb.cloud/proto-http2` - HTTP/2-трафик.

После создания балансировщик будет отображаться в панели управления в разделе «[Балансировщики](https://timeweb.cloud/my/balancer)» с лейблом «K8S».

![Scr 20250625 Lyfb](https://content.timeweb.com/assets/6dbaa39c-5fcb-4f2d-8bbb-5f2f6624960f.png?width=2028&height=900)

Обратите внимание, что балансировщик, созданный с помощью Kubernetes, нельзя изменить в панели управления или через API — только через `kubectl`.

![Scr 20250625 Llzh](https://content.timeweb.com/assets/134fdea9-bdc8-4bad-b0d0-34ffc7f1c96c.png?width=1514&height=784)

## Дополнительные параметры для настройки балансировщика

Для более гибкой настройки балансировщика нагрузки в Kubernetes можно использовать дополнительные параметры. Они указываются в виде аннотаций (`annotations`) в манифесте `Service`.

Пример манифеста с параметрами, заданными через аннотации:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: example-balancer
  namespace: kubernetes-dashboard
  labels:
    app: nginx
  annotations:
    k8s.timeweb.cloud/attached-loadbalancer-algo: "leastconn"    
    k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip: "true" 
spec:
  selector:
    app.kubernetes.io/name: nginx
  ports:
    - port: 80
      appProtocol: k8s.timeweb.cloud/proto-http
      targetPort: 80
  type: LoadBalancer
```

В этом примере задаются два дополнительных параметра:

-   `k8s.timeweb.cloud/attached-loadbalancer-algo`: алгоритм балансировки — `leastconn` (выбирает сервер с наименьшим числом активных подключений).
-   `k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip`: выделяет балансировщику внешний IP с защитой от DDoS.

> [!NOTE]
> Дополнительные параметры также можно задавать с помощью лейблов, но этот способ считается устаревшим. Также, при использовании лейблов некоторые параметры могут применяться некорректно. Поэтому мы рекомендуем использовать аннотации.

## Доступные параметры для балансировщика нагрузки

В таблице ниже перечислены доступные параметры для настройки балансировщика нагрузки. Каждый параметр задается в виде аннотации в манифесте Service:

| **Параметр** | **Назначение** |
| --- | --- |
| `k8s.timeweb.cloud/attached-loadbalancer-preset-id: "391"` | Задает конфигурацию балансировщика. По умолчанию выбирается минимальная конфигурация для зоны. Получить id тарифов можно при помощи [API](https://timeweb.cloud/api-docs#tag/Balansirovshiki/operation/getBalancersPresets). |
| `k8s.timeweb.cloud/attached-loadbalancer-algo: "roundrobin"` | Алгоритм балансировки: `roundrobin` или `leastconn`. |
| `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-check-interval: "10"` | Интервал между проверками доступности (в секундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-timeout: "5"` | Таймаут проверки доступности (в секундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-error-count: "3"` | Количество неудачных проверок перед отключением апстрима. |
| `k8s.timeweb.cloud/attached-loadbalancer-healthcheck-recover-count: "2"` | Количество успешных проверок для восстановления апстрима. |
| `k8s.timeweb.cloud/attached-loadbalancer-no-external-ip: "true"` | Отключение внешнего публичного IP для балансировщика. |
| `k8s.timeweb.cloud/attached-loadbalancer-ddos-guard-external-ip: "true"` | Выделение внешнего IP с защитой от DDoS. |
| `k8s.timeweb.cloud/ignore-timeweb-cloud-loadbalancer: "true"` | Исключает сервис из обработки балансировщиком Timeweb Cloud. Может быть полезно, если используется другой `LoadBalancer`, например, `kube-vip` или `MetalLB`. |
| `k8s.timeweb.cloud/attached-loadbalancer-proxy-enable: "true"` | Включает прокси-режим для балансировщика. При использовании этой аннотации принимающее приложение (например, ingress-контроллер или прокси) также должно быть настроено на прием proxy protocol. В противном случае запросы могут завершаться ошибками (например, HTTP 400). Примеры настройки из официальной документации: [Ingress NGINX](https://kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/), [Traefik](https://doc.traefik.io/traefik/master/reference/install-configuration/entrypoints/). |
| `k8s.timeweb.cloud/attached-loadbalancer-connect-timeout: "5000"` | Время ожидания установления TCP-подключения с апстримом (в миллисекундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-client-timeout: "50000"` | Время ожидания новых TCP-сегментов от клиента (в миллисекундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-server-timeout: "50000"` | Таймаут ожидания ответа от бэкенда (в миллисекундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-http-request-timeout: "10000"` | Таймаут выполнения HTTP-запроса (в миллисекундах). |
| `k8s.timeweb.cloud/attached-loadbalancer-maxconn: "10000"` | Максимальное количество соединений, которое может обрабатывать балансировщик на фронтенде. |
| `k8s.timeweb.cloud/attached-loadbalancer-ssl: "true"` | Включение автоматического выпуска SSL-сертификата. Если указано `false`, сертификат будет удален. |
| `k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com"` | Домен, на который необходимо выпустить SSL-сертификат. |
| `k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "lets_encrypt"` | Тип SSL-сертификата. Доступные значения: `lets_encrypt` или `custom`. |
| `k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "true"` | Перенаправление HTTP-запросов на HTTPS с кодом `307`. Работает только вместе с настроенным сертификатом: `attached-loadbalancer-ssl` и `attached-loadbalancer-ssl-fqdn`. |

### Служебные аннотации

Помимо пользовательских параметров, система может автоматически добавлять служебные аннотации.

Например:

```yaml
metadata:
  annotations:
    k8s.timeweb.cloud/lb-last-config: "..."
```

Аннотация `k8s.timeweb.cloud/lb-last-config` содержит последнюю примененную конфигурацию балансировщика. Система управления кластером использует ее для сравнения текущей и новой конфигурации, чтобы определить, требуется ли обновление балансировщика.

Изменять или добавлять эту аннотацию вручную не требуется.

## Настройка перенаправления на HTTPS

Для включения перенаправления на HTTPS добавьте параметр:

```yaml
metadata:
 annotations:
   k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "true"
```

Перед включением перенаправления HTTP на HTTPS убедитесь, что домен из параметра `k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn` уже указывает на IP-адрес балансировщика. Это необходимо для выпуска сертификата Let's Encrypt.

Параметр `k8s.timeweb.cloud/attached-loadbalancer-force-ssl` включает перенаправление HTTP-запросов на HTTPS с кодом `307`.

Если включить `force-ssl` без настроенного сертификата и домена, параметр будет проигнорирован, а балансировщик продолжит принимать обычный HTTP-трафик. В логах появится предупреждение:

```shell
force-ssl requested but no SSL certificate configured; ignoring force-ssl
```

Если домен еще не указывает на IP-адрес балансировщика, Let's Encrypt не сможет выпустить сертификат. При этом балансировщик может начать отвечать редиректом на HTTPS, где нет валидного сертификата. В результате клиенты будут получать TLS-ошибку, хотя сервис в Kubernetes может выглядеть исправным.

Отключить уже включенное перенаправление значением `k8s.timeweb.cloud/attached-loadbalancer-force-ssl: "false"` нельзя. Чтобы выключить перенаправление, удалите и пересоздайте балансировщик.

## Возможные ошибки

### Не удалось получить IP

Если при создании балансировщика не удалось получить внешний IP-адрес, в аннотациях сервиса появится следующая отметка:

```bash
k8s.timeweb.cloud/attached-loadbalancer-ensuring-error: true
```

Это означает, что что-то пошло не так при привязке внешнего IP. В таком случае рекомендуем попробовать пересоздать балансировщик или [обратиться в техническую поддержку](https://timeweb.cloud/my/support/help-question).

#### Как проверить

Найдите все сервисы с типом `LoadBalancer` в кластере:

```bash
kubectl get svc --all-namespaces --field-selector spec.type=LoadBalancer
```

Посмотрите аннотации нужного сервиса:

```bash
kubectl describe svc <имя-сервиса> -n <неймспейс>
```

Если в выводе будет аннотация `k8s.timeweb.cloud/attached-loadbalancer-ensuring-error: true`, пересоздайте балансировщик или [напишите в поддержку](https://timeweb.cloud/my/support/help-question) и укажите ID кластера.

## Практический пример использования балансировщика

Для демонстрации работы балансировщика создадим два деплоймента Nginx, каждый из которых будет отображать свою HTML-страницу. Балансировщик случайным образом распределит запросы между подами, и в зависимости от этого будет показана одна из страниц.

### Подготовка окружения

Для удобства управления и быстрого удаления всех ресурсов, связанных с балансировщиком, создадим отдельный неймспейс. Это упростит тестирование и последующее удаление ресурсов, сохраняя основной кластер чистым.

Выполните команду для создания неймспейса:

```shell
kubectl create namespace test-namespace
```

После создания используем этот неймспейс для всех дальнейших ресурсов, включая балансировщик, деплойменты и `ConfigMap`. Для этого добавьте `namespace: test-namespace` в каждый манифест, связанный с примером.

### Создание ConfigMap для HTML-страниц

Начнем с создания `ConfigMap`, в котором будут храниться две HTML-страницы. Под 1 будет отображать страницу с заголовком «Pod 1», а Под 2 — с заголовком «Pod 2». Эти страницы подключаются к Nginx в подах.

**Файл `nginx-pages-configmap.yaml`:**

```shell
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-pages
  namespace: test-namespace
data:
  index-page1.html: |
    <html>
      <body>
        <h1>Pod 1</h1>
        <p>This is page served by Pod 1.</p>
      </body>
    </html>
  index-page2.html: |
    <html>
      <body>
        <h1>Pod 2</h1>
        <p>This is page served by Pod 2.</p>
      </body>
    </html>
```

Здесь мы создаем `ConfigMap` с двумя HTML-файлами: `index-page1.html` и `index-page2.html`. Они будут монтироваться в подах Nginx, позволяя каждому поду отображать свою страницу.

Примените `ConfigMap`:

```shell
kubectl apply -f nginx-pages-configmap.yaml
```

### Создание деплойментов Nginx

Теперь создадим два деплоймента, каждый из которых будет использовать разные HTML-страницы из `ConfigMap`. Деплойменты используют селектор `app: nginx` — это метка, которую балансировщик будет использовать для выбора подов, участвующих в распределении нагрузки.

**Файл `nginx-deployment-pod1.yaml`:**

```yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-pod1
  namespace: test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        volumeMounts:
          - name: nginx-pages
            mountPath: /usr/share/nginx/html/index.html
            subPath: index-page1.html
        ports:
          - containerPort: 80
      volumes:
      - name: nginx-pages
        configMap:
          name: nginx-pages
```

Этот деплоймент создает один под (реплика 1) с образом Nginx, который монтирует страницу `index-page1.html` из `ConfigMap` в директорию `/usr/share/nginx/html/index.html`. Порт 80 открыт для доступа к странице.

Примените деплоймент:

```shell
kubectl apply -f nginx-deployment-pod1.yaml
```

**Файл `nginx-deployment-pod2.yaml`:**

```yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-pod2
  namespace: test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          volumeMounts:
            - name: nginx-pages
              mountPath: /usr/share/nginx/html/index.html
              subPath: index-page2.html
          ports:
            - containerPort: 80
      volumes:
        - name: nginx-pages
          configMap:
            name: nginx-pages
```

Этот деплоймент также создает под Nginx, но монтирует страницу `index-page2.html`, отличающуюся содержимым.

Примените второй деплоймент:

```shell
kubectl apply -f nginx-deployment-pod2.yaml
```

### Настройка балансировщика нагрузки

Теперь создадим балансировщик, который будет направлять запросы на поды с меткой `app: nginx`.

**Файл `nginx-loadbalancer.yaml`:**

```yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
  namespace: test-namespace
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      appProtocol: k8s.timeweb.cloud/proto-http
  type: LoadBalancer
```

В этом `Service` указываем `type: LoadBalancer`, что создает балансировщик нагрузки, и `selector: app: nginx`, который направляет запросы на поды Nginx из наших деплойментов. Запросы, поступающие на балансировщик, распределяются между подами при помощи алгоритма `roundrobin`, так как этот алгоритм выбирается по умолчанию.

Примените балансировщик:

```shell
kubectl apply -f nginx-loadbalancer.yaml
```

### Проверка работы балансировщика

После создания балансировщика его внешний IP-адрес можно увидеть в [панели управления](https://timeweb.cloud/my/balancer) или выполнив команду:

```shell
kubectl get services -n test-namespace
```

При доступе по этому IP вы увидите страницу, отображаемую одним из подов. Каждый раз при обновлении страницы трафик может перенаправляться на разные поды, что позволяет балансировщику нагрузки случайным образом переключать отображаемую страницу.

### Удаление ресурсов после проверки

После того как вы проверили работу балансировщика, вы можете удалить все созданные поды и ресурсы. Для этого выполните следующие команды:

```shell
kubectl delete service nginx-loadbalancer -n test-namespace
kubectl delete deployment nginx-pod1 -n test-namespace
kubectl delete deployment nginx-pod2 -n test-namespace
kubectl delete configmap nginx-pages -n test-namespace
```

Эти команды удалят балансировщик, деплойменты подов и `ConfigMap`, созданные ранее.

Либо удалите неймспейс полностью, выполнив:

```shell
kubectl delete namespace test-namespace
```

Этот способ автоматически удалит все ресурсы, связанные с тестовым окружением.
