Ingress-nginx#

Важно

В разделе приведены функциональные отличия от оригинального опционального компонента Ingress-nginx. Данная версия Ingress-nginx используется только в компоненте Utilities (K8SU). Руководство по настройке и установке, а так же подробная информация по опциональному компоненту Ingress-nginx представлена в документации на компонент K8S Core (K8SC) в документе «Руководство по системному администрированию» -> «Сценарии администрирования» -> «Сценарии использования опциональных компонентов DropApp» -> «Ingress-nginx».

Предварительные условия#

Для выполнения дальнейших шагов установите Ingress-nginx. Информация об установке Ingress-nginx представлена в документации на компонент K8S Core (K8SC) в документе «Руководство по системному администрированию» -> «Сценарии администрирования» -> «Сценарии использования опциональных компонентов DropApp» -> «Ingress-nginx»

Время ожидания TCP-соединения#

За время ожидания TCP-соединения отвечает параметр tcp_keepalive_time. По умолчанию время ожидания составляет 30 секунд.

Для изменения параметра tcp_keepalive_time необходимо отредактировать существующий deployment ingress-nginx-controller:

  1. В терминале выполните команду:

    kubectl edit deployment ingress-nginx-deployment -n ingress-nginx
    

    Команда активирует режим редактирования существующего deployment ingress-nginx-controller.

  2. Найдите список env контейнера controller и добавьте в него новую переменную окружения с именем TCP_KEEPALIVE_TIME и желаемым значением:

    env:
    - name: TCP_KEEPALIVE_TIME
    value: 60
    

Передача IP-адреса АРМ пользователя приложению в DropApp#

Ingress-nginx реализует техническую функциональность передачи IP-адреса АРМ пользователя приложению в DropApp и поддерживает аннотации proxy-protocol в соответствующем проекте nginx-test-proxy-ssl.yaml, что позволяет контроллеру отправлять заголовок proxy-protocol с SSL passthrough-соединениями. Это достигается путем добавления нового инструмента анализа аннотаций, обновления структур данных и функций для обработки нового поля proxy-protocol.

Примечание

Proxy Protocol — это протокол, который позволяет передавать информацию о клиентском IP-адресе и порте через прокси-серверы или балансировщики нагрузки. Когда Proxy Protocol включён, балансировщик нагрузки или прокси-сервер добавляет заголовок Proxy Protocol к каждому запросу, который содержит исходный IP-адрес клиента. Ingress-nginx, настроенный на использование Proxy Protocol, может прочитать этот заголовок и использовать его для логирования или других целей, связанных с исходным IP-адресом клиента.

Настройка proxy-protocol Ingress-nginx#

После развертывания кластера и установки Ingress-nginx выполните следующие шаги:

  1. Подготовьте файл манифеста proxy-protocol для проверки nginx-test-proxy-ssl.yaml:

    nginx-test-proxy-ssl.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-conf
    data:
      nginx.conf: |
        user nginx;
        worker_processes  3;
        error_log  /dev/stdout debug;
        events {
          worker_connections  10240;
        }
        http {
          log_format  main
                  'remote_addr:$remote_addr\t'
                  'proxy_protocol:$proxy_protocol_addr\t'
                  'remote_user:$remote_user\t'
                  'time_local:$time_local\t'
                  'method:$request_method\t'
                  'uri:$request_uri\t'
                  'host:$host\t'
                  'status:$status\t'
                  'bytes_sent:$body_bytes_sent\t'
                  'referer:$http_referer\t'
                  'useragent:$http_user_agent\t'
                  'forwardedfor:$http_x_forwarded_for\t'
                  'request_time:$request_time';
          access_log /dev/stdout main;
          server {
              ssl_certificate /etc/cluster-tls/tls.crt;
              ssl_certificate_key /etc/cluster-tls/tls.key;
              listen       443 ssl proxy_protocol;
              real_ip_header proxy_protocol;
              set_real_ip_from 0.0.0.0/0;
              server_name  _;
              location / {
                  root   html;
                  index  index.html index.htm;
              }
          }
        }
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 443
            volumeMounts:
            - mountPath: /etc/nginx # mount nginx-conf volumn to /etc/nginx
              readOnly: true
              name: nginx-conf
            - mountPath: /var/log/nginx
              name: log
            - name: cluster-tls
              readOnly: true
              mountPath: /etc/cluster-tls
            # Для получения tcpdump
            securityContext:
              capabilities:
                add:
                  - NET_ADMIN
                  - NET_RAW
                  - SYS_TIME
              privileged: true
          volumes:
          - name: nginx-conf
            configMap:
              name: nginx-conf # place ConfigMap `nginx-conf` on /etc/nginx
              items:
                - key: nginx.conf
                  path: nginx.conf
          - name: log
            emptyDir: {}
          - name: cluster-tls
            secret:
              secretName: cluster-tls
              defaultMode: 420
     
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      type: ClusterIP
      ports:
      - port: 443
        targetPort: 443
      selector:
        app: nginx
    ---
    kind: Ingress
    apiVersion: networking.k8s.io/v1
    metadata:
      name: nginx-ingress
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/proxy-protocol: 'true'
        nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
    spec:
      ingressClassName: nginx
      tls:
        - hosts:
            - app.dapp.qa
      rules:
        - host: app.dapp.qa
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: nginx
                    port:
                      number: 443
    
  2. Убедитесь, что в nginx-test-proxy-ssl.yaml присутствуют параметры listen 443 ssl proxy_protocol, real_ip_header proxy_protocol и set_real_ip_from 0.0.0.0/0 в разделе server:

    server {
        ssl_certificate /etc/cluster-tls/tls.crt;
        ssl_certificate_key /etc/cluster-tls/tls.key;
        listen       443 ssl proxy_protocol;
        real_ip_header proxy_protocol;
        set_real_ip_from 0.0.0.0/0;
        server_name  _;
        location / {
            root   html;
            index  index.html index.htm;
        }
    
  3. Убедитесь, что в nginx-test-proxy-ssl.yaml присутствуют аннотации nginx.ingress.kubernetes.io/proxy-protocol: 'true' и nginx.ingress.kubernetes.io/ssl-passthrough: 'true':

    ---
    kind: Ingress
    apiVersion: networking.k8s.io/v1
    metadata:
      name: nginx-ingress
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/proxy-protocol: 'true'
        nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
    
  4. Примените манифест:

    kubectl apply -f nginx-test-proxy-ssl.yaml
    
  5. Проверьте статус запущенного pod:

    kubectl rollout status deployment.apps/nginx
    

    Пример вывода:

    kubectl logs nginx-778bf7df4f-psfr4
    ...
    remote_addr:0.0.0.1    proxy_protocol:0.0.0.2 remote_user:-   time_local:22/May/2024:14:55:38 +0000   method:GET  uri:/   host:app.dapp.qa    status:404  bytes_sent:555  referer:-      useragent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/0.0.0.0 Safari/537.36 forwardedfor:-  request_time:0.000
    
  6. Зайдите в pod:

    kubectl exec -it nginx-778bf7df4f-psfr4 -- bash
    
  7. Установите tcpdump внутри pod:

    apt-get update
    apt-get install -y tcpdump
    
  8. Внутри pod включите tcpdump, чтобы с его помощью прослушивать 443-й порт для получения пакетов:

    tcpdump -nn -vv port 443 -A
    
  9. Для проверки в браузере пройдите по адресу https://app.dapp.qa и проанализируйте вывод tcpdump. В выводе должны присутствовать пакеты, например:

    ...
        0.0.0.0.56236 > 0.0.0.0.443: Flags [P.], cksum 0xe7a5 (correct), seq 1:49, ack    1, win 221, options [nop,nop,TS val 2385962799 ecr 1983780703], length 48
    E..d..@.?.+P
    ...
    ...........<..............
    .6./v>._PROXY TCP4 0.0.0.0 0.0.0.1 58611 443
    ...
    ..........?<......E.......
    .6.mv>.s
    ^C
    20 packets captured
    20 packets received by filter
    0 packets dropped by kernel
    

    Запись, отвечающая за получение на правильном порту: .6./v>._PROXY TCP4 0.0.0.0 0.0.0.1 58611 443.