Веб

Настройка 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 блоков.

Ключевая особенность конфигурации для robots.txt заключается в том, что нужно создать отдельный обработчик для этого пути, который будет напрямую проксировать запрос к S3 без применения стандартных правил маршрутизации.


Использование server-snippet аннотации

Самый гибкий способ - использовать аннотацию nginx.ingress.kubernetes.io/server-snippet для добавления пользовательской конфигурации Nginx прямо в ваш Ingress ресурс.

yaml
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:

yaml
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 с конфигурацией:

nginx
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 ожидает, чтобы запросы приходили с правильным именем хоста.

Для решения этой проблемы убедитесь, что в вашей конфигурации есть:

nginx
proxy_set_header Host s3.animori.tv;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;

Эти заголовки гарантируют, что S3 будет обрабатывать запрос правильно.


Полный пример конфигурации Ingress

Вот комплексная конфигурация, которая должна решить вашу проблему:

yaml
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, а не к вложенным путям.

Чтобы решить эту проблему, вам нужно:

  1. Проверить доступность файла: Убедитесь, что файл действительно доступен по пути s3.animori.tv/animori/public/robots.txt

  2. Настроить правильный bucket: Возможно, вам нужно настроить статический хостинг для S3 bucket с корневым путем /robots.txt

  3. Использовать rewrite правила: Если S3 продолжает перенаправлять, добавьте rewrite правило:

nginx
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:

yaml
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:

yaml
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 с конфигурацией:

yaml
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 для использования этого сервиса:

yaml
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:

  1. Используйте server-snippet аннотацию для добавления специфичной конфигурации для /robots.txt
  2. Настройте правильные заголовки проксирования, особенно Host s3.animori.tv
  3. Скрыть заголовки S3 с помощью proxy_hide_header для чистого ответа
  4. Обрабатывайте ошибки с помощью error_page для корректной обработки 404
  5. Используйте точное совпадение пути (location = /robots.txt) вместо префиксов

Если вы продолжаете получать 301 перенаправления, проверьте настройки S3 bucket и рассмотрите возможность использования отдельного прокси-сервиса только для robots.txt. Основная проблема обычно заключается в том, что стандартные конфигурации создают перенаправления вместо прямого проксирования.

Источники

  1. Advanced configuration with Snippets | NGINX Documentation
  2. ConfigMap - Ingress-Nginx Controller - Kubernetes
  3. How to set robots.txt globally in nginx for all virtual hosts - Server Fault
  4. How do i configure nginx to redirect to a url for robots.txt & sitemap.xml - Stack Overflow
  5. S3 proxy on kubernetes using Ingress - Stack Overflow
  6. Annotations - Ingress-Nginx Controller
  7. Kubernetes, nginx-ingress and S3 bucket | liet’s blog
Авторы
Проверено модерацией
Модерация