Передача реального IP-адреса запрашивающего клиента в K3S NGINX Ingress.

Вопрос или проблема

Я настроил окружение K3S Kubernetes в своей частной домашней лаборатории на Raspberry PIs для того, чтобы научиться использовать Kubernetes (новичок), применяя NGINX в качестве контроллера входящего трафика, и я как-то застрял на этапе передачи реального IP запросов в целевые поды, в моем случае — экземпляр Nextcloud. Версия K3S — v1.22.5+k3s1.

K3S был настроен с использованием Docker в качестве среды выполнения контейнеров и с опцией --no-deploy traefik.

После этого я развернул контроллер входящего трафика NGINX, используя

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/baremetal/deploy.yaml

Затем, после развертывания подов Nextcloud, я развернул входящий трафик:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - my.own-dns.org
    secretName: very-secret-ssl-secret
  ingressClassName: nginx
  rules:
  - host: my.own-dns.org
    http:
      paths:
        - path: /somepath
          pathType: Prefix
          backend:
            service:
              name: someservice-service
              port:
                number: 8081
        - path: /
          pathType: Prefix
          backend:
            service:
              name: nextcloud-service
              port:
                number: 80

В развертывании IngressController я добавил следующие записи в ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.10
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  allow-snippet-annotations: 'true'
  compute-full-forwarded-for: 'true'
  use-forwarded-headers: 'true'
  enable-real-ip: 'true'
  proxy-add-original-uri-header: 'true'
  forwarded-for-header: 'X-Forwarded-For'

и изменил ServiceType сервиса http на LoadBalancer, поэтому мой сервис IngressController выглядит так:

apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-4.0.10
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  ipFamilyPolicy: SingleStack
  ipFamilies:
    - IPv4
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
      appProtocol: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
      appProtocol: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

Пока все хорошо, доступ к экземпляру Nextcloud из интернета работает отлично, включая перенаправление на https и т.д. Но в журнале аудита Nextcloud регистрируется только внутренний IP-кластер в качестве IP-источника (удивительно, но это не IP какого-либо сервиса, который я запускаю внутри кластера), а не реальный из внешнего мира.

Что я упускаю? Я пытался установить use-proxy-protocol в true, но это приводит к ERR_CONNECTION_RESET.

Вы пробовали установить spec.externalTrafficPolicy в local? Посмотрите документацию Kubernetes о последствиях.

Ответ или решение

Введение

Ваша задача — настроить корректную передачу реального IP-адреса пользователя через NGINX в Kubernetes-кластере K3S, развернутом в домашней лаборатории на Raspberry Pi. На данный момент ваше приложение Nextcloud получает внутренние кластерационные IP-адреса вместо реального IP-адреса клиента, и вы хотите исправить это. Давайте разберемся, как это сделать.

Теория

Для начала стоит обсудить, почему в вашей конфигурации IP-адреса клиента подменяются на внутренние кластерационные. Это поведение связано с уровнем абстракции и маршрутизации в Kubernetes. Пакеты, поступающие извне, проходят через несколько сетевых слоев, и на их пути становятся NAT’ированными для работы с внутренними резолверами или службами.

Одним из решений этой проблемы является обеспечение правильной работы capture-заголовков, таких как X-Forwarded-For, которые стандартно используются для передачи реальных IP-адресов клиента через прокси. Не менее важным аспектом является настройка параметров, таких как externalTrafficPolicy, который может значительно повлиять на фиксирование реальных пользовательских IP.

Пример

Рассмотрим ваш текущий YAML манифест для NGINX Controller и варианты внесения изменений:

  1. externalTrafficPolicy: Local

    Измените параметр spec.externalTrafficPolicy для вашего Ingress Service на Local. Это установка позволит службам сохранять исходный IP-адрес, поскольку трафик больше не будет проходить через внутренний узел API, который меняет IP на внутренний.

    apiVersion: v1
    kind: Service
    metadata:
     name: ingress-nginx-controller
     namespace: ingress-nginx
    spec:
     type: LoadBalancer
     externalTrafficPolicy: Local
     ports:
       - name: http
         port: 80
         protocol: TCP
         targetPort: http
         appProtocol: http
       - name: https
         port: 443
         protocol: TCP
         targetPort: https
         appProtocol: https
     selector:
       app.kubernetes.io/name: ingress-nginx
       app.kubernetes.io/instance: ingress-nginx
       app.kubernetes.io/component: controller
  2. Проверка заголовков X-Forwarded-For

    Убедитесь, что конфигурация включена для использования правильных заголовков. Ваша конфигурация для use-forwarded-headers и enable-real-ip — это правильный шаг, но также важно, чтобы вы настраивали правильное поведение для Forwarded заголовков.

    Убедитесь, что ваш бэкенд-приложение (Nextcloud) также настроено для чтения и обработки информации X-Forwarded-For.

  3. Прокси-протокол

    Вы упомянули о попытках применения use-proxy-protocol, которые закончились неудачей. Данная функция требует дополнительных настроек и поддержки как со стороны бэкенда, так и со стороны прокси-конфигураций. Если эта функция вам необходима, убедитесь, что вы изменили конфигурацию внешнего балансира нагрузки, чтобы он правильно использовал прокси-протокол.

Применение

  1. Обновите YAML файл вашего сервисного ресурса, используя externalTrafficPolicy: Local, чтобы NGINX начал использовать реальный IP клиента.

  2. Перезапустите или примените обновления к существующему контроллеру Ingress.

  3. Проверьте логи вашего приложения Nextcloud, чтобы убедиться, что они теперь получают реальный IP-адрес клиента.

  4. Если обнаружите, что ваши изменения не приводят к желаемым результатам, рассмотрите возможность использования инструментов сетевой диагностики, таких как kubectl logs, tcpdump для проверки сетевого трафика и заголовков на разных этапах маршрутизации.

Заключение

Правильная настройка заголовков и политика трафика — это важные элементы для корректной работы реального IP-адреса клиента в кластере Kubernetes. Вышеперечисленные рекомендации помогут вам добиться желаемой конфигурации, где приложение Lexcloud сможет правильно идентифицировать IP-адреса. Убедитесь в совместимости всех конфигураций как на уровне инграції, так и на уровне общения между прокси и конечными сервисами.

Оцените материал
Добавить комментарий

Капча загружается...