Настройка доступа к Ingress нескольких кластеров Kubernetes, находящихся в сети за NAT
Есть у меня две мелких инсталляции кубера на домашнем сервере. Использую их для тестирования различных пайплайнов деплоя разрабатываемых приложений. Один кубер условно “тестовый”, другой условно “продакшен”. Нужно сделать приложения, запущенные в этих кубах, доступными из интернетов по https с минимальными усилиями по настройке tls с моей стороны.
Disclaimer
Настройки сети, пробросы портов и т.д. оставлю за кадром.
Nginx to the rescue
Для проброса TCP-соединений буду использовать модуль stream. В этом случае мне не придётся настраивать терминацию SSL на Nginx.
Установка модуля stream
sudo apt-get install libnginx-mod-stream
Подразумевается, что сам Nginx уже установлен и кеш пакетов apt свежий.
Настройка модуля stream
Добавляю в /etc/nginx/nginx.conf
секцию stream для трафика с TLS:
stream {
map_hash_bucket_size 64;
map $ssl_preread_server_name $targetBackend {
hostnames;
*.domain1.tld k8s1;
domain1.tld k8s1;
*.domain2.tld k8s2;
domain2.tld k8s2;
default local;
}
upstream k8s1 {
server 10.0.0.2:443;
}
upstream k8s2 {
server 10.0.0.3:443;
}
upstream local {
server 127.0.0.1:8443;
}
server {
listen 0.0.0.0:443;
ssl_preread on;
proxy_pass $targetBackend;
}
}
Где upstream k8s1
- адрес ингресса первого кубера, upstream k8s2
- адрес ингресса второго кубера, upstream local
- локальный сервер nginx.
Для того, чтобы корректно перенаправить SSL-трафик на разные upstream, использую параметр ssl_preread on
, позволяющий получить FQDN из SNI и записать его в переменную $ssl_preread_server_name
. Далее, на основе заданного маппинга сопоставляем $ssl_preread_server_name
с соответствующим $targetBackend
.
Локальный nginx придётся перенастроить чтобы он слушал обращения к сайтам с TLS на https://127.0.0.1:8443.
Перезапускаю nginx после изменения конфигурации для применения новых настроек.
systemctl restart nginx
Дополнительная настройка nginx для корректной работы Cert Manager
Cert Manager уже задеплоен в кубере и настроен для автоматизации получения SSL-сертификатов от Let’s Encrypt. Создаём для Nginx по конфигу сайта под каждый кубер, чтобы туда мог подключиться проверяющий адреса бот. Приведена минимальная конфигурация, дополняйте по обстоятельствам.
/etc/nginx/sites-enabled/k8s1
:
# HTTP
server {
listen 80;
server_name *.domain1.tld domain1.tld;
location / {
allow all;
proxy_pass http://10.0.0.2:80;
proxy_pass_header Set-Cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
/etc/nginx/sites-enabled/k8s2
:
# HTTP
server {
listen 80;
server_name *.domain2.tld domain2.tld;
location / {
allow all;
proxy_pass http://10.0.0.3:80;
proxy_pass_header Set-Cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
Бонусы
Перенаправление http на https
/etc/nginx/sites-enabled/http2https
:
server {
listen 80 default_server;
return 301 https://$host$request_uri;
}
Сайт-заглушка
/etc/nginx/sites-enabled/landing
:
server {
listen 127.0.0.1:8443 ssl http2 default_server;
root /srv/landing;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}