Маршрутизация 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
Что это делает?
-
Ссылки на шлюз
parentRefsуказывает на Gatewaytls-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. Как устранить проблемы с сертификатом?
Общие шаги по устранению неполадок:
- Проверить статус сертификата:
kubectl get certificate - Просмотр логов cert-manager:
kubectl logs -n cert-manager deployment/cert-manager - Проверка разрешения DNS:
dig your-domain.com - Проверка задачи HTTP-01: Посетите
http://your-domain.com/.well-known/acme-challenge/ - Проверить состояние шлюза:
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.



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