Мы используем HAProxy для балансировки трафика на Ingress-ноды Kubernetes. В нашем случае нельзя использовать BGP вместе с MetalLB, поэтому делаем балансировку снаружи — через HAProxy.
Конфигурация HAProxy:
global
log /dev/log local0
log /dev/log local1 notice
daemon
maxconn 2048
defaults
log global
mode tcp
option tcplog
timeout connect 10s
timeout client 1m
timeout server 1m
frontend k8s_api_frontend
bind *:8080
default_backend k8s_api_backend
backend k8s_api_backend
balance roundrobin
server master-1 <ip>:6443 check
server master-2 <ip>:6443 check
server master-3 <ip>:6443 check
frontend k8s_http_node_port_frontends
bind *:80
default_backend k8s_http_node_port_backend
backend k8s_http_node_port_backend
mode http
balance roundrobin
server <ingress-1> <ip>:30080 check
frontend k8s_https_node_port_frontends
bind *:443
default_backend k8s_https_node_port_backend
backend k8s_https_node_port_backend
mode tcp
balance roundrobin
server ingress-1 <ip>:30081 check
В Kubernetes на ingress-ноды проброшены NodePort'ы: 30080 для HTTP и 30081 для HTTPS.
Обратите внимание на
mode tcp на порту 443. Это необходимо, если вы хотите использовать TLS на уровне Ingress:1. В
mode http HAProxy ожидает видеть обычный HTTP-трафик (открытый текст).2. Но если клиент подключается по HTTPS, он шлёт зашифрованный трафик, и HAProxy не сможет его прочитать.
3. Поэтому мы используем
mode tcp, чтобы не трогать TLS-соединение, а просто прокинуть его до Ingress-контроллера, где оно и будет терминироваться.Пример ingress:
apiVersion: v1
kind: Ingress
metadata:
name: <name>
spec:
ingressClassName: nginx
rules:
- host: <domain>
http:
paths:
- backend:
service:
name: <svc>
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- <domain>
secretName: tls-secret
Таким образом, DNS указывает на HAProxy, который на 443 порту просто прокидывает TLS до Ingress, где и происходит вся логика маршрутизации и терминации.
#haproxy #kubernetes #ingress