При развертывании Kubernetes в корпоративной среде или за файрволом часто возникает необходимость настройки прокси-сервера для доступа к внешним ресурсам. Это критически важно для загрузки образов контейнеров, обновления пакетов и взаимодействия с внешними API. В этом руководстве разберем все уровни настройки прокси в Kubernetes — от конфигурации узлов до отдельных подов.
Зачем нужен прокси в Kubernetes кластерах
Kubernetes кластеры в корпоративной среде часто работают в изолированных сетях с ограниченным доступом к интернету. Прокси-сервер решает несколько критических задач:
- Загрузка образов контейнеров — Docker Hub, Google Container Registry, частные реестры требуют внешнего доступа
- Обновление пакетов — установка зависимостей через apt, yum, pip внутри контейнеров
- Доступ к внешним API — интеграция с облачными сервисами, мониторингом, логированием
- Безопасность — контроль трафика, фильтрация доменов, логирование запросов
- Кэширование — ускорение повторных запросов к одним и тем же ресурсам
Без правильной настройки прокси вы столкнетесь с ошибками типа "image pull failed", "connection timeout" или "network unreachable" при попытке развернуть приложения. Особенно это критично для автоматических CI/CD пайплайнов, где каждая секунда простоя стоит денег.
Важно: Для корпоративных кластеров рекомендуется использовать прокси дата-центров с высокой пропускной способностью и стабильностью соединения, так как от них зависит работоспособность всей инфраструктуры.
Уровни настройки прокси в Kubernetes
Kubernetes имеет многоуровневую архитектуру, и прокси нужно настраивать на каждом уровне в зависимости от задач:
| Уровень | Что настраивается | Для чего нужно |
|---|---|---|
| Операционная система | Системные переменные окружения | Доступ утилит (curl, wget, apt) |
| Container Runtime (Docker/containerd) | Конфигурация демона | Загрузка образов контейнеров |
| kubelet | Параметры запуска kubelet | Взаимодействие с API сервером |
| Поды (Pods) | Переменные окружения в манифестах | Доступ приложений к внешним API |
| kubectl | Переменные окружения клиента | Управление кластером через прокси |
Каждый уровень требует отдельной настройки, и пропуск любого из них может привести к проблемам. Например, если настроить прокси только для Docker, но не для подов, то образы будут загружаться, но приложения внутри контейнеров не смогут обращаться к внешним API.
Настройка прокси для Docker и containerd
Container runtime — это первый компонент, который нужно настроить, так как именно он отвечает за загрузку образов контейнеров из внешних реестров. Рассмотрим настройку для обоих популярных runtime.
Настройка прокси для Docker
Для Docker нужно создать systemd drop-in файл, который добавит переменные окружения в сервис Docker:
# Создаем директорию для конфигурации
sudo mkdir -p /etc/systemd/system/docker.service.d
# Создаем файл с настройками прокси
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Перезагружаем конфигурацию systemd
sudo systemctl daemon-reload
# Перезапускаем Docker
sudo systemctl restart docker
# Проверяем, что настройки применились
sudo systemctl show --property=Environment docker
После этого Docker сможет загружать образы через прокси-сервер. Проверить работу можно командой:
docker pull nginx:latest
Настройка прокси для containerd
Containerd используется в современных Kubernetes кластерах как основной container runtime. Настройка прокси для него немного отличается:
# Создаем директорию для конфигурации
sudo mkdir -p /etc/systemd/system/containerd.service.d
# Создаем файл с настройками прокси
sudo tee /etc/systemd/system/containerd.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF
# Перезагружаем конфигурацию
sudo systemctl daemon-reload
sudo systemctl restart containerd
# Проверяем статус
sudo systemctl status containerd
Совет: Если вы используете частный container registry, добавьте его домен в NO_PROXY, чтобы избежать лишних задержек и проблем с SSL-сертификатами.
Конфигурация прокси для kubelet
Kubelet — это агент Kubernetes, который работает на каждом узле кластера. Ему также нужен доступ к API серверу и внешним ресурсам. Настройка зависит от способа установки Kubernetes.
Для kubeadm кластеров
Если вы используете kubeadm, настройте прокси через systemd:
# Создаем директорию для конфигурации kubelet
sudo mkdir -p /etc/systemd/system/kubelet.service.d
# Создаем файл с настройками прокси
sudo tee /etc/systemd/system/kubelet.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc"
EOF
# Перезагружаем kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
Для управляемых Kubernetes (EKS, GKE, AKS)
В управляемых Kubernetes сервисах настройка kubelet обычно выполняется через параметры запуска узлов или user data скрипты. Например, для AWS EKS:
#!/bin/bash
# User data скрипт для EKS worker nodes
# Настройка прокси для системы
cat <<EOF >> /etc/environment
HTTP_PROXY=http://proxy.company.com:8080
HTTPS_PROXY=http://proxy.company.com:8080
NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local
EOF
# Настройка для kubelet
mkdir -p /etc/systemd/system/kubelet.service.d
cat <<EOF > /etc/systemd/system/kubelet.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,169.254.169.254,.ec2.internal,.cluster.local"
EOF
systemctl daemon-reload
systemctl restart kubelet
Обратите внимание на добавление 169.254.169.254 в NO_PROXY — это адрес metadata сервиса AWS, который должен быть доступен без прокси.
Настройка прокси на уровне подов
Даже если вы настроили прокси для Docker и kubelet, приложения внутри подов не будут автоматически использовать прокси. Нужно явно указать переменные окружения в манифестах Kubernetes.
Настройка через Deployment манифест
Самый простой способ — добавить переменные окружения в спецификацию контейнера:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-company/my-app:latest
env:
- name: HTTP_PROXY
value: "http://proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://proxy.company.com:8080"
- name: NO_PROXY
value: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
ports:
- containerPort: 8080
Использование ConfigMap для централизованной настройки
Чтобы не дублировать настройки прокси в каждом Deployment, создайте ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: proxy-config
namespace: default
data:
HTTP_PROXY: "http://proxy.company.com:8080"
HTTPS_PROXY: "http://proxy.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
Затем используйте этот ConfigMap в Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-company/my-app:latest
envFrom:
- configMapRef:
name: proxy-config
Такой подход упрощает управление: при изменении адреса прокси достаточно обновить ConfigMap, и после перезапуска подов новые настройки применятся автоматически.
Автоматическая инъекция через MutatingWebhook
Для автоматического добавления переменных прокси во все поды можно использовать MutatingAdmissionWebhook. Это продвинутый подход, который требует разработки собственного webhook сервиса, но он позволяет централизованно управлять настройками без изменения манифестов приложений.
Правильная конфигурация NO_PROXY
Переменная NO_PROXY определяет, какие адреса и домены должны обходить прокси-сервер. Неправильная настройка NO_PROXY — самая частая причина проблем в Kubernetes кластерах.
Обязательные исключения для Kubernetes
Следующие адреса и диапазоны ВСЕГДА должны быть в NO_PROXY:
| Адрес/Диапазон | Назначение |
|---|---|
localhost, 127.0.0.1 |
Локальные подключения |
.cluster.local |
Внутренний DNS кластера |
.svc |
Kubernetes сервисы |
10.0.0.0/8 |
Pod network (зависит от CNI) |
10.96.0.0/12 |
Service network (по умолчанию) |
172.16.0.0/12 |
Частные сети Docker |
192.168.0.0/16 |
Частные локальные сети |
Пример полной конфигурации NO_PROXY
NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,10.96.0.0/12,.cluster.local,.svc,.default.svc,.default.svc.cluster.local,kubernetes.default.svc,kubernetes.default.svc.cluster.local
Внимание: Некоторые приложения не поддерживают CIDR нотацию в NO_PROXY. В таких случаях используйте wildcard: 10.* вместо 10.0.0.0/8.
Настройка kubectl для работы через прокси
Если вы управляете кластером с рабочей станции, которая находится за прокси, настройте переменные окружения для kubectl:
# Для Linux/macOS - добавьте в ~/.bashrc или ~/.zshrc
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,kubernetes.default.svc,.cluster.local
# Для Windows PowerShell
$env:HTTP_PROXY="http://proxy.company.com:8080"
$env:HTTPS_PROXY="http://proxy.company.com:8080"
$env:NO_PROXY="localhost,127.0.0.1,kubernetes.default.svc,.cluster.local"
После этого kubectl сможет подключаться к API серверу кластера через прокси. Проверьте работу:
kubectl cluster-info
kubectl get nodes
Настройка прокси с аутентификацией
Если прокси-сервер требует аутентификацию, добавьте учетные данные в URL:
export HTTP_PROXY=http://username:password@proxy.company.com:8080
export HTTPS_PROXY=http://username:password@proxy.company.com:8080
Безопасность: Не храните пароли в открытом виде в конфигурационных файлах. Используйте переменные окружения или секреты Kubernetes для хранения учетных данных прокси.
Диагностика и решение типичных проблем
Даже при правильной настройке могут возникать проблемы. Рассмотрим самые частые ошибки и способы их решения.
Ошибка "ImagePullBackOff" при загрузке образов
Симптомы: Поды не запускаются, в событиях показывается ошибка "Failed to pull image" или "connection timeout".
Диагностика:
# Проверьте события пода
kubectl describe pod <pod-name>
# Проверьте настройки прокси в Docker/containerd
sudo systemctl show --property=Environment docker
sudo systemctl show --property=Environment containerd
# Попробуйте загрузить образ вручную на узле
sudo docker pull nginx:latest
sudo crictl pull nginx:latest
Решение: Убедитесь, что прокси настроен для container runtime и домен реестра образов не находится в NO_PROXY.
Проблемы с DNS резолюцией внутри кластера
Симптомы: Поды не могут обращаться друг к другу по DNS именам (например, service-name.namespace.svc.cluster.local).
Диагностика:
# Проверьте DNS из пода
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
# Проверьте переменные прокси в поде
kubectl exec -it <pod-name> -- env | grep PROXY
Решение: Добавьте .cluster.local и .svc в NO_PROXY.
Медленная работа или таймауты при обращении к внешним API
Симптомы: Приложения медленно работают или получают timeout при запросах к внешним сервисам.
Диагностика:
# Проверьте доступность прокси из пода
kubectl exec -it <pod-name> -- curl -v -x http://proxy.company.com:8080 https://www.google.com
# Измерьте время отклика
kubectl exec -it <pod-name> -- time curl -x http://proxy.company.com:8080 https://api.example.com
Решение: Проблема может быть в производительности прокси-сервера. Рассмотрите использование резидентных прокси с географически близким расположением для снижения задержек.
SSL/TLS ошибки при работе через прокси
Симптомы: Ошибки типа "certificate verify failed" или "SSL handshake failed".
Причина: Некоторые прокси-серверы выполняют SSL inspection (расшифровку HTTPS трафика), что требует установки корневого сертификата прокси.
Решение:
# Создайте ConfigMap с сертификатом прокси
kubectl create configmap proxy-ca-cert --from-file=ca.crt=/path/to/proxy-ca.crt
# Смонтируйте сертификат в под и добавьте в системное хранилище
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
volumeMounts:
- name: proxy-ca
mountPath: /usr/local/share/ca-certificates/proxy-ca.crt
subPath: ca.crt
volumes:
- name: proxy-ca
configMap:
name: proxy-ca-cert
Best practices для прокси в продакшене
На основе опыта эксплуатации Kubernetes кластеров в корпоративной среде, вот рекомендации для надежной работы с прокси:
1. Используйте высокодоступные прокси-серверы
Прокси становится единой точкой отказа для всего кластера. Настройте несколько прокси-серверов за load balancer:
HTTP_PROXY=http://proxy-lb.company.com:8080
Где proxy-lb.company.com — это load balancer перед несколькими прокси-серверами.
2. Централизованное управление конфигурацией
Используйте ConfigMap или Secret для хранения настроек прокси вместо хардкода в каждом манифесте:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-proxy-config
namespace: kube-system
data:
HTTP_PROXY: "http://proxy-lb.company.com:8080"
HTTPS_PROXY: "http://proxy-lb.company.com:8080"
NO_PROXY: "localhost,127.0.0.1,.cluster.local,.svc,10.0.0.0/8"
3. Мониторинг и алертинг
Настройте мониторинг доступности прокси-серверов и алерты при проблемах:
- Время отклика прокси (должно быть < 100ms для локальных прокси)
- Количество ошибок подключения к прокси
- Количество ImagePullBackOff событий в кластере
- Загрузка CPU и сети на прокси-серверах
4. Документируйте исключения NO_PROXY
Ведите документацию, какие домены и IP-адреса добавлены в NO_PROXY и почему. Это поможет при траблшутинге и аудите безопасности.
5. Тестируйте изменения в dev-окружении
Перед изменением настроек прокси в продакшене всегда тестируйте в dev/staging кластере:
# Тестовый под для проверки прокси
apiVersion: v1
kind: Pod
metadata:
name: proxy-test
spec:
containers:
- name: test
image: curlimages/curl:latest
command: ["sleep", "3600"]
env:
- name: HTTP_PROXY
value: "http://new-proxy.company.com:8080"
- name: HTTPS_PROXY
value: "http://new-proxy.company.com:8080"
# Проверьте доступность внешних ресурсов
kubectl exec -it proxy-test -- curl -v https://registry.k8s.io
kubectl exec -it proxy-test -- curl -v https://docker.io
6. Используйте разные типы прокси для разных задач
Для критичных компонентов (загрузка образов, API кластера) используйте быстрые прокси дата-центров, а для приложений, требующих географического разнообразия IP — резидентные или мобильные прокси.
7. Регулярно обновляйте список NO_PROXY
При добавлении новых сервисов или изменении сетевой топологии обновляйте NO_PROXY. Автоматизируйте это через Helm charts или Kustomize:
# values.yaml для Helm chart
proxy:
enabled: true
http: "http://proxy.company.com:8080"
https: "http://proxy.company.com:8080"
noProxy:
- localhost
- 127.0.0.1
- .cluster.local
- .svc
- 10.0.0.0/8
- internal-service.company.com
Заключение
Настройка прокси в Kubernetes кластерах — это многоуровневая задача, требующая внимания к деталям на каждом уровне: от операционной системы и container runtime до отдельных подов. Правильная конфигурация обеспечивает бесперебойную работу кластера, безопасный доступ к внешним ресурсам и соответствие корпоративным политикам безопасности.
Ключевые моменты, которые нужно помнить:
- Настраивайте прокси на всех уровнях: OS, container runtime, kubelet, поды
- Правильно конфигурируйте NO_PROXY, включая все внутренние сети кластера
- Используйте централизованное управление через ConfigMap
- Мониторьте доступность и производительность прокси-серверов
- Тестируйте изменения перед применением в продакшене
Для критически важных Kubernetes кластеров рекомендуем использовать надежные прокси дата-центров с высокой доступностью и низкими задержками. Это обеспечит стабильную работу инфраструктуры и минимизирует риски простоя из-за проблем с сетевым доступом.
При возникновении проблем используйте систематический подход к диагностике: проверяйте настройки на каждом уровне, анализируйте логи и события, тестируйте подключение вручную. Большинство проблем с прокси в Kubernetes решаются правильной настройкой переменных окружения и NO_PROXY.