Настройка Ingress для robots.txt из S3 в Kubernetes
Полное руководство по настройке Nginx Ingress Controller для проксирования robots.txt из S3 без перенаправлений и с правильными статусами ответа.
Как правильно настроить Ingress в Kubernetes, чтобы при запросе к https://animori.tv/robots.txt файл robots.txt отдавался напрямую из хранилища s3.animori.tv? Я уже пробовал различные конфигурации, но вместо нужного файла получаю либо ошибку 404, либо перенаправление 301 на /animori/public/robots.txt.
Подскажите, как именно нужно настроить правила и заголовки в Nginx Ingress Controller, чтобы запрос к animori.tv/robots.txt проксировал содержимое из s3.animori.tv/animori/public/robots.txt без каких-либо перенаправлений и с правильными статусами ответа?
Чтобы настроить проксирование robots.txt из S3 через Kubernetes Nginx Ingress Controller без перенаправлений, нужно использовать правильные конфигурации с аннотациями или фрагментами конфигурации. Основная проблема обычно заключается в том, что стандартные конфигурации создают перенаправления вместо прямого проксирования.
Содержание
- Основные методы настройки проксирования
- Использование server-snippet аннотации
- Настройка location блоков
- Настройка заголовков проксирования
- Полный пример конфигурации Ingress
- Решение проблем с 301 перенаправлением
- Альтернативные подходы
Основные методы настройки проксирования
Для решения вашей проблемы доступны несколько подходов, каждый со своими преимуществами. Наиболее эффективными являются использование аннотаций server-snippet и настройка специфичных location блоков.
Ключевая особенность конфигурации для robots.txt заключается в том, что нужно создать отдельный обработчик для этого пути, который будет напрямую проксировать запрос к S3 без применения стандартных правил маршрутизации.
Использование server-snippet аннотации
Самый гибкий способ - использовать аннотацию nginx.ingress.kubernetes.io/server-snippet для добавления пользовательской конфигурации Nginx прямо в ваш Ingress ресурс.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: animori-ingress
annotations:
nginx.ingress.kubernetes.io/server-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_set_header X-Forwarded-Host $host;
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-version-id;
proxy_hide_header x-amz-delete-marker;
proxy_hide_header Server;
proxy_ignore_headers Set-Cookie;
proxy_intercept_errors on;
error_page 404 =200 @fallback;
}
location @fallback {
return 404;
}
Эта конфигурация создает точное совпадение для /robots.txt и напрямую проксирует запрос к S3 без каких-либо перенаправлений.
Настройка location блоков
Альтернативный подход - использовать более явную настройку с отдельным Ingress ресурсом для robots.txt:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: animori-robots-txt
annotations:
nginx.ingress.kubernetes.io/rewrite-target: ""
spec:
ingressClassName: nginx
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: Exact
backend:
service:
name: s3-proxy-service
port:
number: 80
Для этого потребуется отдельный сервис, который будет перенаправлять запросы к S3. Вы можете использовать простой nginx pod с конфигурацией:
location /robots.txt {
resolver 8.8.8.8;
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_set_header X-Forwarded-Host $host;
proxy_hide_header x-amz-*;
proxy_hide_header Server;
}
Настройка заголовков проксирования
Правильная настройка заголовков критически важна для работы с S3. Ссылка на официальную документацию Nginx Ingress Controller показывает, что нужно контролировать заголовки Host и другие прокси-заголовки.
Если вы получаете 301 перенаправление, скорее всего, проблема в неправильной настройке заголовка Host. S3 ожидает, чтобы запросы приходили с правильным именем хоста.
Для решения этой проблемы убедитесь, что в вашей конфигурации есть:
proxy_set_header Host s3.animori.tv;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
Эти заголовки гарантируют, что S3 будет обрабатывать запрос правильно.
Полный пример конфигурации Ingress
Вот комплексная конфигурация, которая должна решить вашу проблему:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: animori-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/server-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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Скрытие заголовков S3
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-version-id;
proxy_hide_header x-amz-delete-marker;
proxy_hide_header Server;
# Настройка таймаутов
proxy_connect_timeout 30s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
# Обработка ошибок
proxy_intercept_errors on;
error_page 404 =200 @robots-fallback;
}
location @robots-fallback {
return 200 "User-agent: *\nDisallow: /\n";
add_header Content-Type text/plain;
}
# Основная конфигурация для остальных запросов
location / {
proxy_pass http://animori-backend;
proxy_set_header Host $host;
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:
ingressClassName: nginx
tls:
- hosts:
- animori.tv
secretName: animori-tls
rules:
- host: animori.tv
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: animori-backend
port:
number: 80
Решение проблем с 301 перенаправлением
Если вы получаете 301 перенаправление на /animori/public/robots.txt, это означает, что S3 пытается перенаправить запрос на правильный путь. Это происходит из-за того, что S3 ожидает запросы к корневому bucket, а не к вложенным путям.
Чтобы решить эту проблему, вам нужно:
-
Проверить доступность файла: Убедитесь, что файл действительно доступен по пути
s3.animori.tv/animori/public/robots.txt -
Настроить правильный bucket: Возможно, вам нужно настроить статический хостинг для S3 bucket с корневым путем
/robots.txt -
Использовать rewrite правила: Если S3 продолжает перенаправлять, добавьте rewrite правило:
location = /robots.txt {
rewrite ^ /animori/public/robots.txt break;
proxy_pass https://s3.animori.tv;
proxy_set_header Host s3.animori.tv;
# ... остальные заголовки
}
Альтернативные подходы
Использование ConfigMap для глобальной конфигурации
Вы можете настроить глобальную конфигурацию через ConfigMap Nginx Ingress Controller:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: ingress-nginx
data:
proxy-set-headers: "custom-headers"
custom-headers: |
set $proxy_host "s3.animori.tv";
Использование отдельного сервиса
Если ни один из вышеперечисленных методов не работает, создайте отдельный сервис только для robots.txt:
apiVersion: apps/v1
kind: Deployment
metadata:
name: robots-txt-proxy
spec:
replicas: 1
selector:
matchLabels:
app: robots-txt-proxy
template:
metadata:
labels:
app: robots-txt-proxy
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
volumes:
- name: nginx-config
configMap:
name: robots-txt-nginx-config
Создайте ConfigMap с конфигурацией:
apiVersion: v1
kind: ConfigMap
metadata:
name: robots-txt-nginx-config
data:
default.conf: |
server {
listen 80;
server_name _;
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_hide_header x-amz-*;
proxy_hide_header Server;
}
location / {
return 404;
}
}
Затем настройте Ingress для использования этого сервиса:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: animori-robots-txt
spec:
ingressClassName: nginx
rules:
- host: animori.tv
http:
paths:
- path: /robots.txt
pathType: Exact
backend:
service:
name: robots-txt-service
port:
number: 80
Заключение
Для правильной настройки проксирования robots.txt из S3 через Kubernetes Nginx Ingress Controller:
- Используйте server-snippet аннотацию для добавления специфичной конфигурации для
/robots.txt - Настройте правильные заголовки проксирования, особенно
Host s3.animori.tv - Скрыть заголовки S3 с помощью
proxy_hide_headerдля чистого ответа - Обрабатывайте ошибки с помощью
error_pageдля корректной обработки 404 - Используйте точное совпадение пути (
location = /robots.txt) вместо префиксов
Если вы продолжаете получать 301 перенаправления, проверьте настройки S3 bucket и рассмотрите возможность использования отдельного прокси-сервиса только для robots.txt. Основная проблема обычно заключается в том, что стандартные конфигурации создают перенаправления вместо прямого проксирования.
Источники
- Advanced configuration with Snippets | NGINX Documentation
- ConfigMap - Ingress-Nginx Controller - Kubernetes
- How to set robots.txt globally in nginx for all virtual hosts - Server Fault
- How do i configure nginx to redirect to a url for robots.txt & sitemap.xml - Stack Overflow
- S3 proxy on kubernetes using Ingress - Stack Overflow
- Annotations - Ingress-Nginx Controller
- Kubernetes, nginx-ingress and S3 bucket | liet’s blog