Перейти к содержимому
Гайды 8 мин чтения 2 просмотров

Прокси в Kubernetes

Подробное руководство по настройке прокси в Kubernetes для подов и сервисов. Узнайте, как улучшить безопасность и управление трафиком в вашем кластере.

Прокси в Kubernetes настраиваются для подов через переменные окружения или sidecar-контейнеры, а для сервисов — через централизованные egress-шлюзы, управляемые сетевыми политиками, обеспечивая контроль над исходящим трафиком.

Зачем использовать прокси в Kubernetes?

Использование прокси-серверов в Kubernetes необходимо для решения ряда задач:
* Безопасность и соответствие нормативам: Фильтрация исходящего трафика, аудит сетевых запросов, принудительное использование корпоративных прокси.
* Управление исходящим трафиком (Egress Control): Централизованное управление доступом к внешним ресурсам, блокировка нежелательных соединений, привязка к фиксированным IP-адресам для внешних сервисов (IP-whitelisting).
* Обход ограничений сети: Доступ к ресурсам за корпоративным фаерволом или в изолированных сетях.
* Мониторинг и логирование: Сбор метрик и логов всего исходящего трафика.
* Маскировка источника: Скрытие реального IP-адреса пода.
* Кэширование: Ускорение доступа к часто запрашиваемым внешним ресурсам.

Методы настройки прокси для подов

Для отдельных подов существует два основных подхода к настройке прокси.

Использование переменных окружения

Наиболее простой способ — задать стандартные переменные окружения HTTP_PROXY, HTTPS_PROXY и NO_PROXY непосредственно в манифесте пода или деплоймента. Этот метод требует, чтобы приложение внутри пода поддерживало эти переменные окружения.

  • HTTP_PROXY: URL прокси-сервера для HTTP-трафика.
  • HTTPS_PROXY: URL прокси-сервера для HTTPS-трафика.
  • NO_PROXY: Список хостов или доменов, для которых прокси не должен использоваться. Значения могут быть разделены запятыми и включать IP-адреса, CIDR-блоки, доменные имена. Для Kubernetes важно включить внутренние домены кластера (например, *.svc.cluster.local, IP-адрес API-сервера, CIDR сервисов и подов) в NO_PROXY.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app-image:latest
        env:
        - name: HTTP_PROXY
          value: "http://proxy.example.com:3128"
        - name: HTTPS_PROXY
          value: "http://proxy.example.com:3128"
        - name: NO_PROXY
          value: "localhost,127.0.0.1,kubernetes.default.svc.cluster.local,.svc,.cluster.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
        # Добавьте переменные для аутентификации, если прокси требует
        # - name: PROXY_USERNAME
        #   valueFrom:
        #     secretKeyRef:
        #       name: proxy-credentials
        #       key: username
        # - name: PROXY_PASSWORD
        #   valueFrom:
        #     secretKeyRef:
        #       name: proxy-credentials
        #       key: password

Ограничения:
* Зависит от поддержки переменных окружения каждым приложением. Не все приложения могут корректно их интерпретировать.
* Требует изменения манифестов для каждого пода.
* Не обеспечивает прозрачного перехвата TCP-трафика, только HTTP/HTTPS.

Sidecar-контейнеры

Подход с sidecar-контейнером предполагает запуск отдельного прокси-сервера (например, Envoy, Squid, Nginx) в том же поде, что и основное приложение. Весь исходящий трафик из основного контейнера перенаправляется через этот sidecar-прокси, обычно с помощью правил iptables.

Принцип работы:
1. В под добавляется дополнительный контейнер с прокси-сервером.
2. С помощью initContainer или напрямую в entrypoint sidecar-контейнера настраиваются правила iptables внутри сетевого пространства имен пода.
3. Эти правила перенаправляют исходящий трафик из основного контейнера на локальный порт sidecar-прокси.
4. Sidecar-прокси обрабатывает трафик и отправляет его во внешнюю сеть.

Преимущества:
* Прозрачность: Основное приложение не требует модификаций и не знает о наличии прокси.
* Языковая агностичность: Работает независимо от языка или фреймворка приложения.
* Централизация: Единая точка конфигурации прокси для всех приложений в поде.
* Расширенные возможности: Sidecar-прокси могут предоставлять дополнительные функции, такие как балансировка нагрузки, трассировка, метрики, взаимная TLS (mTLS).

Пример (Squid как sidecar):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-with-proxy-sidecar
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app-sidecar
  template:
    metadata:
      labels:
        app: my-app-sidecar
    spec:
      initContainers:
      - name: setup-iptables
        image: alpine/iptables:latest # Или любой образ с iptables
        securityContext:
          capabilities:
            add: ["NET_ADMIN"] # Требуется для изменения iptables
        command: ["sh", "-c", "iptables -t nat -A OUTPUT -p tcp ! -d 127.0.0.1 --dport 80 -j REDIRECT --to-port 3128; iptables -t nat -A OUTPUT -p tcp ! -d 127.0.0.1 --dport 443 -j REDIRECT --to-port 3128"]
        # В реальной среде NO_PROXY логика будет сложнее, чтобы не перенаправлять внутренний трафик
      containers:
      - name: my-app-container
        image: my-app-image:latest
        # Приложение не требует настройки прокси
      - name: squid-proxy-sidecar
        image: ubuntu/squid:latest # Или другой образ Squid
        ports:
        - containerPort: 3128
        # Дополнительная конфигурация Squid, например, через ConfigMap
        # volumeMounts:
        # - name: squid-config
        #   mountPath: /etc/squid/squid.conf
        # subPath: squid.conf
      # volumes:
      # - name: squid-config
      #   configMap:
      #     name: squid-configmap

Ограничения:
* Увеличивает потребление ресурсов (CPU, память) для каждого пода.
* Усложняет отладку.
* Требует привилегий NET_ADMIN для initContainer или sidecar, что является риском безопасности.

Методы настройки прокси для сервисов и кластера

Для централизованного управления исходящим трафиком на уровне всего кластера или отдельных пространств имен используются более комплексные решения.

Egress-шлюзы на уровне Service Mesh (например, Istio)

Service Mesh, такой как Istio, Linkerd или Consul Connect, предоставляет мощные механизмы для управления трафиком, включая исходящий. Egress Gateway — это специализированный компонент Service Mesh, который выступает в качестве центральной точки выхода для всего трафика из кластера.

Принцип работы:
1. Весь исходящий трафик из подов, включенных в Service Mesh, перехватывается прокси-контейнерами (например, Envoy sidecar).
2. Настраиваются правила Service Mesh (например, EgressGateway, VirtualService, Gateway в Istio), которые направляют этот трафик через выделенные поды Egress Gateway.
3. Egress Gateway, в свою очередь, отправляет трафик во внешнюю сеть через настроенный прокси-сервер.

Преимущества:
* Глубокий контроль: Детализированные политики для исходящего трафика на основе хоста, порта, протокола, источника.
* Наблюдаемость: Автоматический сбор метрик, логов, трассировки для всего исходящего трафика.
* mTLS: Возможность применения взаимной TLS даже для внешних соединений (если прокси это поддерживает).
* Централизованное управление: Единая панель управления для всех политик.

Пример (концептуальный для Istio Egress Gateway):

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-proxy-serviceentry
spec:
  hosts:
  - proxy.example.com # IP-адрес или домен вашего прокси-сервера
  ports:
  - number: 3128
    name: http-proxy
    protocol: HTTP
  resolution: STATIC
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: direct-to-proxy
spec:
  hosts:
  - "*"
  gateways:
  - mesh
  - istio-egressgateway
  http:
  - match:
    - gateways:
      - mesh
    # Это правило перенаправляет весь внешний HTTP-трафик через Egress Gateway
    route:
    - destination:
        host: proxy.example.com # Перенаправляем на внешний прокси
        port:
          number: 3128
      weight: 100
    # Дополнительные правила для HTTPS и других протоколов

Ограничения:
* Высокая сложность развертывания и управления Service Mesh.
* Дополнительные накладные расходы на ресурсы.

Централизованный egress-прокси с NetworkPolicies

Данный подход предполагает развертывание выделенного пода (или нескольких подов) с прокси-сервером (например, Squid, Nginx) в кластере и использование Kubernetes NetworkPolicies для принудительного направления всего исходящего трафика через этот прокси.

Принцип работы:
1. Разворачивается Deployment для прокси-сервера.
2. Service предоставляет доступ к этому прокси.
3. NetworkPolicies настраиваются так, чтобы разрешать исходящий трафик из подов только к IP-адресу прокси-сервера (или его Service IP), а весь остальной внешний трафик блокировать.

Преимущества:
* Централизация: Единая точка выхода и контроля для всего кластера или пространства имен.
* Простота: Относительно проще в настройке, чем Service Mesh.
* Гибкость: Можно использовать любой прокси-сервер.

Пример:

# 1. Deployment для прокси-сервера (например, Squid)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: egress-proxy
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: egress-proxy
  template:
    metadata:
      labels:
        app: egress-proxy
    spec:
      containers:
      - name: squid
        image: ubuntu/squid:latest
        ports:
        - containerPort: 3128
        # Добавьте ConfigMap с конфигурацией Squid, если требуется
        # volumeMounts:
        # - name: squid-config
        #   mountPath: /etc/squid/squid.conf
        # subPath: squid.conf
      # volumes:
      # - name: squid-config
      #   configMap:
      #     name: squid-configmap
---
# 2. Service для доступа к прокси
apiVersion: v1
kind: Service
metadata:
  name: egress-proxy-service
  namespace: default
spec:
  selector:
    app: egress-proxy
  ports:
  - protocol: TCP
    port: 3128
    targetPort: 3128
---
# 3. NetworkPolicy для принудительного использования прокси
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: enforce-egress-proxy
  namespace: default
spec:
  podSelector: {} # Применяется ко всем подам в данном namespace
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: egress-proxy # Разрешаем исходящий трафик к нашему прокси
    ports:
    - protocol: TCP
      port: 3128
  - to: # Разрешаем трафик к DNS-серверу кластера (важно!)
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns # Или другой лейбл вашего DNS-сервиса
    ports:
    - protocol: UDP
      port: 53
  - to: # Разрешаем трафик к API-серверу Kubernetes
    - ipBlock:
        cidr: 0.0.0.0/0 # Это заглушка, нужно указать CIDR API-сервера
    ports:
    - protocol: TCP
      port: 443
  # Для подов, которым нужен доступ к внутренним сервисам без прокси:
  # - to:
  #   - podSelector: {}
  #   - namespaceSelector: {}
  #   ports:
  #   - protocol: TCP
  #     port: 80
  #   - protocol: TCP
  #     port: 443

Ограничения:
* Требует корректной настройки NetworkPolicy, иначе можно заблокировать весь трафик.
* Приложениям по-прежнему нужно быть настроенными на использование прокси (через переменные окружения или sidecar). NetworkPolicy лишь запрещает прямой выход, но не перенаправляет трафик автоматически. Для прозрачного перенаправления потребуется iptables на подах.

Настройка прокси на уровне узлов

Настройка прокси на уровне узлов Kubernetes (рабочих нод) обычно не применяется для трафика приложений, но важна для системных компонентов, таких как kubelet, containerd (или docker), которые могут инициировать внешние запросы (например, для загрузки образов контейнеров или отправки метрик).

Принцип работы:
Переменные окружения HTTP_PROXY, HTTPS_PROXY, NO_PROXY задаются для процессов kubelet и демонов контейнеризации.

Пример (для containerd через systemd):

Создайте или отредактируйте файл /etc/systemd/system/containerd.service.d/http-proxy.conf:

[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=http://proxy.example.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.svc,.cluster.local,$(hostname),$(hostname -i),10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

Затем перезагрузите systemd и containerd:

sudo systemctl daemon-reload
sudo systemctl restart containerd

Для kubelet аналогично. Обычно это делается через конфигурацию kubelet или через systemd unit-файл.

Ограничения:
* Влияет на все контейнеры, запущенные этим демоном, если они не переопределяют переменные.
* Требует ручного управления на каждой ноде или автоматизации через средства управления конфигурацией (Ansible, Puppet, Terraform).

Выбор метода и рекомендации

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

Метод Прозрачность для приложения Сложность настройки Гибкость/Функциональность Ресурсы Применение
Переменные окружения Нет (приложение должно знать) Низкая Базовая (HTTP/S прокси) Низкие Простые приложения, единичные поды
Sidecar-контейнеры Да Средняя Расширенная (iptables, аудит, метрики, mTLS с Envoy) Средние-Высокие Микросервисы, Service Mesh без Egress Gateway
Egress-шлюз (Service Mesh) Да Высокая Детализированные политики, трассировка, mTLS, observability Высокие Крупные кластеры, строгие политики безопасности
Центральный egress-прокси + NetworkPolicies Нет (приложение должно знать) Средняя Базовая (HTTP/S прокси) + сетевая изоляция Средние Несколько приложений, централизованный контроль
Уровень узлов Да (для демонов) Средняя Базовая (HTTP/S прокси) Низкие Системные компоненты, загрузка образов

Общие рекомендации:
* NO_PROXY: Всегда тщательно настраивайте NO_PROXY для предотвращения перенаправления внутреннего трафика Kubernetes (API-сервер, DNS, внутренняя связь между подами) через внешний прокси. Включите localhost, 127.0.0.1, CIDR подов и сервисов, домены .svc, .cluster.local, а также IP-адрес API-сервера.
* Управление секретами: Если прокси требует аутентификации, используйте Kubernetes Secrets для хранения учетных данных и монтируйте их в поды, а не храните в манифестах открытым текстом.
* Производительность: Оценивайте влияние прокси на задержку и пропускную способность, особенно при высоких нагрузках.
* Отказоустойчивость: Разворачивайте прокси-серверы как минимум с двумя репликами для обеспечения отказоустойчивости.
* Health Checks: Настройте liveness и readiness пробы для прокси-контейнеров, чтобы Kubernetes мог управлять их состоянием.
* Логирование: Убедитесь, что прокси-серверы настроены на адекватное логирование для аудита и отладки.

Обновлено: 03.03.2026
Назад к категории

Попробуйте наши прокси

20,000+ прокси в 100+ странах мира