Олег Марков
Настройка и работа с Proxy в Kubernetes
Введение
Работа с прокси-серверами (Proxy) — одна из ключевых и часто встречающихся задач при эксплуатации приложений внутри Kubernetes. Проектируя инфраструктуру, часто возникает потребность контролировать сетевой доступ, организовывать маршрутизацию или выдавать доступ к внутренним сервисам кластера из внешней среды. Kubernetes предлагает различные способы работы с proxy: от встроенных возможностей до настройки специфических решений, таких как Ingress-контроллеры и проксирование командой kubectl. Эта статья поможет разобрать базовые и продвинутые сценарии настройки и использования Proxy в Kubernetes, объяснит внутреннюю кухню механизмов проксирования, а также даст вам практические инструкции по их применению.
Виды Proxy в Kubernetes
Встроенный прокси kube-proxy
Один из самых важных компонентов, отвечающих за внутреннюю маршрутизацию трафика в Kubernetes — это kube-proxy. Он обеспечивает сетевое взаимодействие между Pod’ами и Service внутри кластера, реализуя свою работу различными способами: iptables, IPVS или userspace.
Кратко о kube-proxy:
- Работает как DaemonSet, размещаясь на каждом узле.
- Получает информацию о сервисах и эндпоинтах от kube-apiserver.
- Настраивает локальные правила маршрутизации или проксирования для сервисного трафика.
Режимы работы kube-proxy:
- iptables: Меняет iptables на узле, чтобы маршрутизировать трафик.
- ipvs: Использует Linux IPVS для балансировки.
- userspace: Прокси через локальный порт и редиректы.
Пример проверки работы kube-proxy
Давайте посмотрим, как проверить статус kube-proxy на узле:
kubectl -n kube-system get pods -l k8s-app=kube-proxy -o wide
# Показывает, где запущены инстансы kube-proxy
Использование kubectl proxy
Часто возникает задача быстро получить доступ к Kubernetes API из внешней среды для отладки или скриптов. Для этих целей удобно использовать встроенную команду:
kubectl proxy --port=8001
# Прокси сервис открывает локальный порт 8001, доступ к API будет через http://localhost:8001/
Теперь вы можете обращаться к Kubernetes API через этот порт, все ваши запросы будут проходить по текущему kubeconfig и использовать вашу авторизацию.
Пример использования:
curl http://localhost:8001/api/v1/nodes
# Получение списка нод через запущенный прокси
Это удобно для локального теста, но не подходит для продакшн-нагрузки.
Sidecar Proxy и сервисные Mesh решения
Иногда нужно более сложное проксирование между Pod’ами, анализ и маршрутизация трафика на уровне приложений, TLS-терминация или A/B-тестирование. В таких случаях применяются отдельные прокси в виде sidecar-контейнеров (например, Envoy) и комплексные Service Mesh решения (например, Istio).
Пример sidecar с Envoy
Добавьте к своему Pod описания еще один контейнер c Envoy (в сокращенном виде):
apiVersion: v1
kind: Pod
metadata:
name: myapp-with-envoy
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080
- name: envoy
image: envoyproxy/envoy:v1.24.0
args:
- /usr/local/bin/envoy
- -c
- /etc/envoy/envoy.yaml
- --service-cluster myapp
ports:
- containerPort: 15001
volumeMounts:
- name: envoy-config
mountPath: /etc/envoy/
volumes:
- name: envoy-config
configMap:
name: envoy-config
# Здесь второй контейнер envoy будет проксировать трафик вашего приложения
Когда стоит использовать sidecar:
- Нужно инспектировать, фильтровать или защищать трафик внутри Pod.
- Требуется взаимосвязанный контроль потоков данных между различными приложениями.
Ingress-контроллеры как HTTP(S)-proxy для входящего трафика
Для управления внешним трафиком, поступающим в кластер, применяются Ingress-контроллеры. Они создают HTTP(S)-proxy на входе и маршрутизируют запросы на сервисы по правилам конфигурации Ingress.
Пример настройки Nginx Ingress Controller
Установим контроллер с помощью Helm:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx
Далее создадим Ingress-ресурс:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80
# Запросы на myapp.example.com попадут на сервис myapp-service
Контроллеры Ingress могут быть реализованы на базе Nginx, Traefik, HAProxy, Istio и других прокси.
Внешние прокси для доступа из кластера
Чаще всего внутри Pod нужно инициировать исходящие запросы через корпоративный или внешний прокси.
Настройка переменных окружения для прокси
У большинства приложений можно задать переменные окружения, чтобы трафик шел через корпоративный proxy:
apiVersion: v1
kind: Pod
metadata:
name: curl-through-proxy
spec:
containers:
- name: curl
image: curlimages/curl
command: ["sleep", "3600"]
env:
- name: HTTP_PROXY
value: http://proxy.corp.local:3128
- name: HTTPS_PROXY
value: http://proxy.corp.local:3128
- name: NO_PROXY
value: localhost,127.0.0.1,.svc,.cluster.local
# Теперь обращения curl внутри Pod'а будут идти через заданный прокси
Как видите, установка HTTP_PROXY/HTTPS_PROXY влияет на все приложения внутри контейнера, которые поддерживают такую настройку.
Проксирование на уровне контейнерной сети (CNI)
Более сложно, но более гибко — реализовать Forced Proxy на уровне CNI или iptables. Вы можете, например, настроить правила iptables с DNAT для обязательного перенаправления определенного внешнего трафика на внешний прокси.
Пример (для экспериментов, не для продакшена):
# Применим на узле с запущенным Pod
sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 10.10.10.10:3128
# Все исходящие подключения на порт 80 будут направлены на proxy 10.10.10.10:3128
Этот подход требует точной настройки диапазонов, чтобы не сломать внутреннюю сетевую маршрутизацию Kubernetes.
Layer 4 (L4) и Layer 7 (L7) прокси: в чем разница?
В Kubernetes часто применяются два типа прокси:
- L4 proxy маршрутизируют трафик на уровне TCP/UDP (например, kube-proxy).
- L7 proxy работают на уровне HTTP/HTTPS, могут анализировать и менять запросы (например, ingress-контроллеры, sidecar с Envoy).
Когда использовать L4:
- Простое балансирование или проксирование TCP/UDP-сервисов.
- Подходит для свежедеплоенных сервисов без сложного роутинга.
Когда использовать L7:
- Разруливание маршрутов по Host или Path.
- Инспекция, манипуляции с HTTP-запросами, SSL-терминация.
- Когда нужен комплексный контроль трафика.
Настройка прокси для kubectl и агентских приложений
Иногда админам или приложениям, общающимся с API, требуется пускать этот трафик через внешний прокси (например, при работе из-за NAT или в защищенных холдингах).
Проксирование для kubectl
Воспользуйтесь переменными окружения как для Pod’ов, так и для локальной машины:
export HTTPS_PROXY=http://my.proxy.server:3128
export NO_PROXY=localhost,127.0.0.1,.svc,.cluster.local,10.96.0.0/12
kubectl get pods
# Ваш kubectl будет ходить в API через прокси
Проксирование клиентских соединений через сервис ClusterIP
Если нужно скрывать сервисы внутри кластера от внешнего мира, можно использовать сервисы с типом ClusterIP (они доступны только из кластера). Для выхода наружу такие сервисы используют прокси уже на уровне приложения — например, “egress proxy”.
Пример Egress Proxy через отдельный сервис
Создайте отдельный Pod с прокси (например, Squid), опубликуйте его на ClusterIP, и обязывайте все Pod’ы отправлять трафик через этот сервис.
apiVersion: v1
kind: Service
metadata:
name: squid-proxy
spec:
type: ClusterIP
selector:
app: squid
ports:
- name: http
port: 3128
targetPort: 3128
Затем пропишите HTTP_PROXY на ваши приложения, чтобы использовать squid-proxy.default.svc.cluster.local:3128.
Продвинутые сценарии: динамическое проксирование и безопасное подключение
Использование прокси для изоляции компонентов
В некоторых случаях нужно создать “airgap” — изоляцию между сервисами с разрешением только одного контролируемого выхода наружу. Используйте внутренний egress-proxy, настроенный с whitelist/blacklist.
Пример с Envoy (урезанная конфигурация):
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
route_config:
name: local_route
virtual_hosts:
- name: external_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: allowed_sites
http_filters:
- name: envoy.filters.http.router
clusters:
- name: allowed_sites
connect_timeout: 1s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: allowed_sites
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: allowed.external.site
port_value: 443
Только разрешенные хосты попадут в whitelist, все остальное будет запрещено.
Проксирование из Pod в Internet через приватный egress-гейтвей
В большинстве современных cloud-платформ (AWS, Azure, GCP) предлагаются механизмы “egress gateway” — специальные узлы/Pods, через которые весь исходящий трафик Pod’ов может быть пропущен наружу. Это позволяет централизованно контролировать и логировать внешний трафик кластера. Настройка требует изменения маршуртизации на уровне Kubernetes NetworkPolicy, CNI или специализированных роутеров.
Разделение ролей прокси в Kubernetes
- kube-proxy занимается внутренним сервисным трафиком на уровне узлов.
- Ingress-контроллер — точка входа для внешнего HTTP/HTTPS-трафика.
- Sidecar proxy (Envoy, HAProxy) — для тонких и специфичных сценариев проксирования между микросервисами.
- Внешние прокси (Squid, корпоративные) — для контроля исходящего трафика.
Заключение
Проксирование — неотъемлемая часть Kubernetes, влияющая на безопасность, отказоустойчивость и управляемость инфраструктуры. Kubernetes из коробки реализует проксирование через kube-proxy, но современные сценарии требуют подключения ingress-контроллеров, sidecar-прокси и внешних egress gateway. Для управления трафиком часто достаточно базовой настройки, а для сложных случаев помогут инструменты уровня service mesh и дополнительные сторонние решения. Подбирайте подходящий инструмент исходя из требуемого уровня контроля, сложности инфраструктуры и задач, которые вы решаете.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Вопрос 1. Как проксировать трафик только для определенных namespace Kubernetes?
Ответ: Используйте NetworkPolicy в сочетании с egress proxy. Определите policy, блокирующую исходящий трафик для namespace, где не требуется прямой выход в интернет, и разрешите доступ только к egress-прокси. Затем настройте приложения на использование этого прокси, указав HTTP_PROXY/HTTPS_PROXY.
Вопрос 2. Как организовать прозрачный (transparent) proxy для Pod в Kubernetes, чтобы не указывать переменные окружения вручную?
Ответ: Примените iptables/Netfilter правило на уровне ноды или внутри init-контейнера вашего Pod, чтобы весь исходящий HTTP-трафик переадресовывался на адрес прокси. Также можно реализовать transparent proxy через service mesh (например, с помощью Istio Sidecar Injection с поддержкой egress gateway).
Вопрос 3. Как ограничить внешний доступ только к определенным сайтам при использовании HTTP_PROXY?
Ответ: Используйте прокси-сервер с поддержкой ACL (например, Squid или Envoy). В конфиге ограничьте доступ по ACL — разрешите только нужные домены/IP. Применяйте эти настройки централизовано, чтобы все Pod'ы получали одинаковые policy через общий proxy.
Вопрос 4. Как реализовать аудит и логирование всего проксируемого трафика из Kubernetes?
Ответ: Для максимальной прозрачности используйте централизованный прокси (squid, Envoy) или ingress/egress gateway. Включите full access logging в proxy и экспортируйте логи в вашу систему мониторинга (например, через Fluentd или Logstash в Elasticsearch/Kibana).
Вопрос 5. Почему proxy не работает внутри некоторых Pod, хотя HTTP_PROXY выставлен правильно?
Ответ: Убедитесь, что ваше приложение не использует собственные настройки прокси или игнорирует переменные окружения по умолчанию. Некоторые CLI и языковые рантаймы (например, Go, Java) требуют дополнительных ключей или переменных (например, для Java нужно указать -Dhttp.proxyHost). Проверьте документацию вашего ПО и настройте переменные согласно её рекомендациям.
Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!
Kubernetes — часть карты развития DevOps
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Kubernetes
Лучшие курсы по теме

Kubernetes и Helm
Антон Ларичев
Docker и Ansible
Антон Ларичев