Маршрутизация HTTPS-трафика в Kubernetes с использованием Gateway API и Cilium

Маршрутизация HTTPS-трафика в Kubernetes с использованием Gateway API и Cilium


Введение

Представьте, что вы работаете над развивающейся платформой Kubernetes. Вам нужно безопасно предоставлять службы, эффективно управлять трафиком и масштабироваться без сложности. Исторически пользователи Kubernetes обращались к ресурсам Ingress для открытия HTTP- и HTTPS-приложений. Но по мере развития требований, таких как формирование трафика, работа в мультикомандной среде и продвинутая маршрутизация, ограничения Ingress становятся особенно очевидными.

Здесь вступает в дело Gateway API. Это набор ресурсов Kubernetes, который предоставляет современный, ориентированный на роли и расширяемый подход к маршрутизации трафика, исправляющий недостатки Ingress и прокладывающий путь к гибкой и масштабируемой архитектуре.

В этом руководстве мы рассмотрим, как развернуть простой веб-сервис, доступный через ресурс Gateway на базе Cilium по HTTPS, а также использовать контроллеры, встречающиеся во многих развертываниях Kubernetes, такие как cert-manager с использованием Let’s Encrypt и external-dns.

Пожалуйста, ознакомьтесь с предыдущим учебным материалом Kubernetes Gateway API: Замена Ingress на Cilium Gateway для HTTP-трафика, чтобы лучше понять ресурс Gateway, его ценность и как выполнить простое развертывание с поддержкой HTTP-трафика.

В этом руководстве мы рассмотрим, как безопасно предоставить доступ к приложению с использованием HTTPS и Gateway API, поддерживаемого cert-manager и Let’s Encrypt.

Основные выводы

  • Современная маршрутизация HTTPS с Gateway API: Узнайте, как использовать Kubernetes Gateway API и Cilium Gateway для безопасного предоставления сервисов по HTTPS, выходя за рамки ограничений традиционного Ingress.
  • Автоматизированный TLS с cert-manager и Let’s Encrypt: Настройте cert-manager для автоматического запроса и управления TLS-сертификатами с использованием проверки HTTP-01 для подтверждения домена.
  • Пошаговое развертывание: Разверните пример многосервисного приложения (Bookinfo) и безопасно откройте доступ к нему через API Gateway.
  • Интеграция DNS: Настройте DNS-записи, чтобы направлять ваш домен на Шлюз, обеспечивая внешний доступ к вашим сервисам.
  • Лучшие практики масштабируемости: Применяйте рекомендованные методы для надежного, масштабируемого и удобного в обслуживании управления HTTPS-трафиком на Kubernetes (DOKS) от Linux-Console.net.
  • Практические примеры YAML: Используйте предоставленные манифесты и команды Helm для установки и настройки всех необходимых компонентов.
  • Замените Ingress на Gateway: Поймите преимущества API Gateway по сравнению с Ingress для расширенной маршрутизации, работы в мультикомандных средах и обеспечения устойчивости сетевой инфраструктуры Kubernetes в будущем.

Примечание: Замените примерные домены (например, dolearn.xyz) на ваш собственный домен во всем руководстве.

Интеграция Cert-manager и Let’s Encrypt

Этот учебник использует cert-manager для динамического запроса и управления готовыми к производству TLS-сертификатами от Let’s Encrypt.

В этом руководстве мы будем использовать проверку HTTP-01 в рамках процесса запроса сертификата. Эта проверка используется cert-manager и Let’s Encrypt для подтверждения контроля над полностью квалифицированным доменным именем (FQDN) при выдаче сертификата. Проверка HTTP-01 постоянно упоминается в этом руководстве, и понимание того, как она работает, будет полезным.

Предварительные требования

  • Запущенный VPC Native Linux-Console.net Kubernetes кластер (версия 1.33+)
  • kubectl установлен и настроен для работы с вашим кластером.
  • Установлены CRD API шлюза (DOKS включает Cilium, который поддерживает это по умолчанию)
  • Зарегистрированное доменное имя и доступ к DNS.

Примечание: в примерах используется домен dolearn.xyz, не забудьте заменить эти ссылки на ваш собственный домен.

Шаг 1: Разверните пример приложения

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.11/samples/bookinfo/platform/kube/bookinfo.yaml 

Применение манифеста bookinfo.yaml запускает четыре микросервиса Bookinfo — productpage, details, reviews и ratings — с ядром

  • Сервисы на порту 9080, чтобы каждый микросервис был обнаруживаемым.
  • Развертывания для запуска Pod-ов (детали и рейтинги имеют v1, страница продукта имеет v1, а отзывы имеют v1, v2 и v3).
  • Служебные учетные записи (ServiceAccounts), чтобы предоставить каждому сервису собственную личность.

Шаг 2. Установите Cert Manager с помощью Helm

Перед тем как вы сможете автоматически предоставлять TLS-сертификаты для ваших приложений, необходимо установить cert-manager. cert-manager — это дополнение Kubernetes, которое автоматизирует управление и выдачу TLS-сертификатов из различных источников, включая Let’s Encrypt. В этом руководстве cert-manager будет отвечать за запрос и обновление сертификатов для ваших доменов, что важно для обеспечения безопасного HTTPS-трафика через Gateway API.

Мы будем использовать Helm, менеджер пакетов для Kubernetes, чтобы установить cert-manager. Такой подход гарантирует получение последней стабильной версии и упрощает последующие обновления. Следующие команды добавят официальный репозиторий Helm Jetstack, обновят информацию о локальных чартах и установят cert-manager с включенной поддержкой Gateway API.

helm repo add jetstack https://charts.jetstack.io helm repo update 
helm install cert-manager jetstack/cert-manager      --namespace cert-manager      --set crds.enabled=true      --create-namespace      --set config.apiVersion="controller.config.cert-manager.io/v1alpha1"      --set config.kind="ControllerConfiguration"      --set config.enableGatewayAPI=true --wait 

Шаг 3: Создайте шлюз

Когда вы создаёте шлюз, вы также решаете, как он будет совместно использоваться:

  • Выделенный шлюз: Развертывается в том же пространстве имен, что и приложение и его HTTP-маршруты. Эта модель хорошо работает, когда каждая команда или приложение владеет своим собственным шлюзом.
  • Общий шлюз: Развернут в другом пространстве имен и используется несколькими приложениями. В этом случае владелец шлюза должен явно разрешить другим пространствам имен прикреплять маршруты с помощью поля allowedRoutes.

Для нашего сценария использования давайте создадим Специальный Шлюз, который определяет слушателей для:

  • TLS/HTTPS (порт 443) для каждого имени хоста.
  • HTTP (порт 80) используется только для обработки трафика ACME-челленджа HTTP-01.
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata:   name: tls-gateway spec:   gatewayClassName: cilium   listeners:      - name: https-1     protocol: HTTPS     port: 443     hostname: "bookinfo.dolearn.xyz"     tls:       certificateRefs:        - kind: Secret          name: gateway-tls-secret   - name: https-2     protocol: HTTPS     port: 443     hostname: "hipstershop.dolearn.xyz"     tls:       certificateRefs:        - kind: Secret          name: gateway-tls-secret     - name: http #  created for the purpose of solving HTTP-01 challenges     protocol: HTTP     port: 80     hostname: "bookinfo.dolearn.xyz"     allowedRoutes:        namespaces:         from: Same  # Any HTTPRoute in same namespace can bind to this Gateway listener.    - name: http-2 # created for the purpose of solving HTTP-01 challenges     protocol: HTTP     port: 80     hostname: "hipstershop.dolearn.xyz"     allowedRoutes:        namespaces:         from: Same  # Any HTTPRoute in same namespace can bind to this Gateway listener.       

Шлюз и HTTP-маршруты приложения находятся в одном пространстве имён. Только команда sample-app может подключать к нему маршруты, что обеспечивает изоляцию маршрутизации и предотвращает использование этой точки входа другими командами или пространствами имён.

После применения вышеуказанного манифеста будут созданы два ресурса: Gateway и Service типа LoadBalancer. Обратите внимание, процесс создания балансировщика нагрузки и отображения его IP-адреса может занять несколько минут.

kubectl get gateway 
NAME          CLASS    ADDRESS   PROGRAMMED   AGE tls-gateway   cilium             True         7s 
kubectl get svc -o wide | grep LoadBalancer 
cilium-gateway-tls-gateway   LoadBalancer   10.108.88.49    167.172.14.164   443:32269/TCP,80:30298/TCP   21s   <none> 

Шаг 4: Создайте HTTP-маршрут

После того как у вас настроен Gateway, следующим шагом является определение HTTPRoutes — они указывают Gateway, как направлять входящие запросы к вашим сервисам приложений.

apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata:   name: https-app-route-1 spec:   parentRefs:   - name: tls-gateway     sectionName: https-1   hostnames:   - "bookinfo.dolearn.xyz"   rules:   - matches:     - path:         type: PathPrefix         value: /details     backendRefs:     - name: details       port: 9080 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata:   name: https-app-route-2 spec:   parentRefs:   - name: tls-gateway     sectionName: https-2   hostnames:   - "hipstershop.dolearn.xyz"   rules:   - matches:     - path:         type: PathPrefix         value: /     backendRefs:     - name: productpage       port: 9080 

Что это делает?

  • Ссылки на шлюз

    1. parentRefs указывает на Gateway tls-gateway в той же namespace.
  • Это указывает кластеру, какой шлюз должен обрабатывать эти маршруты.
  • Определяет имена хостов. Запросы к bookinfo.dolearn.xyz и hipstershop.dolearn.xyz будут соответствовать этому HTTPRoute.
  • Устанавливает правила маршрутизации. 4. Первое правило: Запросы с путями, начинающимися с /details, отправляются на сервис details на порту 9080. 5. Второе правило: — Совпадает с запросами, где путь начинается с/(т.е. все пути). — Направляет эти запросы на сервис productpage на порту 9080.

Шаг 5: Настройка ExternalDNS с Linux-Console.net [По желанию]

ExternalDNS автоматизирует управление DNS-записями у вашего провайдера (в данном случае, Linux-Console.net) на основе ресурсов Kubernetes, таких как Services, Ingresses и маршруты Gateway API.

1. Создайте токен API для Linux-Console.net

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

2. Сохраните токен как секрет Kubernetes

Создайте секрет Kubernetes, который ExternalDNS будет использовать для аутентификации на Linux-Console.net:

kubectl create secret generic digitalocean-dns    --from-literal=access-token=<YOUR_DIGITALOCEAN_TOKEN> 

3. Добавьте репозиторий Helm для ExternalDNS

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/ helm repo update 

4. Настройка значений для развертывания Helm

env: # Passes the Linux-Console.net token from the secret   - name: DO_TOKEN     valueFrom:       secretKeyRef:         name: digitalocean-dns         key: access-token  provider: # ExternalDNS provider configuration   name: digitalocean  policy: sync # Ensures ExternalDNS continuously reconciles DNS records txtOwnerId: gateway-api # Ensures ExternalDNS does not conflict others using this domain  sources: # Kubernetes resources to watch and create DNS records for   - service   - ingress   - gateway-grpcroute   - gateway-httproute 

5. Установите ExternalDNS

Развернуть ExternalDNS с помощью Helm

helm install external-dns external-dns/external-dns -f values.yaml 

6. Проверить DNS-записи

После развертывания ExternalDNS должен автоматически создавать DNS-записи для ваших служб/Ingress.

Вы можете проверить с помощью:

$ dig +short hipstershop.dolearn.xyz 167.172.14.164 $ dig +short bookinfo.dolearn.xyz 167.172.14.164 

Справка: https://kubernetes-sigs.github.io/external-dns/latest/

В качестве альтернативы, вы можете вручную добавить DNS-записи: https://docs.linux-console.net/products/networking/dns/how-to/manage-records/

Шаг 6: Создание издателя и сертификата

Эмитент в cert-manager определяет, где и как получить сертификаты. В этом примере мы будем использовать Let’s Encrypt с проверкой HTTP-01.

Челлендж HTTP-01 работает путем временного создания HTTP-эндпоинта под вашим доменом (например, http://example.com/.well-known/acme-challenge/…).

Затем Let’s Encrypt проверяет этот эндпоинт, чтобы подтвердить, что вы владеете доменом. После подтверждения он выдаёт сертификат.

apiVersion: cert-manager.io/v1 kind: Issuer metadata:   name: letsencrypt-gateway spec:   acme:     email: your-email@example.com # Replace this with your email address     server: https://acme-v02.api.letsencrypt.org/directory     privateKeySecretRef:       name: letsencrypt-gateway-account-key     solvers:       # Use the HTTP-01 challenge provider       - http01:           gatewayHTTPRoute:             parentRefs:               - name: tls-gateway                 kind: Gateway 

Теперь мы создадим ресурс Certificate. Это указывает cert-manager, для какого домена нам нужен TLS-сертификат и какой Issuer должен его выдать.

apiVersion: cert-manager.io/v1 kind: Certificate metadata:   name: letsencrypt-certificate spec:   secretName: gateway-tls-secret   dnsNames:     - bookinfo.dolearn.xyz     - hipstershop.dolearn.xyz    issuerRef:     name: letsencrypt-gateway     kind: Issuer 

Как проверить, что сертификат выдан

kubectl get certificate 
NAME                        READY   SECRET               AGE letsencrypt-certificate  True    gateway-tls-secret   3h32m 

Примечание

При создании шлюза и запросе сертификата с использованием проверки HTTP-01, cert-manager выполняет самопроверку, делая HTTP-запрос к конечной точке проверки, чтобы убедиться, что она публично доступна.

Может возникнуть задержка до того, как запись DNS будет создана ExternalDNS и полностью распространена. В этот период распространение проверки HTTP-01 может занять некоторое время, что может вызвать временные ошибки в самопроверке.

Cert-manager обрабатывает это корректно, периодически повторяя самопроверку. Как только запись DNS становится доступной и правильно разрешается, самопроверка проходит успешно, позволяя завершить проверку HTTP-01 и выпустить сертификат.

Шаг 7: Выполнение HTTPS-запросов

Теперь давайте проверим это, выполняя HTTPS-запросы к приложению с использованием сервиса.

 curl https://bookinfo.dolearn.xyz/details/1 {"id":1,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}% 
$ curl https://hipstershop.dolearn.xyz/ <!DOCTYPE html> <html>   <head>     <title>Simple Bookstore App</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">  <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">  <!-- Optional theme --> <link rel="stylesheet" href="static/bootstrap/css/bootstrap-theme.min.css">    </head>   <body>   <p>     <h3>Hello! This is a simple bookstore application consisting of three services as shown below</h3> </p>  <table class="table table-condensed table-bordered table-hover"><tr><th>name</th><td>http://details:9080</td></tr><tr><th>endpoint</th><td>details</td></tr><tr><th>children</th><td><table class="table table-condensed table-bordered table-hover"><tr><th>name</th><th>endpoint</th><th>children</th></tr><tr><td>http://details:9080</td><td>details</td><td></td></tr><tr><td>http://reviews:9080</td><td>reviews</td><td><table class="table table-condensed table-bordered table-hover"><tr><th>name</th><th>endpoint</th><th>children</th></tr><tr><td>http://ratings:9080</td><td>ratings</td><td></td></tr></table></td></tr></table></td></tr></table>  <p>     <h4>Click on one of the links below to auto generate a request to the backend as a real user or a tester     </h4> </p> <p><a href="/productpage?u=normal">Normal user</a></p> <p><a href="/productpage?u=test">Test user</a></p>    <!-- Latest compiled and minified JavaScript --> <script src="static/jquery.min.js"></script>  <!-- Latest compiled and minified JavaScript --> <script src="static/bootstrap/js/bootstrap.min.js"></script>    </body> </html> 

Шаг 8: Создание и тестирование перенаправления с HTTP на HTTPS

С текущей конфигурацией, если кто-то попытается получить доступ к URL через HTTP, он получит ошибку 404. Нам нужно создать объекты HTTPRoute, которые будут перенаправлять HTTP-запросы на защищённые HTTPS URL. Это можно сделать, применив следующее к вашему кластеру:

apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata:   name: https-1-redirect spec:   hostnames:     - bookinfo.dolearn.xyz   parentRefs:     - group: gateway.networking.k8s.io       kind: Gateway       name: tls-gateway       sectionName: http   rules:     - filters:         - requestRedirect:             port: 443             scheme: https             statusCode: 301           type: RequestRedirect       matches:         - path:             type: PathPrefix             value: / --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata:   name: https-2-redirect spec:   hostnames:     - hipstershop.dolearn.xyz   parentRefs:     - group: gateway.networking.k8s.io       kind: Gateway       name: tls-gateway       sectionName: http-2   rules:     - filters:         - requestRedirect:             port: 443             scheme: https             statusCode: 301           type: RequestRedirect       matches:         - path:             type: PathPrefix             value: / 

Теперь, когда вы используете curl для HTTP-URL, вы можете увидеть переадресацию, а затем с помощью -L последуете за этой переадресацией на HTTPS-URL.

https$ curl -Lv http://bookinfo.dolearn.xyz/details/1 *   Trying 167.172.14.164:80... * Connected to bookinfo.dolearn.xyz (167.172.14.164) port 80 (#0) > GET /details/1 HTTP/1.1 > Host: bookinfo.dolearn.xyz > User-Agent: curl/7.81.0 > Accept: */* >  * Mark bundle as not supporting multiuse < HTTP/1.1 301 Moved Permanently < location: https://bookinfo.dolearn.xyz:443/details/1 < date: Thu, 11 Sep 2025 18:20:19 GMT < server: envoy < content-length: 0 <  * Connection #0 to host bookinfo.dolearn.xyz left intact * Clear auth, redirects to port from 80 to 443 * Issue another request to this URL: 'https://bookinfo.dolearn.xyz:443/details/1' *   Trying 167.172.14.164:443... * Connected to bookinfo.dolearn.xyz (167.172.14.164) port 443 (#1) <SNIP>  

Часто задаваемые вопросы (ЧЗВ)

1. В чем разница между Gateway API и Ingress?

API Gateway — современный преемник Ingress, предлагающий несколько преимуществ:

  • Контроль доступа на основе ролей: различные команды могут управлять различными аспектами маршрутизации трафика
  • Лучшая расширяемость: Более гибкий и программируемый по сравнению с Ingress
  • Поддержка нескольких команд: Позволяет нескольким командам управлять маршрутами без конфликтов
  • Расширенные функции: Встроенная поддержка разделения трафика, сопоставления заголовков и сложных правил маршрутизации

2. Почему стоит использовать Cilium с Gateway API?

Cilium предоставляет:

  • Высокая производительность: сетевые технологии на основе eBPF для лучшей производительности по сравнению с традиционными iptables
  • Встроенная безопасность: Сетевые политики и возможности сервисной сети
  • Поддержка Gateway API: Родная реализация спецификаций Gateway API
  • Готово к эксплуатации: Используется крупными облачными провайдерами и предприятиями

3. Как cert-manager работает с Gateway API?

Cert-manager интегрируется с Gateway API через:

  • HTTP-01 задачи: Использует временные HTTP-эндпоинты для проверки владения доменом
  • Автоматическое продление: Обеспечивает обновление сертификата до истечения срока действия
  • Несколько эмитентов: поддерживаются Let’s Encrypt, HashiCorp Vault и другие удостоверяющие центры
  • Интеграция шлюза: Прямое предоставление сертификатов для ресурсов шлюза

4. Что происходит, если распространение DNS происходит медленно?

ExternalDNS и cert-manager корректно обрабатывают задержки:

  • ExternalDNS: Постоянно повторяет попытки создания DNS-записи
  • cert-manager: Периодически повторяет попытки выполнения HTTP-01 вызовов
  • Механизм самопроверки: Проверяет публичную доступность перед продолжением
  • Типичная задержка: 1-5 минут для распространения DNS

5. Могу ли я использовать несколько доменов с одним шлюзом?

Да, вы можете настроить несколько доменных имен в одном шлюзе:

  • Несколько слушателей: Каждый хост получает свою собственную конфигурацию слушателя
  • Совместные сертификаты: Используйте универсальные сертификаты или сертификаты SAN
  • Отдельные маршруты: Каждый домен может иметь различные конфигурации HTTPRoute
  • Эффективность балансировщика нагрузки: Один балансировщик нагрузки обслуживает несколько доменов

6. Как устранить проблемы с сертификатом?

Общие шаги по устранению неполадок:

  1. Проверить статус сертификата: kubectl get certificate
  2. Просмотр логов cert-manager: kubectl logs -n cert-manager deployment/cert-manager
  3. Проверка разрешения DNS: dig your-domain.com
  4. Проверка задачи HTTP-01: Посетите http://your-domain.com/.well-known/acme-challenge/
  5. Проверить состояние шлюза: kubectl describe gateway your-gateway

7. Готова ли эта установка для эксплуатации в производстве?

Это руководство предоставляет основу, готовую для производства, с:

  • Автоматическое управление сертификатами: Нет необходимости в ручном обновлении сертификатов
  • Автоматизация DNS: Автоматическое управление записями DNS
  • Рекомендации по безопасности: перенаправления с HTTP на HTTPS
  • Мониторинг: Встроенные проверки состояния и отчётность о статусе
  • Масштабируемость: Может работать с несколькими доменами и сервисами

Заключение

Следуя этому руководству, вы развернули пример приложения, сделали его доступным через Gateway и обеспечили его безопасное соединение через HTTPS с использованием cert-manager. С API Gateway маршрутизация, завершение TLS и управление сертификатами становятся более гибкими и нативными для Kubernetes по сравнению с традиционным Ingress.

Эту основу можно расширить дальше, включая добавление Canary-трафика, маршрутизацию между пространствами имен или продвинутые политики, такие как сопоставление заголовков и ограничение скорости. С настроенным HTTPS ваши рабочие нагрузки готовы к производственному трафику, и теперь у вас есть современный, масштабируемый способ управления сетью в Kubernetes.

Готовы поднять сетевое взаимодействие Kubernetes на новый уровень? Разверните свои приложения на Kubernetes от Linux-Console.net и ощутите возможности современного маршрутизации трафика с помощью Gateway API и Cilium.

Следующие шаги

Теперь, когда у вас есть надежная основа для Gateway API, рассмотрите эти продвинутые реализации:

Учебное пособие по Kubernetes Gateway API: Замена Ingress на Cilium Gateway для HTTP-трафика

Готовность DOKS к эксплуатации, часть 2: Включение HTTPS Настройка аутентификации OAuth с внешними поставщиками Установка мониторинга Prometheus для метрик Gateway

Изучайте нашу обширную библиотеку учебных материалов по Kubernetes, охватывающую всё — от основ до корпоративных шаблонов.

Присоединяйтесь к сообществу Linux-Console.net, чтобы делиться своими реализациями Gateway API и учиться у других разработчиков.

Спасибо, что учитесь вместе с сообществом Linux-Console.net.

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *