Nginx как TCP, HTTP Load Balancer¶
Реализуем LoadBalancer с функциями:
- умеет прокидывать в докер контейнеры на хосте
- умеет проксировать на другие сервера в локальной сети
- умеет прокидывать tcp в kubernetes кластер
Это дает возможность терминировать tls как на хосте(для контейнеров и для хостов в локальной сети) так и в кластере(и получать сертификаты через cert-manager)
Основная магия здесь в ssl_preread_server_name. Используется в Nginx для извлечения имени сервера (Server Name Indication - SNI) из SSL/TLS ClientHello сообщения во время установки SSL-соединения с клиентом. Это позволяет еще до момента терминации tls определять куда направить трафик
Сертификаты в кластере cert-manager сможет получить только через DNS01, потому что 80 порт на хосте , а на нем нет записей о ресурсах, которые развернуты через ingress nginx.
Минус это схемы в том, что не получится использовать external-dns, потому что ingress будут создаваться с ExternalIP внутренним, а нам нужен внешний, чтобы запись А создавалась корректно. Получается хосты придется добавлят вручную в nginx.
Nginx из-за пропускной скорости и меньших задержек на данный момент лучше подходит для prod, Traefik более динамичный используем под test, stage. https://medium.com/beyn-technology/is-nginx-dead-is-traefik-v3-20-faster-than-traefik-v2-f28ffb7eed3e
/etc/nginx/nginx.conf
stream {
upstream truedev {
server 127.0.0.1:8443;
}
upstream k8s {
server 10.0.1.102:31443;
server 10.0.1.103:31443;
}
#upstream host {
# server 127.0.0.1;
#}
# ...
map $ssl_preread_server_name $upstream {
truedev.ru truedev;
k8ss.truedev.ru k8s;
# ...
}
server {
listen 443;
resolver 1.1.1.1;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass $upstream;
ssl_preread on;
}
}
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
/etc/nginx/sites-enabled/k8ss.truedev.ru.conf
upstream k8ss_server {
server 10.0.1.102:31080;
server 10.0.1.103:31080;
}
server {
listen 80;
server_name k8ss.truedev.ru;
location / {
proxy_pass http://k8ss_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
include /etc/nginx/templates/letsencrypt.conf;
}
IBS
server {
server_name ibs-java.truedev.ru;
access_log /var/log/nginx/ibs-java.truedev.ru-access.log;
error_log /var/log/nginx/ibs-corenet.truedev.ru-error.log;
client_max_body_size 0;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 1200;
fastcgi_read_timeout 1200;
proxy_read_timeout 1d;
proxy_buffering off;
location / {
# limit_req zone=darkfire burst=50 nodelay;
proxy_pass http://127.0.0.1:8083;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffers 16 4k;
proxy_buffer_size 2k;
}
listen 8443 ssl http2;
ssl_certificate /etc/letsencrypt/live/ibs-java.truedev.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ibs-java.truedev.ru/privkey.pem;
include /etc/nginx/ssl_params;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "block-all-mixed-content";
ssl_dhparam /etc/ssl/certs/dhparam.pem;
include /etc/nginx/templates/letsencrypt.conf;
}
ssl params
ssl_protocols TLSv1.2 TLSv1.3; # Only allow TLS 1.2 and TLS 1.3
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
ssl_stapling on;
ssl_stapling_verify on;
ssl_prefer_server_ciphers off; # Disable prefer_server_ciphers