Top.Mail.Ru
Публичное облако на базе VMware с управлением через vCloud Director
Вход / Регистрация
На главную
25eb9e0a-a5a8-472a-ace7-940b8bd2adf0
Облачные сервисы

Nginx Ingress

Ingress — это ресурс Kubernetes, позволяющий организовать доступ к сервисам внутри кластера через HTTP и HTTPS. Он предоставляет маршрутизацию на основе URL, доменов и других параметров. В этой статье рассмотрим использование Nginx Ingress на примере трех деплойментов Nginx, имитирующих три разных сервиса. Мы также настроим SSL-сертификат для защиты соединения.

Установка Nginx Ingress

Для начала необходимо установить Nginx Ingress в кластере. В панели управления кластером перейдите во вкладку «Дополнения», нажмите на три точки рядом с Nginx Ingress и выберите «Установить».

Image2

После установки проверьте, что Ingress работает корректно. Выполните команду:

  
kubectl get pods -n ingress-nginx

Убедитесь, что все поды находятся в статусе Running.

Настройка деплойментов и сервисов

Для удобства создадим отдельный неймспейс, в котором будут находиться все манифесты:

  
kubectl create namespace ingress-example

Мы развернем три Deployment с образами Nginx, каждый будет имитировать отдельный сервис. К каждому Deployment мы создадим Service с типом ClusterIP — это служебный тип сервиса в Kubernetes, который выдает внутренний IP-адрес внутри кластера. Такой сервис не доступен извне напрямую, однако он может быть подцеплен к Ingress для публикации во внешнюю сеть.

service1-deployment.yaml:

  
apiVersion: apps/v1 kind: Deployment metadata: name: service1 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service1 template: metadata: labels: app: service1 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service1.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service1 namespace: ingress-example spec: selector: app: service1 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP

Пояснения к манифесту:

  1. Deployment

    • replicas: 2 указывает, что будет запущено две реплики подов с Nginx.

    • В секции selector и template.metadata.labels задаётся соответствие между подами и тем, как их будет находить сервис.

    • volumeMounts и volumes используются, чтобы подмонтировать файл service1.html из ConfigMap в директорию, откуда Nginx по умолчанию раздает контент.

  2. Service

    • ClusterIP означает, что сервис будет доступен только внутри кластера по выделенному IP-адресу. Для внешнего доступа мы будем использовать Ingress.

service2-deployment.yaml:

  
apiVersion: apps/v1 kind: Deployment metadata: name: service2 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service2 template: metadata: labels: app: service2 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service2.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service2 namespace: ingress-example spec: selector: app: service2 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP

service3-deployment.yaml:

  
apiVersion: apps/v1 kind: Deployment metadata: name: service3 namespace: ingress-example spec: replicas: 2 selector: matchLabels: app: service3 template: metadata: labels: app: service3 spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: service-config items: - key: service3.html path: index.html --- apiVersion: v1 kind: Service metadata: name: service3 namespace: ingress-example spec: selector: app: service3 ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP

Чтобы отличать наши сервисы друг от друга, создадим ConfigMap с тремя разными HTML-страницами.

configmap.yaml:

  
apiVersion: v1 kind: ConfigMap metadata: name: service-config namespace: ingress-example data: service1.html: | <html> <head><title>Service 1</title></head> <body><h1>Welcome to Service 1!</h1></body> </html> service2.html: | <html> <head><title>Service 2</title></head> <body><h1>Welcome to Service 2!</h1></body> </html> service3.html: | <html> <head><title>Service 3</title></head> <body><h1>Welcome to Service 3!</h1></body> </html>

И применим манифесты:

  
kubectl apply -f configmap.yaml kubectl apply -f service1-deployment.yaml kubectl apply -f service2-deployment.yaml kubectl apply -f service3-deployment.yaml

Проверим статус подов:

  
kubectl get pods -n ingress-example

Все поды должны иметь статус Running. На этом подготовительные работы можно считать завершенными.

Создание Ingress 

С помощью Ingress мы укажем, какой трафик (по доменам и путям) перенаправлять на соответствующие сервисы. Создадим манифест ingress.yaml:

  
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 - host: ingress2.example.com http: paths: - path: / pathType: Prefix backend: service: name: service3 port: number: 80

Пояснения к манифесту:

  • rules.host задает домен, к которому будет привязан Ingress.

  • paths определяет правила маршрутизации:

    • При обращении к ingress1.example.com/service1 будет перенаправление на service1.

    • При обращении к ingress1.example.com/service2 будет перенаправление на service2.

    • При обращении к ingress2.example.com/ будет перенаправление на service3.

Применим манифест:

  
kubectl apply -f ingress.yaml

Создание LoadBalancer

Чтобы обратиться к Nginx Ingress из внешней сети, создадим Service типа LoadBalancer, который будет отвечать за балансировку нагрузки и предоставит нам внешний IP-адрес. Подготовим для этого манифест loadbalancer.yaml следующего содержания:

  
apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: selector: app.kubernetes.io/name: ingress-nginx ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443 type: LoadBalancer

Применим манифест:

  
kubectl apply -f loadbalancer.yaml

Дождитесь, пока балансировщик создастся, и убедитесь, что у него появился внешний IP-адрес:

  
kubectl get services -n ingress-nginx

Внешний IP будет отображен в колонке EXTERNAL-IP.

Полученный IP-адрес необходимо прописать в DNS-настройках домена в виде А-записей для доменов ingress1.example.com и ingress2.example.com. После обновления DNS ваши домены будут указывать на этот балансировщик, и вы сможете обращаться к сервисам по внешним URL:

  • http://ingress1.example.com/service1 отобразится заголовок «Welcome to Service 1!».
  • http://ingress1.example.com/service2 — отобразится заголовок «Welcome to Service 2!».
  • http://ingress2.example.com/ — отобразится заголовок «Welcome to Service 3!».

Настройка SSL-сертификата

Для обеспечения защищенного соединения в Nginx Ingress необходимо добавить существующий SSL-сертификат в виде Kubernetes-секрета, а затем указать этот секрет в манифесте Ingress.

Если вы хотите автоматизировать выпуск и продление сертификатов (например, через Let’s Encrypt), рекомендуем использовать инструмент cert-manager.

Подготовка файлов сертификата и ключа

Сохраните файл ключа tls.key и сертификат tls.crt локально. Если вы заказывали сертификат в Timeweb Cloud, содержимое ключа и сертификата можно скопировать со страницы управления сертификатом в панели Timeweb Cloud. Убедитесь, что сертификат не просрочен и соответствует доменам, которые вы хотите защитить.

Image1

Создание Kubernetes-секрета

Чтобы добавить сертификат в кластер, необходимо закодировать файлы в Base64 и создать манифест секрета. Выполните в терминале команды:

  
base64 -w 0 ./tls.crt base64 -w 0 ./tls.key

Затем создайте файл tls-secret.yaml следующего содержания:

  
apiVersion: v1 kind: Secret metadata: name: ingress-example-tls namespace: ingress-example type: kubernetes.io/tls data: tls.crt: |- <BASE64_ЗАКОДИРОВАННЫЙ_СЕРТИФИКАТ> tls.key: |- <BASE64_ЗАКОДИРОВАННЫЙ_КЛЮЧ>

Сохраните файл и примените манифест:

  
kubectl apply -f tls-secret.yaml

Проверьте, что значения ключа и сертификата ненулевые. Для этого выполните:

  
kubectl describe secret ingress-example-tls -n ingress-example

Обновление манифеста Ingress

Обновите ваш манифест ingress.yaml, добавив секцию tls, и укажите имя созданного секрета:

  
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: ingress-example annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: tls: - hosts: - ingress1.example.com - ingress2.example.com secretName: ingress-example-tls rules: - host: ingress1.example.com http: paths: - path: /service1 pathType: Prefix backend: service: name: service1 port: number: 80 - path: /service2 pathType: Prefix backend: service: name: service2 port: number: 80 - host: ingress2.example.com http: paths: - path: / pathType: Prefix backend: service: name: service3 port: number: 80

Примените измененный манифест:

  
kubectl apply -f ingress.yaml

Теперь при обращении к ingress1.example.com или ingress2.example.com по HTTPS браузер будет использовать сертификат, указанный в секрете ingress-example-tls. Таким образом, трафик к вашим сервисам будет защищен.

Если у вас несколько сертификатов для разных доменов, создайте Secret для каждого из них. Например, для доменов example.com и example.org создайте два секрета.

После этого обновите манифест Ingress, добавив секцию tls для каждого домена:

  
spec: tls: - hosts: - example.com secretName: example-com-tls - hosts: - example.org secretName: example-org-tls

После этого каждый домен будет использовать свой сертификат, указанный в соответствующем секрете.

Была ли статья полезна?
Ваша оценка очень важна
  • Ваш комментарий
  • Предпросмотр
Пока нет комментариев
Мы используем на сайте куки.
В интернете без них никак