Compare languages | The ingress-nginx module: FAQ

How do I limit access to the application in the cluster to ingress controllers only?

Как разрешить доступ к приложению внутри кластера только от ingress controller’ов?

Add the kube-rbac-proxy container to the application Pod to allow only ingress Pods to access your application in the cluster:

Если вы хотите ограничить доступ к вашему приложению внутри кластера ТОЛЬКО от подов ingress’а, необходимо в под с приложением добавить контейнер с kube-rbac-proxy:

An example of the corresponding Kubernetes Deployment

Пример Deployment для защищенного приложения

yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: my-namespace spec: selector: matchLabels: app: my-app replicas: 1 template: metadata: labels: app: my-app spec: serviceAccountName: my-sa containers:

  • name: my-cool-app image: mycompany/my-app:v0.5.3 args:
  • ”–listen=127.0.0.1:8080” livenessProbe: httpGet: path: /healthz port: 443 scheme: HTTPS
  • name: kube-rbac-proxy image: flant/kube-rbac-proxy:v0.1.0 # it is recommended to use a proxy from our repository args:
  • ”–secure-listen-address=0.0.0.0:443”
  • ”–config-file=/etc/kube-rbac-proxy/config-file.yaml”
  • ”–v=2”
  • ”–logtostderr=true” The user authentication and authorization are not possible if the kube-apiserver is not available. Stale Cache stores the results of successful authorization and is used only if the apiserver is not available.
  • ”–stale-cache-interval=1h30m” ports:
  • containerPort: 443 name: https volumeMounts:
  • name: kube-rbac-proxy mountPath: /etc/kube-rbac-proxy volumes:
  • name: kube-rbac-proxy configMap: name: kube-rbac-proxy

yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: my-namespace spec: selector: matchLabels: app: my-app replicas: 1 template: metadata: labels: app: my-app spec: serviceAccountName: my-sa containers:

  • name: my-cool-app image: mycompany/my-app:v0.5.3 args:
  • ”–listen=127.0.0.1:8080” livenessProbe: httpGet: path: /healthz port: 443 scheme: HTTPS
  • name: kube-rbac-proxy image: flant/kube-rbac-proxy:v0.1.0 # Рекомендуется использовать прокси из нашего репозитория. args:
  • ”–secure-listen-address=0.0.0.0:443”
  • ”–config-file=/etc/kube-rbac-proxy/config-file.yaml”
  • ”–v=2”
  • ”–logtostderr=true” Если kube-apiserver недоступен, мы не сможем аутентифицировать и авторизовывать пользователей. Stale Cache хранит только результаты успешной авторизации и используется, только если apiserver недоступен.
  • ”–stale-cache-interval=1h30m” ports:
  • containerPort: 443 name: https volumeMounts:
  • name: kube-rbac-proxy mountPath: /etc/kube-rbac-proxy volumes:
  • name: kube-rbac-proxy configMap: name: kube-rbac-proxy

The application only accepts localhost (127.0.0.1) requests. That means that an unsecured connection can only be established to it from within the Pod. At the same time, the proxy listens on 0.0.0.0 and intercepts all external traffic to the Pod.

Приложение принимает запросы на адресе 127.0.0.1, это означает, что по незащищенному соединению к нему можно подключиться только изнутри пода. Прокси же слушает на адресе 0.0.0.0 и перехватывает весь внешний трафик к поду.

How do I provide minimum rights to the Service Account?

Как дать минимальные права для Service Account?

The proxy needs permissions to create TokenReview and SubjectAccessReview to authenticate and authorize users using the kube-apiserver.

Чтобы аутентифицировать и авторизовывать пользователей с помощью kube-apiserver, у прокси должны быть права на создание TokenReview и SubjectAccessReview.

Our clusters have a built-in ClusterRole called d8-rbac-proxy that is ideal for this kind of situation. You don’t need to create it yourself! Just attach it to the ServiceAccount of your Deployment.

В наших кластерах уже есть готовая ClusterRoled8-rbac-proxy. Создавать ее самостоятельно не нужно! Нужно только прикрепить ее к Service Account’у вашего Deployment’а.

yaml

apiVersion: v1 kind: ServiceAccount metadata: name: my-sa namespace: my-namespace — apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: my-namespace:my-sa:d8-rbac-proxy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: d8:rbac-proxy subjects:

  • kind: ServiceAccount name: my-sa namespace: my-namespace

yaml

apiVersion: v1 kind: ServiceAccount metadata: name: my-sa namespace: my-namespace — apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: my-namespace:my-sa:d8-rbac-proxy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: d8:rbac-proxy subjects:

  • kind: ServiceAccount name: my-sa namespace: my-namespace

The Kube-RBAC-Proxy configuration

Конфигурация Kube-RBAC-Proxy

yaml apiVersion: v1 kind: ConfigMap metadata: name: kube-rbac-proxy data: config-file.yaml: |+ excludePaths:

  • /healthz # no authorization for liveness probes is required upstreams:
  • upstream: http://127.0.0.1:8081/ # the destination address path: / # the path to the proxy to forward requests to the upstream authorization: resourceAttributes: namespace: my-namespace apiGroup: apps apiVersion: v1 resource: deployments subresource: http name: my-app

yaml apiVersion: v1 kind: ConfigMap metadata: name: kube-rbac-proxy data: config-file.yaml: |+ excludePaths:

  • /healthz # Не требуем авторизацию для liveness пробы. upstreams:
  • upstream: http://127.0.0.1:8081/ # Куда проксируем. path: / # Location прокси, с которого запросы будут проксированы на upstream. authorization: resourceAttributes: namespace: my-namespace apiGroup: apps apiVersion: v1 resource: deployments subresource: http name: my-app

According to the configuration, the user must have access to the my-app Deployment and its http subresource in the my-namespace namespace.

Согласно конфигурации, у пользователя должны быть права на доступ к Deployment с именем my-app и его дополнительному ресурсу http в namespace my-namespace.

Such permissions have the following RBAC form:

Выглядят такие права в виде RBAC так:

yaml

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kube-rbac-proxy:my-app namespace: my-namespace rules:

  • apiGroups: [“apps”] resources: [“deployments/http”] resourceNames: [“my-app”] verbs: [“get”, “create”, “update”, “patch”, “delete”] — apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kube-rbac-proxy:my-app namespace: my-namespace roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kube-rbac-proxy:my-app subjects:

yaml

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kube-rbac-proxy:my-app namespace: my-namespace rules:

  • apiGroups: [“apps”] resources: [“deployments/http”] resourceNames: [“my-app”] verbs: [“get”, “create”, “update”, “patch”, “delete”] — apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kube-rbac-proxy:my-app namespace: my-namespace roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kube-rbac-proxy:my-app subjects:

All user certificates of ingress-controllers are issued for one specific group

  • kind: Group name: ingress-nginx:auth

Все пользовательские сертификаты ingress-контроллеров выписаны для одной конкретной группы.

  • kind: Group name: ingress-nginx:auth

You also need to add the following parameters to the ingress of the resource:

Для ingress’а ресурса необходимо добавить параметры:

yaml nginx.ingress.kubernetes.io/backend-protocol: HTTPS nginx.ingress.kubernetes.io/configuration-snippet: | proxy_ssl_certificate /etc/nginx/ssl/client.crt; proxy_ssl_certificate_key /etc/nginx/ssl/client.key; proxy_ssl_protocols TLSv1.2; proxy_ssl_session_reuse on;

yaml nginx.ingress.kubernetes.io/backend-protocol: HTTPS nginx.ingress.kubernetes.io/configuration-snippet: | proxy_ssl_certificate /etc/nginx/ssl/client.crt; proxy_ssl_certificate_key /etc/nginx/ssl/client.key; proxy_ssl_protocols TLSv1.2; proxy_ssl_session_reuse on;

Here you can read more about how certificate authentication works.

Подробнее о том, как работает аутентификация по сертификатам, можно прочитать в документации Kubernetes.

How do I configure an external load balancer to check if IngressNginxController is available?

Как сконфигурировать балансировщик нагрузки для проверки доступности IngressNginxController?

In case an IngressNginxController is deployed behind a load balancer, it is advisable to configure your load balancer so that it would check the availability of the IngressNginxController’s endpoints via a health check mechanism, periodically sending either HTTP-requests or TCP-packets. While it is possible to test the endpoints simply by checking if a relevant TCP port is open, we recommend implementing HTTP checks with the following parameters:

  • Protocol: HTTP
  • Path: /healthz
  • Port: 80 (or relevant httpPort value in case of using HostPort inlet).

В ситуации, когда IngressNginxController размещен за балансировщиком нагрузки, рекомендуется сконфигурировать балансировщик для проверки доступности узлов IngressNginxController с помощью HTTP-запросов или TCP-подключений. В то время как тестирование с помощью TCP-подключений представляет собой простой и универсальный механизм проверки доступности, мы рекомендуем использовать проверку на основе HTTP-запросов со следующими параметрами:

  • протокол: HTTP;
  • путь: /healthz;
  • порт: 80 (в случае использования инлета HostPort нужно указать номер порта, соответствующий параметру httpPort.

How do I configure MetalLB to be accessible from the internal network only?

Как настроить работу через MetalLB с доступом только из внутренней сети?

Below is an example of a MetalLB config with access from the internal network only.

Пример MetalLB с доступом только из внутренней сети.

yaml apiVersion: deckhouse.io/v1 kind: IngressNginxController metadata: name: main spec: ingressClass: “nginx” inlet: “LoadBalancer” loadBalancer: sourceRanges:

  • 192.168.0.0/24

yaml apiVersion: deckhouse.io/v1 kind: IngressNginxController metadata: name: main spec: ingressClass: “nginx” inlet: “LoadBalancer” loadBalancer: sourceRanges:

  • 192.168.0.0/24

The svcSourceRangeCheck parameter should be enabled in cni-cilium module for correct work.

Для работы необходимо включить параметр svcSourceRangeCheck в модуле cni-cilium.

How to add extra log fields to a nginx-controller?

Как добавить дополнительные поля для логирования в nginx-controller?

yaml apiVersion: deckhouse.io/v1 kind: IngressNginxController metadata: name: main spec: ingressClass: “nginx” inlet: “LoadBalancer” additionalLogFields: my-cookie: “$cookie_MY_COOKIE”

yaml apiVersion: deckhouse.io/v1 kind: IngressNginxController metadata: name: main spec: ingressClass: “nginx” inlet: “LoadBalancer” additionalLogFields: my-cookie: “$cookie_MY_COOKIE”

How to enable HorizontalPodAutoscaling for IngressNginxController?

Как включить HorizontalPodAutoscaling для IngressNginxController?

Note. HPA mode is possible only for controllers with inlet: LoadBalancer or LoadBalancerWithProxyProtocol.

Note. HPA mode is possible only for minReplicas != maxReplicas otherwise deployment hpa-scaler will not be created.

Режим HPA возможен только для контроллеров с инлетом LoadBalancer или LoadBalancerWithProxyProtocol.

HPA is set with attributes minReplicas and maxReplicas in a IngressNginxController CR.

Режим HPA возможен только при minReplicas != maxReplicas, в противном случае deployment hpa-scaler не создается.

The IngressNginxController is deployed using DaemonSet. DaemonSet does not provide horizontal scaling capabilities, so hpa-scaler Deployment will be created with the HPA resource, which is observing custom metric prometheus-metrics-adapter-d8-ingress-nginx-cpu-utilization-for-hpa. If CPU utilization exceeds 50%, the HPA-controller scales hpa-scaler Deployment with a new replica (with respect to minReplicas and maxReplicas).

HPA выставляется с помощью аттрибутов minReplicas и maxReplicas в IngressNginxController CR.

hpa-scaler Deployment has HardPodAntiAffinity, and it will order a new Node (inside its NodeGroup), where one more ingress-controller will be set.

IngressNginxController разворачивается с помощью DaemonSet. DaemonSet не предоставляет возможности горизонтального масштабирования, поэтому создается дополнительный deployment hpa-scaler и HPA resource, который следит за предварительно созданной метрикой prometheus-metrics-adapter-d8-ingress-nginx-cpu-utilization-for-hpa. Если CPU utilization превысит 50%, HPA закажет новую реплику для hpa-scaler (с учетом minReplicas и maxReplicas).

Notes:

  • The minimum actual number of ingressNginxController replicas cannot be less than the minimum number of nodes in the NodeGroup where ingressNginxController is deployed.
  • The maximum actual number of ingressNginxController replicas cannot be greater than the maximum number of nodes in the NodeGroup where ingressNginxController is deployed.

hpa-scaler deployment обладает HardPodAntiAffinity, поэтому он попытается заказать себе новый узел (если это возможно в рамках своей NodeGroup), куда автоматически будет размещен еще один Ingress-контроллер.

How to use IngressClass with IngressClassParameters?

Примечания:

  • Минимальное реальное количество реплик IngressNginxController не может быть меньше минимального количества узлов в NodeGroup, в которую разворачивается IngressNginxController.
  • Максимальное реальное количество реплик IngressNginxController не может быть больше максимального количества узлов в NodeGroup, в которую разворачивается IngressNginxController.

Since version 1.1 IngressNginxController Deckhouse creates an IngressClass object. If you want to use your own IngressClass with your customized IngressClassParameters, you need to add the label ingress-class.deckhouse.io/external: "true"

Как использовать IngressClass с установленными IngressClassParameters?

yaml apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: labels: ingress-class.deckhouse.io/external: “true” name: my-super-ingress spec: controller: ingress-nginx.deckhouse.io/my-super-ingress parameters: apiGroup: elbv2.k8s.aws kind: IngressClassParams name: awesome-class-cfg

Начиная с версии 1.1 IngressNginxController, Deckhouse создает объект IngressClass самостоятельно. Если вы хотите использовать свой IngressClass, например с установленными IngressClassParameters, достаточно добавить к нему label ingress-class.deckhouse.io/external: "true"

In this case Deckhouse will not create an IngressClass object and will use your own.

yaml apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: labels: ingress-class.deckhouse.io/external: “true” name: my-super-ingress spec: controller: ingress-nginx.deckhouse.io/my-super-ingress parameters: apiGroup: elbv2.k8s.aws kind: IngressClassParams name: awesome-class-cfg

How to disable the collection of detailed Ingress resources statistics?

В таком случае, при указании данного IngressClass в CRD IngressNginxController, Deckhouse не будет создавать объект, а использует уже существующий.

By default, Deckhouse collects detailed statistics from all Ingress resources in the cluster. This behavior may generate high load on the monitoring system.

Как отключить сборку детализированной статистики Ingress-ресурсов?

To disable statistics collection, add label ingress.deckhouse.io/discard-metrics: "true" to the corresponding Namespace or Ingress resource.

По умолчанию Deckhouse собирает подробную статистику со всех Ingress-ресурсов в кластере, что может генерировать высокую нагрузку на систему мониторинга.

Example of disabling statistics (metrics) collection for all Ingress resources in the review-1 namespace:

Для отключения сбора статистики добавьте label ingress.deckhouse.io/discard-metrics: "true" к соответствующему namespace или Ingress-ресурсу.

shell kubectl label ns review-1 ingress.deckhouse.io/discard-metrics=true

Пример отключения сбора статистики (метрик) для всех Ingress-ресурсов в пространстве имен review-1:

Example of disabling statistics (metrics) collection for all test-site Ingress resources in the development namespace:

shell kubectl label ns review-1 ingress.deckhouse.io/discard-metrics=true

shell kubectl label ingress test-site -n development ingress.deckhouse.io/discard-metrics=true

Пример отключения сбора статистики (метрик) для всех Ingress-ресурсов test-site в пространстве имен development:

How do I correctly drain a node running an IngressNginxController’s pods?

shell kubectl label ingress test-site -n development ingress.deckhouse.io/discard-metrics=true

There are two ways of draining such a node correctly - either by annotating the node (the annotation will be deleted once the node is drained):

Как корректно вывести из эксплуатации (drain) узел с запущенным IngressNginxController?

shell kubectl annotate node update.node.deckhouse.io/draining=user

Доступно два способа вывода такого узла из эксплуатации - или с помощью аннотации узла (аннотация будет удалена после завершения операции):

or by using kubectl drain functionality (it’s worth mentioning that –force flag is required despite having –ignore-daemonsets flag set, as IngressNginxControllers are backed by Advanced DaemonSets):

shell kubectl annotate node update.node.deckhouse.io/draining=user

shell kubectl drain --delete-emptydir-data --ignore-daemonsets --force

или с помощью базового функционала kubectl drain (тут стоит отметить, что необходимо указать флаг –force, несмотря на то, что указан флаг –ignore-daemonsets, так как IngressNginxController разворачивается с помощью Advanced DaemonSet):

 

shell kubectl drain --delete-emptydir-data --ignore-daemonsets --force