Как настроить перенаправление доменов в Kubernetes Ingress
Настройка кросс-доменного проксирования в Kubernetes Ingress без перенаправлений. Решение проблемы 301 ошибки при проксировании robots.txt между доменами.
Как настроить перенаправление запросов с одного домена на другой в Kubernetes Ingress?
Добрый день! У меня возникла задача настроить Ingress в Kubernetes так, чтобы запросы к https://animori.tv/robots.txt обслуживались с https://s3.animori.tv/animori/public/robots.txt.
Текущая конфигурация Ingress
Вот моя текущая конфигурация Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
annotations:
kubernetes.io.ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/client-body-timeout: "300"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0"
spec:
rules:
- host: animori.tv
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-backend-svc
port:
number: 8088
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-frontend-svc
port:
number: 80
- host: rabbitmq.animori.tv
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-rabbit-mq-sf-svc
port:
number: 15672
- host: minio.animori.tv
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9090
- host: s3.animori.tv
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9000
- host: sentry.animori.tv
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: glitchtip-svc
port:
number: 8000
Моя попытка решения
Я попробовал добавить следующую настройку:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
annotations:
kubernetes.io.ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/client-body-timeout: "300"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0"
# Для специфических путей используем configuration-snippet
nginx.ingress.kubernetes.io/configuration-snippet: |
location = /robots.txt {
proxy_pass https://s3.animori.tv/;
proxy_set_header Host s3.animori.tv;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
spec:
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9000
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-backend-svc
port:
number: 8088
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-frontend-svc
port:
number: 80
Проблема, с которой я столкнулся
Однако при попытке перейти по https://animori.tv/robots.txt происходит перенаправление на https://animori.tv/animori/public/robots.txt и возвращается ошибка 404. При проверке с помощью curl я получаю такой ответ:
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>openresty</center>
</body>
</html>
Вопрос
Как правильно настроить Ingress в Kubernetes, чтобы запросы к https://animori.tv/robots.txt обслуживались с https://s3.animori.tv/animori/public/robots.txt без перенаправления и с кодом ответа 200?
Для решения вашей задачи по перенаправлению запросов с одного домена на другой в Kubernetes Ingress нужно правильно настроить проксирование с контролем поведения перенаправлений. Ваша текущая конфигурация частично верна, но требует дополнительных настроек для предотвращения автоматических перенаправлений.
Содержание
- Основные подходы к перенаправлению в Ingress
- Настройка проксирования между доменами
- Решение для вашего случая
- Дополнительные рекомендации
- Проверка конфигурации
Основные подходы к перенаправлению в Ingress
В Kubernetes Ingress существует несколько способов настройки перенаправлений и проксирования. На самом деле, вот основные из них:
-
Использование аннотаций для перенаправления
nginx.ingress.kubernetes.io/permanent-redirect- для постоянного перенаправления (301)nginx.ingress.kubernetes.io/temporal-redirect- для временного перенаправления (302)
-
Использование проксирования с контролем перенаправлений
nginx.ingress.kubernetes.io/proxy-redirect-from- для указания исходного URL в перенаправленияхnginx.ingress.kubernetes.io/proxy-redirect-to- для указания целевого URL в перенаправлениях
-
Использование server-snippet или configuration-snippet
- Для сложных сценариев с индивидуальной настройкой location
Для вашей задачи, честно говоря, подойдет третий подход, но с правильной настройкой заголовков и параметров проксирования. Интересно, что многие упускают важность именно этой части конфигурации.
Настройка проксирования между доменами
При проксировании между разными доменами в Nginx возникает автоматическое перенаправление, которое нужно контролировать. Согласно документации Ingress-Nginx [1], для этого необходимо правильно настроить заголовки и параметры.
Проблема в вашей конфигурации заключается в том, что при проксировании на другой домен Nginx автоматически генерирует перенаправление. Чтобы это предотвратить, нужно:
- Правильно настроить заголовки проксирования
- Использовать директиву
proxy_redirect off - Настроить обработку заголовков Host
На самом деле, это довольно распространенная проблема, с которой сталкиваются многие при настройке кросс-доменного проксирования. К счастью, решение не такое сложное, как может показаться на первый взгляд.
Решение для вашего случая
Для решения вашей задачи используйте следующую конфигурацию:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
annotations:
kubernetes.io.ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/client-body-timeout: "300"
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0"
# Конфигурация для проксирования robots.txt
nginx.ingress.kubernetes.io/configuration-snippet: |
location = /robots.txt {
proxy_pass https://s3.animori.tv/animori/public/robots.txt;
proxy_set_header Host s3.animori.tv;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_ssl_server_name on;
}
spec:
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9000
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-backend-svc
port:
number: 8088
- path: /
pathType: Prefix
backend:
service:
name: ani-mori-frontend-svc
port:
number: 80
Ключевые изменения:
-
Полный путь в proxy_pass: Вместо
proxy_pass https://s3.animori.tv/;используемproxy_pass https://s3.animori.tv/animori/public/robots.txt;- это указывает точный целевой ресурс. -
Отключение перенаправлений: Добавлена директива
proxy_redirect off;для предотвращения автоматических перенаправлений. Это, по сути, самое важное изменение. -
Настройка SSL: Добавлена
proxy_ssl_server_name on;для корректной работы с HTTPS бэкендом. -
Заголовки проксирования: Сохранены необходимые заголовки для правильной работы.
На самом деле, эти изменения кажутся небольшими, но они решают основную проблему с автоматическими перенаправлениями при кросс-доменном проксировании.
Дополнительные рекомендации
1. Использование отдельного Ingress для проксирования
Для более чистой конфигурации можно создать отдельный Ingress специально для проксирования:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: robots-proxy-ingress
annotations:
kubernetes.io.ingress.class: "nginx"
nginx.ingress.kubernetes.io/configuration-snippet: |
location = /robots.txt {
proxy_pass https://s3.animori.tv/animori/public/robots.txt;
proxy_set_header Host s3.animori.tv;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_ssl_server_name on;
}
spec:
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9000
2. Альтернативный подход с rewrite-target
Если вы хотите использовать более стандартные аннотации, можно попробовать:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: robots-rewrite-ingress
annotations:
kubernetes.io.ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: "/animori/public/$2"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: ImplementationSpecific
backend:
service:
name: ani-mori-minio-sf-svc
port:
number: 9000
3. Настройка CORS для кросс-доменных запросов
Если потребуется настроить CORS, используйте аннотации [2]:
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization"
Интересно, что многие забывают про CORS при настройке кросс-доменного проксирования, что потом приводит к проблемам с браузерными политиками безопасности.
Проверка конфигурации
После применения конфигурации проверьте работу с помощью curl:
curl -I https://animori.tv/robots.txt
Ожидаемый результат должен содержать:
- Статус код 200 OK
- Правильные заголовки Location (если есть перенаправления)
- Отсутствие нежелательных перенаправлений
Если проблема сохраняется, проверьте логи Ingress controller:
kubectl logs -n ingress-nginx <ingress-controller-pod-name>
В логах ищите ошибки конфигурации Nginx или проблемы с проксированием. Кстати, я всегда рекомендую сначала проверить конфигурацию именно через curl, прежде чем лезть в логи - это часто экономит массу времени.
Заключение
-
Правильное проксирование - Используйте
proxy_passс полным путем к ресурсу иproxy_redirect offдля предотвращения автоматических перенаправлений. Это, пожалуй, самое важное. -
Заголовки проксирования - Корректно настройте заголовки Host, X-Forwarded-* и другие для работы с кросс-доменным проксированием. Не пренебрегайте этим моментом.
-
Разделение конфигураций - Для сложных сценариев используйте отдельные Ingress объекты или конфигурационные сниппеты. Это действительно упрощает поддержку.
-
Постоянная проверка - Регулярно проверяйте работу конфигурации с помощью curl и мониторинга логов. Поверьте, это сэкономит вам кучу нервов в будущем.
-
Альтернативные подходы - Рассмотрите возможность использования rewrite-target или других стандартных аннотаций для упрощения конфигурации. Иногда стандартные решения работают лучше.
С предложенной конфигурацией запросы к https://animori.tv/robots.txt должны успешно проксироваться на https://s3.animori.tv/animori/public/robots.txt с кодом ответа 200 без нежелательных перенаправлений. Надеюсь, это решит вашу проблему!
Источники
- Annotations - Ingress-Nginx Controller
- NGINX Kubernetes Ingress Controller & Other NGINX K8s Solutions | Solo.io
- Kubernetes nginx ingress: How to redirect foo.example.org to example.org? - Server Fault
- What is the Best way to Setup Proxy Pass in an Nginx Ingress object for Kubernetes - Stack Overflow