Ingress-nginx#
Ingress-nginx - часть DropApp, которая отвечает за управление сетевым трафиком в кластере. Осуществляет доступ к сервисам и приложениям, используя правила маршрутизации с помощью HTTP, HTTPS, DNS и других протоколов.
Ingress-nginx-controller предоставляет гибкие механизмы для управления конфигурацией маршрутизации сетевых запросов. Позволяет администраторам настраивать и конфигурировать сервисы и приложения, обеспечивая прозрачное балансирование нагрузки и управление трафиком. Это способствует повышению отказоустойчивости и эффективности работы приложений.
Ingress-nginx обеспечивает безопасность и надежность сетевых взаимодействий в кластере, снижая нагрузку на инфраструктуру и повышая стабильность работы сервисов и приложений.
Контроль доступа на основе ролей (RBAC)#
Примечание
Применяется к Ingress-nginx-controller, развернутым в среде с включенным RBAC.
Ролевый контроль доступа состоит из четырех уровней:
ClusterRole- это разрешения, назначенные роли, которые применяются ко всему кластеру.ClusterRoleBinding- это привязкаClusterRoleк определенной учетной записи.Role- это разрешения, назначенные роли, которые применяются к определенному namespace.RoleBinding- это привязка роли к определенной учетной записи.
Для применения RBAC к Ingress-nginx-controller, этот контроллер должен быть назначен ServiceAccount. ServiceAccount должжен быть привязанным к ролям и ClusterRoles, определенным для Ingress-nginx-controller.
Разрешения кластера#
Предоставляются для того, чтобы Ingress-nginx-controller мог функционировать как входной порт в кластере. Разрешения предоставляются ClusterRole с именем ingress-nginx:
configmaps,endpoints,nodes,pods,secrets: list, watch - разрешения позволяют получать список объектов и наблюдать за изменениями;nodes: get - разрешение позволяет получать информацию о nodes в кластере;services,ingresses,ingressclasses,endpointslices: get, list, watch - разрешения позволяют получать информацию, а также наблюдать за изменениями в этих ресурсах;events: create, patch - разрешения позволяют создавать и изменять события в кластере;ingresses/status: update - разрешение позволяет обновлять статус внешних ресурсов;leases: list, watch - разрешения позволяют получать список и наблюдать за изменениями в лицензиях.
Разрешения namespace#
Предоставляются для namespace Ingress-nginx. Разрешения выдаются Role с именем ingress-nginx:
configmaps,pods,secrets: get - разрешения позволяют получать информацию;endpoints: get - разрешения позволяют получать информацию о конечных точках.
Ingress-nginx-controller должен иметь доступ к leases с использованием resourceName ingress-nginx-leader:
leases: get, update - разрешения на получение и обновление (с использованием resourceNameingress-controller-leader);leases: create - разрешение на создание.
Важно
ResourceName не могут быть использованы для ограничения запросов с использованием «create», потому что модули авторизации имеют доступ только к информации, которую можно получить из URL-адреса запроса, метода и заголовков (resourceName в запросе на «create» являются частью тела запроса).
ResourceName это election-id определенный ingress-controller, который по умолчанию:
election-id:ingress-controller-leader;resourceName :
<election-id>.
Установка Ingress-nginx#
Для выполнения данного сценария необходимы права администратора.
Создайте манифест
ingress-nginx.yamlсо следующим содержанием:ingress-nginx.yaml
# Replace <repoexample.ru> (if present) to actual docker registry with dropapp images # Replace '0.0.0.0' (if present) to actual IP address of dropapp control plane node apiVersion: v1 kind: Namespace metadata: labels: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx name: ingress-nginx --- apiVersion: v1 automountServiceAccountToken: true kind: ServiceAccount metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx namespace: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx namespace: ingress-nginx rules: - apiGroups: - "" resources: - namespaces verbs: - get - apiGroups: - "" resources: - configmaps - pods - secrets - endpoints verbs: - get - list - watch - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - networking.k8s.io resources: - ingresses verbs: - get - list - watch - apiGroups: - networking.k8s.io resources: - ingresses/status verbs: - update - apiGroups: - networking.k8s.io resources: - ingressclasses verbs: - get - list - watch - apiGroups: - "" resourceNames: - ingress-controller-leader resources: - configmaps verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - coordination.k8s.io resourceNames: - ingress-controller-leader resources: - leases verbs: - get - update - apiGroups: - coordination.k8s.io resources: - leases verbs: - create - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list - watch - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission namespace: ingress-nginx rules: - apiGroups: - "" resources: - secrets verbs: - get - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets - namespaces verbs: - list - watch - apiGroups: - coordination.k8s.io resources: - leases verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - networking.k8s.io resources: - ingresses verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - networking.k8s.io resources: - ingresses/status verbs: - update - apiGroups: - networking.k8s.io resources: - ingressclasses verbs: - get - list - watch - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list - watch - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission rules: - apiGroups: - admissionregistration.k8s.io resources: - validatingwebhookconfigurations verbs: - get - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx namespace: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ingress-nginx subjects: - kind: ServiceAccount name: ingress-nginx namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission namespace: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ingress-nginx-admission subjects: - kind: ServiceAccount name: ingress-nginx-admission namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: ingress-nginx subjects: - kind: ServiceAccount name: ingress-nginx namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: ingress-nginx-admission subjects: - kind: ServiceAccount name: ingress-nginx-admission namespace: ingress-nginx --- apiVersion: v1 data: allow-snippet-annotations: "true" kind: ConfigMap metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-controller namespace: ingress-nginx --- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-controller namespace: ingress-nginx spec: externalTrafficPolicy: Local ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - appProtocol: http name: http port: 80 protocol: TCP targetPort: http - appProtocol: https name: https port: 443 protocol: TCP targetPort: https selector: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx type: LoadBalancer --- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: ports: - appProtocol: https name: https-webhook port: 443 targetPort: webhook selector: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-controller namespace: ingress-nginx spec: minReadySeconds: 0 revisionHistoryLimit: 10 selector: matchLabels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx template: metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx spec: hostAliases: - ip: "10.26.3.61" hostnames: - "app.dapp.qa" - "kc.dapp.qa" - "okd.dapp.qa" containers: - args: - /nginx-ingress-controller - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller - --election-id=ingress-controller-leader - --controller-class=k8s.io/ingress-nginx - --ingress-class=nginx - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so image: <repoexample.ru>/dapp-ingress-nginx-2/nginx-controller:v2.1.0 # Укажите актуальный путь до локального репозитория imagePullPolicy: IfNotPresent lifecycle: preStop: exec: command: - /wait-shutdown livenessProbe: failureThreshold: 5 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: controller ports: - containerPort: 80 name: http protocol: TCP - containerPort: 443 name: https protocol: TCP - containerPort: 8443 name: webhook protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 resources: requests: cpu: 100m memory: 90Mi securityContext: allowPrivilegeEscalation: true capabilities: add: - NET_BIND_SERVICE drop: - ALL runAsUser: 101 volumeMounts: - mountPath: /usr/local/certificates/ name: webhook-cert readOnly: true dnsPolicy: ClusterFirst nodeSelector: kubernetes.io/os: linux serviceAccountName: ingress-nginx terminationGracePeriodSeconds: 300 volumes: - name: webhook-cert secret: secretName: ingress-nginx-admission --- apiVersion: batch/v1 kind: Job metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission-create namespace: ingress-nginx spec: template: metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission-create spec: containers: - args: - create - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc - --namespace=$(POD_NAMESPACE) - --secret-name=ingress-nginx-admission env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f imagePullPolicy: IfNotPresent name: create securityContext: allowPrivilegeEscalation: false nodeSelector: kubernetes.io/os: linux restartPolicy: OnFailure securityContext: fsGroup: 2000 runAsNonRoot: true runAsUser: 2000 serviceAccountName: ingress-nginx-admission --- apiVersion: batch/v1 kind: Job metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: template: metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission-patch spec: containers: - args: - patch - --webhook-name=ingress-nginx-admission - --namespace=$(POD_NAMESPACE) - --patch-mutating=false - --secret-name=ingress-nginx-admission - --patch-failure-policy=Fail env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f imagePullPolicy: IfNotPresent name: patch securityContext: allowPrivilegeEscalation: false nodeSelector: kubernetes.io/os: linux restartPolicy: OnFailure securityContext: fsGroup: 2000 runAsNonRoot: true runAsUser: 2000 serviceAccountName: ingress-nginx-admission --- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: nginx spec: controller: k8s.io/ingress-nginx --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: app.kubernetes.io/component: admission-webhook app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 2.1.0 name: ingress-nginx-admission webhooks: - admissionReviewVersions: - v1 clientConfig: service: name: ingress-nginx-controller-admission namespace: ingress-nginx path: /networking/v1/ingresses failurePolicy: Fail matchPolicy: Equivalent name: validate.nginx.ingress.kubernetes.io rules: - apiGroups: - networking.k8s.io apiVersions: - v1 operations: - CREATE - UPDATE resources: - ingresses sideEffects: NoneПримените манифест в DropApp:
kubectl apply -f ingress-nginx.yaml
Установка Ingress-nginx с помощью Helm#
Для выполнения данного сценария необходимы права администратора, а также установленный Helm.
Примечание
В сценарии используется менеджер пакетов Helm. Данный инструмент не входит в состав продукта и требует дополнительной установки.
Развертывание Ingress-nginx:
Разверните контроллер входящего трафика с помощью следующей команды:
helm upgrade --install ingress-nginx ingress-nginx \ --repo https://<repoexample.ru>.ru/ingress-nginx \ # Укажите актуальный путь до локального репозитория --namespace ingress-nginx --create-namespaceКоманда устанавливает контроллер в namespace
ingress-nginx, создает namespaceingress-nginx, если его не существует.Убедитесь, что в namespace
ingress-nginxсозданы pods:kubectl get pods --namespace=ingress-nginxСоздайте web-сервер и связанный с ним сервис:
kubectl create deployment demo --image=httpd --port=80 kubectl expose deployment demoСоздайте входной ресурс:
kubectl create ingress demo-localhost --class=nginx \ --rule="demo.localdev.me/*=demo:80"В приведенном примере используется хост, который сопоставляется с
localhost.Перенаправьте локальный порт на
ingress-nginx-controller:kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80Примечание
Приведенная выше команда
kubectl port-forwardпереадресовывает номер порта8080в стеке tcp/ip локального хоста, где была введена команда, на номер порта80службы, созданной при установкеingress-nginx. Трафик отправленный на порт с номером8080на локальном хосте, будет достигать порта с номером80службыingress-nginx. Переадресация портов не предназначена для использования в производственной и использована в примере для имитации HTTP-запроса, исходящего из-за пределов кластера, для достижения службы контроллераingress-nginx.Получите доступ к развертыванию, введите команду:
curl --resolve demo.localdev.me:8080:127.0.0.1 http://demo.localdev.me:8080Ответ вернет текст в формате HTML.
Просмотрите внешний IP-адрес или полное доменное имя кластера, введите команду:
kubectl get service ingress-nginx-controller --namespace=ingress-nginxОтвет вернет поле
EXTERNAL-IP. Если в этом поле отображается статусpending, кластер DropApp не сможет подготовить балансировщик нагрузки (чаще это связано с тем, что служба LoadBalancer не запущена).Настройте DNS-запись, указывающую на внешний IP адрес (или полное доменное имя), настройте DNS-запись, указывающую на него.
Для того чтобы настроить DNS-записи, нужно выполнить следующие шаги:
определите IP-адрес или доменное имя, на которое нужно настроить DNS-запись;
создайте DNS-запись в DNS-службе, указав тип записи (например, A запись для IP-адреса или CNAME запись для доменного имени), имя записи, значение записи (IP-адрес или домен) и TTL (время жизни записи);
проверьте, что DNS-запись была успешно создана и настроена на сервер;
убедитесь, что клиенты, которые обращаются к серверу, используют настроенную DNS-запись для получения IP-адреса сервера.
Создайте входной ресурс:
kubectl create ingress demo --class=nginx \ --rule="www.demo.io/*=demo:80"В приведенном примере предполагается, что запись DNS настроена для адреса
www.demo.ioВведите адрес
http://www.demo.io/в адресную строку браузера.В выводе отобразится надпись
It works!.Результатом выполнения сценария является общедоступный сайт
http://www.demo.io/, размещенный в кластере DropApp.