Перейти к содержанию

Обновление Ingress‑контроллера NGINX с сервисами Валарм

Инструкция описывает способ обновления Ingress‑контроллера Валарм версии 3.4 или 3.2 до новой версии с нодой 3.6.

Новая версия Community Ingress-контроллера NGINX

В новом релизе изменилась версия Community Ingress-контроллера NGINX, на котором основан Ingress-контроллер Валарм. Ранее использовалась версия 0.26.2, теперь — 1.1.3.

В связи с этим при обновлении Ingress-контроллера Валарм потребуется изменить не только настройки Валарм, но и стандартные настройки Ingress-контроллера.

В этой инструкции мы привели набор настроек Ingress-контроллера, которые потенциально потребуется изменить. Однако мы рекомендуем подготовить индивидуальный план обновления, опираясь на список изменений в Ingress-контроллере NGINX.

Для обновления Ingress‑контроллера версии 2.18 и ниже используйте отдельную инструкцию.

Шаг 1: Обновите репозиторий с Helm‑чартами Валарм

helm repo update wallarm

Добавьте репозиторий Helm со всеми версиями чартов, используя команду ниже. В дальнейшем рекомендуется использовать репозиторий Helm.

helm repo add wallarm https://charts.wallarm.com
helm repo update wallarm

Шаг 2: Внесите необходимые изменения в values.yaml

Для миграции на новую версию Ingress-контроллера Валарм, необходимо обновить содержимое текущего файла values.yaml в соответствии с изменениями в новой версии контроллера. Изменения делятся на 2 группы:

  • Стандартная конфигурация Community Ingress-контроллера NGINX

  • Конфигурация модулей Валарм

Стандартная конфигурация Community Ingress-контроллера NGINX

  1. Внимательно изучите список изменений в Ingress-контроллере NGINX версии выше 0.26.2 и определите, какие настройки вам потребуется изменить.

  2. Обновите конфигурацию в файле values.yaml в соответствии с изменениями в работе Ingress-контроллера NGINX.

Потенциальные изменения конфигурации:

  • Идентификация реального IP‑адреса клиента, если для направления внешнего трафика на Ingress‑контроллер используется балансировщик нагрузки:

    controller:
      config:
    -    use-forwarded-headers: "true"
    +    enable-real-ip: "true"
    +    forwarded-for-header: "X-Forwarded-For"
    
  • Конфигурация IngressClasses. В новой версии Ingress-контроллера используется новая версия Kubernetes API, в которой IngressClasses настраиваются с помощью параметров .controller.ingressClass, .controller.ingressClassResource и .controller.watchIngressWithoutClass.

    controller:
    +  ingressClass: waf-ingress
    +  ingressClassResource:
    +    name: waf-ingress
    +    default: true
    +  watchIngressWithoutClass: true
    
  • Набор параметров в ConfigMap (.controller.config), например:

    controller:
    config:
    +  allow-backend-server-header: "false"
      enable-brotli: "true"
      gzip-level: "3"
      hide-headers: Server
      server-snippet: |
        proxy_request_buffering on;
        wallarm_enable_libdetection on;
    
  • Валидация синтаксиса Ingress с помощью "admission webhook" теперь включена по умолчанию.

    controller:
    +  admissionWebhooks:
    +    enabled: true
    

    Отключение валидации синтаксиса Ingress

    Мы не рекомендуем отключать валидацию синтаксиса Ingress с помощью "admission webhook" без необходимости.

    Однако в некоторых случаях валидация может работать нестабильно, например, при использовании нескольких Ingress-контроллеров. Если при создании Ingress-объектов вы столкнулись с проблемами из-за валидации синтаксиса, отключите ее.

  • Новый формат меток. Если в values.yaml заданы affinity-правила для распределения подов по кластеру, необходимо изменить в них формат меток. Например:

    controller:
      affinity:
        podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - podAffinityTerm:
            labelSelector:
                matchExpressions:
    -            - key: app
    +            - key: app.kubernetes.io/name
                operator: In
                values:
                - waf-ingress
    -            - key: component
    +            - key: app.kubernetes.io/component
                operator: In
                values:
    -              - waf-ingress
    +              - controller
    -            - key: release
    +            - key: app.kubernetes.io/instance
                operator: In
                values:
                - waf-ingress-ingress
            topologyKey: kubernetes.io/hostname
            weight: 100
    

Конфигурация модулей Валарм

Измените конфигурацию модулей Валарм в файле values.yaml следующим образом:

  • Удалите явную конфигурацию сервиса метрик. Теперь сервис метрик включен по умолчанию, отдельная настройка не требуется.

    controller:
    wallarm:
      enabled: true
      tarantool:
        resources: {}
    -  metrics:
    -    enabled: true
    -    service:
    -      annotations: {}
    
  • Если вы используете страницу блокировки Валарм и ее настройки заданы через ConfigMap, обновите ее настройку по инструкции.

    В новой версии ноды изменился пример страницы блокировки Валарм, &/usr/share/nginx/html/wallarm_blocked.html. Теперь на странице по умолчанию не заданы логотип и почта.

Шаг 3: Проверьте все предстоящие изменения в манифестах Kubernetes

Чтобы избежать непредвиденных изменений в работе Ingress‑контроллера после обновления, проверьте все предстоящие изменения в манифестах Kubernetes.

Для этого мы рекомендуем использовать плагин Helm Diff Plugin. Плагин выведет разницу между манифестами Kubernetes в установленной версии контроллера и новой.

Чтобы установить и запустить плагин:

  1. Установите плагин:

    helm plugin install https://github.com/databus23/helm-diff
    
  2. Запустите плагин:

    helm diff upgrade <RELEASE_NAME> -n <NAMESPACE> wallarm/wallarm-ingress --version 3.6.9 -f <PATH_TO_VALUES>
    
    • <RELEASE_NAME>: название релиза с активным Ingress‑контроллером
    • <NAMESPACE>: пространство имен, в котором развернут Ingress‑контроллер
    • <PATH_TO_VALUES>: путь до файла values.yaml с настройками для Ingress‑контроллера 3.6
  3. Убедитесь, что никакие изменения не повлияют на стабильность запущенных сервисов, и внимательно изучите ошибки из stdout.

    Если stdout команды пустой, убедитесь в валидности values.yaml.

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

  • Immutable-параметры. Например, селекторы для Deployment и/или StatefulSet.

  • Метки подов. Изменения могут привести к прекращению работы сетевых политик (NetworkPolicy). Например:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    spec:
      egress:
      - to:
        - namespaceSelector:
            matchExpressions:
            - key: name
              operator: In
              values:
              - kube-system # ${NAMESPACE}
          podSelector:
            matchLabels: # RELEASE_NAME=waf-ingress
    -         app: waf-ingress
    +         app.kubernetes.io/component: "controller"
    +         app.kubernetes.io/instance: "waf-ingress"
    +         app.kubernetes.io/name: "waf-ingress"
    -         component: waf-ingress
    
  • Конфигурацию Prometheus с обновленными метками, например:

     - job_name: 'kubernetes-ingress'
       kubernetes_sd_configs:
       - role: pod
         namespaces:
           names:
             - kube-system # ${NAMESPACE}
       relabel_configs: # RELEASE_NAME=waf-ingress
         # Selectors
    -    - source_labels: [__meta_kubernetes_pod_label_app]
    +    - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
           action: keep
           regex: waf-ingress
    -    - source_labels: [__meta_kubernetes_pod_label_release]
    +    - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
           action: keep
           regex: waf-ingress
    -    - source_labels: [__meta_kubernetes_pod_label_component]
    +    - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
           action: keep
    -      regex: waf-ingress
    +      regex: controller
         - source_labels: [__meta_kubernetes_pod_container_port_number]
           action: keep
           regex: "10254|18080"
           # Replacers
         - action: replace
           target_label: __metrics_path__
           regex: /metrics
         - action: labelmap
           regex: __meta_kubernetes_pod_label_(.+)
         - source_labels: [__meta_kubernetes_namespace]
           action: replace
           target_label: kubernetes_namespace
         - source_labels: [__meta_kubernetes_pod_name]
           action: replace
           target_label: kubernetes_pod_name
         - source_labels: [__meta_kubernetes_pod_name]
           regex: (.*)
           action: replace
           target_label: instance
           replacement: "$1"
    
  • Проанализируйте все остальные изменения.

Шаг 4: Обновите Ingress-контроллер

Вы можете обновить Ingress‑контроллер одним из трех способов. Выбор зависит от того, используется ли в вашей инфраструктуре балансировщик нагрузки. Возможны следующие способы обновления:

  • Установка временного Ingress‑контроллера

  • Обычное пересоздание релиза Ingress‑контроллера

  • Пересоздание релиза Ingress‑контроллера с сохранением балансировщика нагрузки

Использование staging‑среды и minikube

Если вы используете Ingress‑контроллер Валарм на staging‑среде, рекомендуем сначала обновить его. Убедитесь, что все сервисы работают корректно, и повторите обновление в боевой среде.

В остальных случаях рекомендуем развернуть Ingress‑контроллер 3.6 с обновленной конфигурацией с помощью minikube или другого сервиса. Убедитесь, что все сервисы работают ожидаемо и обновите Ingress‑контроллер в боевой среде.

Такой подход позволит избежать ошибок и деградации сервисов в боевой среде.

Способ 1: Установка временного Ingress‑контроллера

Вы можете развернуть Ingress‑контроллер 3.6 как дополнительную сущность в инфраструктуре и переключать на нее трафик постепенно. Это позволит избежать даже временной деградации сервисов и обеспечит безопасную миграцию.

  1. Скопируйте конфигурацию IngressClass из values.yaml Ingress‑контроллера предыдущей версии в values.yaml для Ingress‑контроллера 3.6.

    Таким образом новый Ingress‑контроллер идентифицирует объекты Ingress, а трафик на новый Ingress‑контроллер поступать не будет.

  2. Установите Ingress‑контроллер 3.6:

    helm install <RELEASE_NAME> -n <NAMESPACE> wallarm/wallarm-ingress --version 3.6.9 -f <PATH_TO_VALUES>
    
    • <RELEASE_NAME>: название релиза с Ingress‑контроллером 3.6, отличное от релиз с Ingress‑контроллером предыдущей версии.
    • <NAMESPACE>: пространство имен, в котором развернут Ingress‑контроллер предыдущей версии.
    • <PATH_TO_VALUES>: путь до файла values.yaml с настройками для Ingress‑контроллера 3.6 и настройкой IngressClass из пункта 1.
  3. Убедитесь, что все сервисы работают корректно.

  4. Постепенно переключите нагрузку на новый Ingress‑контроллер.

Способ 2: Обычное пересоздание релиза Ingress‑контроллера

Если балансировщик нагрузки и Ingress‑контроллер НЕ описаны в одном Helm‑чарте, для обновления достаточно пересоздать Helm‑релиз. Пересоздание релиза займет несколько минут, Ingress‑контроллер будет недоступен это время.

Если Helm‑чарт описывает и балансировку нагрузки

Если Helm‑чарт описывает и балансировку нагрузки, при пересоздании релиза облачный провайдер может непредсказуемо долго пересоздавать балансировщик нагрузки. Также, если балансировщику нагрузки не присвоен статичный IP‑адрес, адрес может измениться.

При использовании этого метода обновления рекомендуем внимательно изучить риски.

Для пересоздания релиза Ingress‑контроллера:

  1. Удалите предыдущий релиз:

    helm delete <RELEASE_NAME> -n <NAMESPACE>
    
    • <RELEASE_NAME>: название релиза с Ingress‑контроллером предыдущей версии

    • <NAMESPACE>: пространство имен, в котором развернут Ingress‑контроллер предыдущей версии

    Не рекомендуется использовать опцию --wait при выполнении команды, чтобы снизить время обновления.

  2. Создайте новый релиз с Ingress‑контроллером 3.6:

    helm install <RELEASE_NAME> -n <NAMESPACE> wallarm/wallarm-ingress --version 3.6.9 -f <PATH_TO_VALUES>
    
    • <RELEASE_NAME>: название релиза с Ingress‑контроллером 3.6

    • <NAMESPACE>: пространство имен, в котором необходимо развернуть Ingress‑контроллер

    • <PATH_TO_VALUES>: путь до файла values.yaml с настройками для Ingress‑контроллера 3.6

  1. Задайте параметр wait = false в конфигурации Terraform, чтобы снизить время обновления:

    resource "helm_release" "release" {
      ...
    
    + wait = false
    
      ...
    }
    
  2. Удалите предыдущий релиз:

    terraform taint helm_release.release
    
  3. Создайте новый релиз с Ingress‑контроллером 3.6:

    terraform apply -target=helm_release.release
    

Способ 3: Пересоздание релиза Ingress‑контроллера с сохранением балансировщика нагрузки

Рекомендуем обновить модули этим способом, если вы используете балансировщик нагрузки, настроенный облачным провайдером. Этот способ не затрагивает обновление балансировщика нагрузки. Пересоздание релиза займет несколько минут, Ingress‑контроллер будет недоступен это время.

  1. Получите список объектов, которые будут удалены (за исключением балансировщика нагрузки):

    helm get manifest <RELEASE_NAME> -n <NAMESPACE> | yq -r '. | select(.spec.type != "LoadBalancer") | .kind + "/" + .metadata.name' | tr 'A-Z' 'a-z' > objects-to-remove.txt
    

    Если утилита yq еще не установлена, установите ее по инструкции.

    Список объектов для удаления будет выведен в файл objects-to-remove.txt.

  2. Удалите полученные объекты и обновите релиз:

    cat objects-to-remove.txt | xargs kubectl delete --wait=false -n <NAMESPACE>    && \
    helm upgrade <RELEASE_NAME> -n <NAMESPACE> wallarm/wallarm-ingress --version 3.6.9 -f `<PATH_TO_VALUES>`
    

    Не рекомендуется выполнять команды по отдельности, чтобы минимизировать время деградации сервисов.

  3. Убедитесь, что все объекты созданы:

    helm get manifest <RELEASE_NAME> -n <NAMESPACE> | kubectl create -f -
    

    Выводом команды должно быть сообщение о том, что все объекты уже существуют.

В командах передаются следующие параметры:

Шаг 5: Протестируйте обновление

  1. Убедитесь, что чарт обновлен:

    helm ls
    

    Версия чарта должна соответствовать wallarm-ingress-3.6.9.

  2. Получите список pod'ов, передав в <INGRESS_CONTROLLER_NAME> название Ingress‑контроллера Валарм:

    kubectl get pods -l release=<INGRESS_CONTROLLER_NAME>
    

    Все pod'ы должны быть в состоянии: STATUS: Running и READY: N/N. Например:

    NAME                                                              READY     STATUS    RESTARTS   AGE
    ingress-controller-nginx-ingress-controller-675c68d46d-cfck8      3/3       Running   0          5m
    ingress-controller-nginx-ingress-controller-wallarm-tarantljj8g   8/8       Running   0          5m
    ingress-controller-nginx-ingress-default-backend-584ffc6c7xj5xx   1/1       Running   0          5m
    
  3. Отправьте тестовый запрос с атаками SQLI и XSS на адрес Ingress‑контроллера Валарм:

    curl http://<INGRESS_CONTROLLER_IP>/?id='or+1=1--a-<script>prompt(1)</script>'
    

    Если нода находится в статусе block, в ответ на запрос вернется код 403 Forbidden и атаки отобразятся в Консоли управления Валарм → секция События.

Шаг 6: Измените аннотации Ingress в соответствии с обновлениями в версии 3.6

Адаптируйте следующие аннотации Ingress под изменения в версии 3.6:

  1. Если вы используете аннотацию Ingress nginx.ingress.kubernetes.io/wallarm-instance, переименуйте ее в nginx.ingress.kubernetes.io/wallarm-application.

    В новой версии изменилось название аннотации. Аннотация с устаревшим названием временно поддерживается, но в будущих релизах ее поддержка прекратится полностью. Логика аннотации не изменилась.

  2. Если вы используете страницу блокировки Валарм и ее настройки заданы через аннотации Ingress, обновите их в соответствии с инструкцией.

    В новой версии ноды изменилась страница блокировки Валарм, &/usr/share/nginx/html/wallarm_blocked.html. Теперь на странице по умолчанию не заданы логотип и почта.

К началу