Проксі в Kubernetes для Pods і Services налаштовуються переважно за допомогою змінних середовища для вихідного трафіку, sidecar-контейнерів для гранульованого контролю та інтеграції з service mesh, а також Ingress-ресурсів або типів Service для керування вхідним трафіком. Ця стаття детально описує механізми реалізації конфігурацій проксі в середовищі Kubernetes.
Конфігурація вихідного проксі для Pods
Pods часто потребують вихідного проксі для доступу до зовнішніх мереж, застосування політик безпеки або керування маршрутизацією трафіку за межами кластера.
Змінні середовища
Найпростіший метод налаштування вихідного проксі для застосунків у Pod – це використання стандартних змінних середовища HTTP/HTTPS проксі. Багато застосунків і клієнтських бібліотек автоматично враховують ці змінні.
HTTP_PROXY: Вказує проксі-сервер для HTTP-запитів.HTTPS_PROXY: Вказує проксі-сервер для HTTPS-запитів.NO_PROXY: Список імен хостів, доменів або IP-адрес, розділених комами, які повинні обходити проксі. Це критично важливо для внутрішнього зв'язку кластера (наприклад,kubernetes.default.svc,10.0.0.0/8,*.svc.cluster.local).
Ці змінні визначаються у специфікації контейнера Pod.
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-proxy
spec:
containers:
- name: my-app
image: my-application-image:latest
env:
- name: HTTP_PROXY
value: "http://proxy.internal.domain:3128"
- name: HTTPS_PROXY
value: "http://proxy.internal.domain:3128"
- name: NO_PROXY
value: "localhost,127.0.0.1,.svc,.cluster.local,10.0.0.0/8" # Приклад: налаштуйте для вашого CIDR кластера
Init Containers для динамічної конфігурації проксі
Для більш складних сценаріїв Init Container може підготувати конфігурації проксі або впровадити сертифікати перед запуском основного контейнера застосунку. Це корисно для:
- Отримання деталей проксі з сервісу конфігурації.
- Генерації списків
NO_PROXYна основі внутрішніх IP-діапазонів кластера. - Впровадження користувацьких CA-сертифікатів, необхідних проксі.
apiVersion: v1
kind: Pod
metadata:
name: my-app-init-proxy
spec:
initContainers:
- name: init-proxy-config
image: alpine/git # Приклад: Простий образ для отримання конфігурації
command: ["sh", "-c", "echo 'HTTP_PROXY=http://dynamic-proxy:3128' > /mnt/proxy/config"]
volumeMounts:
- name: proxy-config-volume
mountPath: /mnt/proxy
containers:
- name: my-app
image: my-application-image:latest
command: ["sh", "-c", ". /mnt/proxy/config && exec my-app-binary"] # Джерело конфігурації
volumeMounts:
- name: proxy-config-volume
mountPath: /mnt/proxy
volumes:
- name: proxy-config-volume
emptyDir: {}
Sidecar-проксі для вихідного трафіку
Sidecar-проксі працює в тому ж Pod, що й контейнер застосунку. Він перехоплює весь вихідний трафік з контейнера застосунку, маршрутизуючи його через проксі. Цей патерн забезпечує:
- Мережеву прозорість: Контейнер застосунку не потребує знання про проксі; sidecar обробляє логіку проксі.
- Централізовану політику: Політики вихідного трафіку (наприклад, списки дозволу/заборони, обмеження швидкості, автентифікація) можуть застосовуватися на рівні sidecar, незалежно від застосунку.
- Спостережуваність: Sidecar може генерувати метрики, логи та трасування для всього вихідного трафіку.
Поширені sidecar-проксі включають Envoy (використовується Istio) або проксі Linkerd.
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-sidecar-egress
spec:
containers:
- name: my-app
image: my-application-image:latest
# Трафік застосунку перенаправляється до sidecar через правила iptables
- name: egress-proxy-sidecar
image: envoyproxy/envoy:v1.28.0 # Приклад образу Envoy
ports:
- containerPort: 15001 # Порт для надсилання трафіку застосунком
volumeMounts:
- name: envoy-config
mountPath: /etc/envoy
# Конфігурація для Envoy для пересилання трафіку до зовнішнього проксі або безпосередньо
# (зазвичай керується площиною керування service mesh)
volumes:
- name: envoy-config
configMap:
name: egress-envoy-config
Конфігурація вхідного проксі для Services
Для вхідного трафіку до Services Kubernetes пропонує кілька механізмів, які за своєю суттю передбачають проксіювання.
Kubernetes Services (kube-proxy)
Компонент kube-proxy, що працює на кожному вузлі, обробляє віртуальний IP (VIP) для Kubernetes Services. Коли клієнт всередині або за межами кластера намагається підключитися до ClusterIP Service, kube-proxy перехоплює трафік і пересилає його до одного з Pods, що підтримують цей Service. Це діє як проксі та балансувальник на рівні 4 (TCP/UDP).
- Режим:
kube-proxyпрацює в режиміiptables(за замовчуванням) абоipvs.- iptables: Використовує правила
iptablesдля виконання NAT та балансування навантаження. - ipvs: Використовує IP Virtual Server (IPVS) для більш складних алгоритмів балансування навантаження та кращої продуктивності для великої кількості сервісів.
- iptables: Використовує правила
Це проксіювання є автоматичним і не потребує явного налаштування в Pods або Services, окрім визначення самого Service.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP # Внутрішнє проксіювання за допомогою kube-proxy
Ingress-ресурси та Ingress-контролери
Для зовнішнього доступу HTTP/HTTPS до Services використовується Ingress-ресурс у поєднанні з Ingress-контролером. Сам Ingress-контролер є спеціалізованим проксі, який працює всередині кластера.
- Ingress-контролер: Pod (або набір Pods), що працює з проксі, таким як NGINX, HAProxy, Traefik, або контролер AWS ALB/GCE L7 Load Balancer. Він спостерігає за Ingress-ресурсами та динамічно налаштовує свої правила проксі.
- Ingress-ресурс: Визначає правила для маршрутизації зовнішнього HTTP/HTTPS трафіку до Services. Це включає маршрутизацію на основі хоста, маршрутизацію на основі шляху та термінацію TLS.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
tls: # Необов'язково: термінація TLS на Ingress-контролері
- hosts:
- api.example.com
secretName: my-tls-secret
LoadBalancer Services
Коли створюється Service типу LoadBalancer, він надає зовнішній балансувальник навантаження (зазвичай від хмарного провайдера). Цей зовнішній балансувальник навантаження діє як проксі, пересилаючи трафік до NodePorts Service, який kube-proxy потім маршрутизує до підтримуючих Pods.
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer # Зовнішнє проксіювання за допомогою LB хмарного провайдера
Sidecar-проксі для вхідного трафіку (Service Mesh)
У service mesh (наприклад, Istio, Linkerd) sidecar-проксі впроваджуються в Pods для обробки як вхідного, так і вихідного трафіку для контейнера застосунку. Для вхідного трафіку sidecar перехоплює вхідний трафік до застосунку та застосовує політики mesh (наприклад, автентифікацію, авторизацію, перемикання трафіку, повторні спроби, розрив ланцюга) перед пересиланням його до контейнера застосунку.
Це забезпечує:
- Застосування політик: Детальний контроль над тим, як взаємодіють сервіси.
- Спостережуваність: Автоматичні метрики, логування та розподілене трасування для всього зв'язку між сервісами.
- Керування трафіком: Розширені можливості маршрутизації (наприклад, canary-розгортання, A/B-тестування).
- Безпека: Взаємний TLS (mTLS) між сервісами.
Впровадження та конфігурація sidecar зазвичай автоматизуються площиною керування service mesh.
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-mesh-sidecar
labels:
app: my-app
# Приклад для Istio: запускає автоматичне впровадження sidecar
istio-injection: enabled
spec:
containers:
- name: my-app
image: my-application-image:latest
ports:
- containerPort: 8080
# Площина керування Istio автоматично додає sidecar-контейнер 'istio-proxy'
# та налаштовує правила iptables для перенаправлення трафіку.
Порівняння підходів до проксі
| Функція | Змінні середовища | Sidecar-проксі (ручний) | Sidecar-проксі (Service Mesh) | Ingress-контролер | LoadBalancer Service |
|---|---|---|---|---|---|
| Область дії | Вихідний трафік з конкретного контейнера | Вихідний/вхідний для конкретного Pod | Вихідний/вхідний для всіх Pods з mesh | Зовнішній вхідний трафік до Services | Зовнішній вхідний трафік до Services |
| Рівень | L7 (HTTP/S) | L4/L7 | L4/L7 | L7 (HTTP/S) | L4 (TCP/UDP) |
| Конфігурація | env Pod |
containers, volumes, iptables Pod (ручний) |
Автоматизовано площиною керування | Ingress-ресурс, конфігурація контролера | Тип Service, хмарний провайдер |
| Складність | Низька | Висока (ручні iptables, конфігурація) | Середня (початкове налаштування mesh) | Середня (правила Ingress, контролер) | Низька (визначення Service) |
| Можливості | Базовий вихідний проксі | Гранульований контроль трафіку, спостережуваність, безпека | Розширене керування трафіком, mTLS, спостережуваність, безпека | Маршрутизація за шляхом/хостом, термінація TLS, функції L7 | Базове балансування навантаження L4, зовнішній IP |
| Основний випадок використання | Прості вимоги до зовнішнього проксі | Користувацький, детальний проксі для застосунку | Зв'язок мікросервісів, політики, спостережуваність | Зовнішній доступ HTTP/S, маршрутизація L7 | Зовнішній доступ L4, хмарна інтеграція |
| Вплив на застосунок | Застосунок повинен враховувати змінні середовища | Застосунок не знає (прозоро) | Застосунок не знає (прозоро) | Застосунок не знає (ціль Service) | Застосунок не знає (ціль Service) |
Практичні міркування
Керування сертифікатами
Проксі часто завершують або ініціюють TLS-з'єднання.
- Ingress-контролери: Зазвичай керують TLS-сертифікатами через Kubernetes Secrets, дозволяючи термінацію TLS на межі кластера.
- Sidecar-проксі: У service mesh sidecars автоматично обробляють mTLS, часто використовуючи короткоживучі сертифікати, видані центром сертифікації mesh. Для вихідного трафіку їм може знадобитися довіряти користувацьким CA для перевірки зашифрованого трафіку або підключення до внутрішніх сервісів.
Продуктивність та накладні витрати
Кожен проксі додає додатковий стрибок у мережевому шляху, що може збільшити затримку.
kube-proxy: Високооптимізований. Режимipvsпропонує кращу продуктивність для великої кількості сервісів.- Sidecars: Вносять навантаження на CPU, пам'ять та мережу для кожного Pod. Це навантаження є важливим аспектом при розгортанні service mesh.
- Ingress-контролери: Можуть стати вузьким місцем, якщо їх не масштабувати належним чином для великих обсягів трафіку.
Спостережуваність
Проксі надають централізовану точку для збору телеметрії.
- Логи: Проксі можуть реєструвати деталі з'єднання, заголовки запитів/відповідей та помилки.
- Метрики: Можна збирати стандартні метрики, такі як частота запитів, затримки, частота помилок.
- Трасування: Sidecar-проксі в service mesh дозволяють розподілене трасування без змін у коді застосунку.
Безпека
Проксі є критично важливими точками застосування політик безпеки.
- Контроль доступу: Проксі можуть застосовувати політики автентифікації та авторизації для вхідного та вихідного трафіку.
- Сегментація мережі: Проксі можуть ізолювати трафік застосунків, запобігаючи прямим з'єднанням між сервісами, які не повинні взаємодіяти.
- Захист від DDoS: Зовнішні проксі (такі як Ingress-контролери або хмарні LB) можуть пропонувати можливості пом'якшення DDoS-атак.