Хостинг
VDS
Аренда серверов
Домены
Почта
SSL
Хранилище
Сайты
Обзоры
Регламенты
AI Studio
Kubernetes
Архив
Ограничение доступа к сервису LoadBalancer с помощью loadBalancerSourceRanges

Сервис типа LoadBalancer по умолчанию принимает запросы с любых адресов, для которых настроена маршрутизация до внешнего IP балансировщика. Чтобы ограничить доступ к приложению определёнными клиентами, в поле spec.loadBalancerSourceRanges сервиса задаётся список разрешённых IP-адресов или подсетей в формате CIDR.

Балансировщик пробрасывает к подам только трафик с разрешённых адресов. Соединения с остальных адресов отбрасываются на уровне сети: приложение их не видит, а клиент вместо ответа от приложения получает таймаут соединения.

Ограничим доступ к сервису LoadBalancer одним IP-адресом, проверим работу ограничения с двух внешних виртуальных машин и снимем его.

Для начала работы

Перед началом работы вам понадобится:

  • Кластер Kubernetes в NetAngels

  • Установленная утилита kubectl с настроенным доступом (конфигурационный файл кластера)

  • Две внешние виртуальные машины с публичными IP-адресами: адрес одной будет добавлен в список разрешённых, со второй будет проверяться, что доступ с неразрешённого адреса запрещён

1. Запуск nginx и создание балансировщика

Запустим веб-сервер nginx в двух экземплярах и создадим для него сервис типа LoadBalancer без ограничений:

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Namespace
metadata:
  name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: nginx
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: nginx
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  type: LoadBalancer
  externalTrafficPolicy: Local
EOF
namespace/nginx created
deployment.apps/nginx created
service/nginx created

Проверим готовность сервиса командой describe — когда балансировщику назначат внешний адрес, он появится в поле LoadBalancer Ingress:

kubectl describe service nginx -n nginx
Name:                     nginx
Namespace:                nginx
Labels:                   <none>
Annotations:              <none>
Selector:                 app=nginx
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.38.1
IPs:                      10.96.38.1
LoadBalancer Ingress:     80.87.99.128 (VIP)
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30243/TCP
Endpoints:                10.244.226.80:80,10.244.226.81:80
Session Affinity:         None
External Traffic Policy:  Local
Internal Traffic Policy:  Cluster
HealthCheck NodePort:     30918
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  15s   service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   8s    service-controller  Ensured load balancer

Внешний адрес 80.87.99.128 назначен, сервис готов.

Отметим, что IP-адрес 80.87.99.128 это адрес выданный балансировщику в демонстрационном кластере. При выполнении инструкций из статьи замените его на адрес балансировщика выданный вашему сервису, а адреса тестовых виртуальных машин — на адреса своих виртуальных машин.

Проверим также статус подов и сервиса:

kubectl get pods,svc -n nginx
NAME                       READY   STATUS    RESTARTS   AGE
pod/nginx-96b9d695-65g5h   1/1     Running   0          16s
pod/nginx-96b9d695-m9pvk   1/1     Running   0          16s

NAME            TYPE           CLUSTER-IP   EXTERNAL-IP    PORT(S)        AGE
service/nginx   LoadBalancer   10.96.38.1   80.87.99.128   80:30243/TCP   16s

2. Проверка доступа без ограничений

Запустим curl с первой виртуальной машины:

curl -s http://80.87.99.128/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
Further configuration is required for the web server, reverse proxy,
API gateway, load balancer, content cache, or other features.</p>

<p>For online documentation and support please refer to
<a href="https://nginx.org/">nginx.org</a>.<br/>
To engage with the community please visit
<a href="https://community.nginx.org/">community.nginx.org</a>.<br/>
For enterprise grade support, professional services, additional
security features and capabilities please refer to
<a href="https://f5.com/nginx">f5.com/nginx</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Пока поле loadBalancerSourceRanges не задано, доступ открыт с любого адреса: со второй виртуальной машины будет получена та же страница.

3. Ограничение доступа по IP-адресам

Добавим в сервис поле loadBalancerSourceRanges со списком разрешённых источников. Значения задаются в формате CIDR: <адрес>/<маска>. Укажем адрес первой виртуальной машины:

kubectl -n nginx patch service nginx -p '{"spec": {"loadBalancerSourceRanges": ["<IP первой виртуальной машины>/32"]}}'
service/nginx patched

Поле можно задать и сразу в манифесте сервиса — тогда балансировщик будет создан с ограничениями с самого начала.

Изменения на балансировщике применяются асинхронно. При начале изменения в событиях сервиса появляется Ensuring load balancer, а после применения новых настроек — Ensured load balancer. Состояние проверяем командой describe:

kubectl describe service nginx -n nginx | tail -9
External Traffic Policy:     Local
Internal Traffic Policy:     Cluster
HealthCheck NodePort:        30918
LoadBalancer Source Ranges:  80.87.106.224/32
Events:
  Type    Reason                Age                 From                Message
  ----    ------                ----                ----                -------
  Normal  EnsuringLoadBalancer  29s (x2 over 110s)  service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   28s (x2 over 103s)  service-controller  Ensured load balancer

Событие Ensured load balancer говорит о том, что новые настройки на балансировщике применены, и можно переходить к проверке.

Два момента, которые важно учитывать:

  • Ограничение действует только для обращения через внешний адрес балансировщика. Трафик, который идёт в обход балансировщика — например, по ClusterIP внутри кластера, — не затрагивается.

  • Соединения с неразрешённых адресов отбрасываются балансировщиком: клиенту не приходит ни ответа от приложения, ни ошибки HTTP — он видит лишь таймаут соединения.

4. Проверка ограничения

С первой виртуальной машины, чей адрес указан в loadBalancerSourceRanges, сервис по-прежнему доступен:

curl -s -o /dev/null -w '%{http_code}\n' --max-time 10 http://80.87.99.128/
200

Со второй виртуальной машины, не указанной в списке, соединение не устанавливается:

curl -sS --max-time 10 http://80.87.99.128/
curl: (28) Connection timed out after 10002 milliseconds

Балансировщик не пробрасывает трафик с неразрешённого адреса, поэтому соединение не устанавливается и curl завершает работу с ошибкой таймаута.

5. Снятие ограничения

Уберём ограничения, установив поле в пустое значение:

kubectl -n nginx patch service nginx -p '{"spec": {"loadBalancerSourceRanges": null}}'
service/nginx patched

Поле станет пустым списком, и балансировщик снова начнёт принимать соединения со всех адресов. Дождёмся нового события Ensured load balancer в выводе kubectl describe service nginx -n nginx и проверим доступ со второй виртуальной машины:

curl -s -o /dev/null -w '%{http_code}\n' --max-time 10 http://80.87.99.128/
200

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

Удалим неймспейс вместе с сервисом, деплоем и подами:

kubectl delete ns nginx
namespace "nginx" deleted

Нам доверяют тысячи компаний и разработчиков

22 года
Предоставляем услуги профессионального хостинга
35 000+
Клиентов доверяют нам размещение своих сайтов
99.99%
Подтвержденный uptime наших серверов хостинга
Callibri
Крылья
Tele-Club
Linline
Премьер зал
УГМК-Здоровье
Магнум
Алатырь
Туристер
Callibri
Крылья
Tele-Club
Linline
Премьер зал
УГМК-Здоровье
Магнум
Алатырь
Туристер
ВК49865