<div><img src="https://top-fwz1.mail.ru/counter?id=3548135;js=na" style="position:absolute;left:-9999px;" alt="Top.Mail.Ru" /></div>
Публичное облако на базе VMware с управлением через vCloud Director
На главную
25eb9e0a-a5a8-472a-ace7-940b8bd2adf0
Облачные сервисы

Traefik

Traefik — это ингресс контроллер и реверс прокси для работы в облачных средах и Kubernetes. Он автоматически обнаруживает сервисы, обеспечивает SSL/TLS-терминацию и расширенные возможности маршрутизации.  Использование Traefik в Kubernetes позволяет гибко управлять маршрутизацией трафика к сервисам внутри кластера.

Установка

  1. Перейдите во вкладку «Дополнения» в панели управления кластером.

  2. Найдите Traefik и нажмите на него.

Image2

  1. Откроется мастер установки. Вы можете загрузить собственный values.yaml для кастомизации установки или оставить настройки по умолчанию. Запустите установку, нажав на кнопку «Установить».

Image1

  1. Дождитесь завершения установки. После этого убедитесь, что все поды в неймспейсе traefik запущены и находятся в статусе «Running»:
kubectl get pods -n traefik

Использование

По умолчанию в установленной конфигурации Traefik использует четыре entryPoints (входные точки):

  • :8000/tcp — HTTP (web)
  • :8443/tcp — HTTPS (websecure)
  • :8080/tcp — API Dashboard (traefik)
  • :9100/tcp — Метрики Prometheus (metrics)

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

apiVersion: v1
kind: Service
metadata:
  name: example-service
  namespace: default
spec:
  selector:
    app: example-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Этот манифест создает сервис example-service в пространстве имен default, который:

  • Маршрутизирует HTTP-трафик (порт 80).
  • Направляет его на поды, имеющие метку app: example-app.
  • Передает запросы на targetPort: 80 внутри подов.

Теперь можно настроить маршрутизацию через Traefik с помощью IngressRoute:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: example-service-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`service.example.com`)
      kind: Rule
      services:
        - name: example-service
          port: 80

В этом манифесте:

  • entryPoints: web — указывает, что маршрутизация происходит через HTTP (8000/tcp).
  • match: Host(‘service.example.com’) — задает правило маршрутизации по доменному имени.
  • Запросы направляются на сервис example-service на порт 80.

Пример использования

Рассмотрим использование Traefik на примере. Создадим два деплоймента Nginx, которые будут работать на двух разных доменах — service1.example.com и service2.example.com. Также настроим балансировщик нагрузки и маршрутизацию через Traefik. В завершение настроим SSL-сертификаты средствами Traefik.

Создание ConfigMap

Сначала создадим файл configmap-nginx.yaml, который определит HTML-страницы для каждого сервиса:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-pages
  namespace: default
data:
  index1.html: |
    <!DOCTYPE html>
    <html>
    <head><title>Service 1</title></head>
    <body><h1>Service 1</h1></body>
    </html>
  index2.html: |
    <!DOCTYPE html>
    <html>
    <head><title>Service 2</title></head>
    <body><h1>Service 2</h1></body>
    </html>

Создание Deployment для Nginx

Манифест service1-nginx.yaml описывает деплоймент для первого сервиса:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service1
  namespace: default
  labels:
    app: service1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: service1
  template:
    metadata:
      labels:
        app: service1
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - name: html-volume
              mountPath: /usr/share/nginx/html
          ports:
            - containerPort: 80
      volumes:
        - name: html-volume
          configMap:
            name: nginx-pages
            items:
              - key: index1.html
                path: index.html

Манифест service2-nginx.yaml описывает деплоймент для второго сервиса:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service2
  namespace: default
  labels:
    app: service2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: service2
  template:
    metadata:
      labels:
        app: service2
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - name: html-volume
              mountPath: /usr/share/nginx/html
          ports:
            - containerPort: 80
      volumes:
        - name: html-volume
          configMap:
            name: nginx-pages
            items:
              - key: index2.html
                path: index.html

Создание Service

Определим сервисы, к которым Traefik будет направляться трафик.

Манифест service1-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: service1
  namespace: default
spec:
  selector:
    app: service1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Этот манифест создает сервис service1, который будет принимать HTTP-запросы на порт 80 и перенаправлять их на поды, имеющие метку app: service1.

Манифест service2-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: service2
  namespace: default
spec:
  selector:
    app: service2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Создание маршрутов в Traefik

В манифесте service1-ingressroute.yaml описывается маршрут для первого сервиса:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service1-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`service1.example.com`)
      kind: Rule
      services:
        - name: service1
          port: 80

Этот манифест определяет IngressRoute для service1.example.com. Разберем его компоненты:

  • entryPoints: web — указывает, что маршрут будет доступен через HTTP (порт 80, указанный в балансировщике Traefik).
  • match: Host(‘service1.example.com’) — определяет, что данный маршрут будет срабатывать при обращении к домену service1.example.com.
  • name: service1 — маршрут передает трафик в сервис service1.
  • port: 80 — передача происходит на порт 80 внутри Kubernetes-сервиса service1.

Файл service2-ingressroute.yaml описывает маршрут для второго сервиса:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service2-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`service2.example.com`)
      kind: Rule
      services:
        - name: service2
          port: 80

Настройка балансировщика нагрузки

Опишем балансировщик для Traefik в traefik-loadbalancer.yaml:

apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: traefik
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: traefik
  ports:
    - name: web
      port: 80
      targetPort: 8000
    - name: websecure
      port: 443
      targetPort: 8443

Применение конфигурации

Применяем все манифесты:

kubectl apply -f ./

После завершения создания балансировщика указываем его IP-адрес в качестве A-записей для доменов. Теперь можно обращаться к сервисам:

  • http://service1.example.com
  • http://service2.example.com

Таким образом, мы настроили два сервиса в Kubernetes с использованием Traefik, обеспечили маршрутизацию и балансировку нагрузки.

Настройка SSL

При использовании Traefik можно получать SSL-сертификаты двумя способами:

  • встроенными средствами Traefik;
  • с использованием cert-manager.

Выбор метода зависит от конфигурации кластера. Если используются другие Ingress-контроллеры, рекомендуется cert-manager для централизованного управления сертификатами. Если же в кластере используется только Traefik, можно воспользоваться встроенной функцией получения сертификатов.

Обновление конфигурации Traefik

Для включения поддержки Let's Encrypt необходимо изменить конфигурацию Traefik:

  1. Перейдите в панель управления кластером → «Дополнения» → выберите Traefik.

  2. Включите режим продвинутой установки.

  3. Приведите конфигурацию к виду:

image:
  registry: dockerhub.timeweb.cloud

deployment:
  kind: Deployment

updateStrategy:
  rollingUpdate:
    maxUnavailable: 1
    maxSurge: 0

additionalArguments:
  - "--certificatesresolvers.le.acme.email=admin@example.com"
  - "--certificatesresolvers.le.acme.storage=/data/acme.json"
  - "--certificatesresolvers.le.acme.tlschallenge=true"

Что изменилось:

  • По умолчанию, Traefik устанавливается как DaemonSet. В этом режиме сертификаты средствами Traefik получить невозможно. Поэтому тип развёртывания меняется на Deployment.
  • Добавлен сегмент additionalArguments. В --certificatesresolvers.le.acme.email укажите свою почту для регистрации в Let's Encrypt.

Image3

  1. Сохраните изменения и дождитесь завершения обновления.

Проверка конфигурации

После обновления убедитесь, что конфигурация применена корректно:

kubectl get pod -n traefik

Затем проверьте наличие параметров ACME:

kubectl get pod имя_пода -n traefik -o yaml | grep acme

Вывод должен содержать строки:

  - --certificatesresolvers.le.acme.email=admin@example.com
  - --certificatesresolvers.le.acme.storage=/data/acme.json
  - --certificatesresolvers.le.acme.tlschallenge=true

Автоматический редирект с HTTP на HTTPS

Создадим middleware для автоматического редиректа с HTTP на HTTPS. Файл redirect-https.yaml:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: redirect-to-https
  namespace: default
spec:
  redirectScheme:
    scheme: https
    permanent: true

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

kubectl apply -f redirect-https.yaml

Обновление IngressRoute

Обновим IngressRoute, добавив middleware для редиректа с HTTP на HTTPS.

Манифест service1-ingressroute.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service1-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`service1.example.com`)
      kind: Rule
      middlewares:
        - name: redirect-to-https
      services:
        - name: service1
          port: 80

Манифест service2-ingressroute.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service2-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`service2.example.com`)
      kind: Rule
      middlewares:
        - name: redirect-to-https
      services:
        - name: service2
          port: 80

Теперь в манифестах маршрутизации service1-ingressroute.yaml и service2-ingressroute.yaml добавляется middleware redirect-to-https, которая автоматически перенаправляет HTTP-запросы на HTTPS.

Обновляем манифесты:

kubectl apply -f service1-ingressroute.yaml
kubectl apply -f service2-ingressroute.yaml

Настройка HTTPS IngressRoute

Теперь нам необходимо создать отдельные IngressRoute для HTTPS. Это необходимо, потому что стандартные HTTP-маршруты не обрабатывают TLS, и для работы HTTPS необходимо задать certResolver, который будет использовать Let's Encrypt для автоматического получения сертификатов. В новых IngressRoute указываются entryPoints: websecure и параметр tls, который активирует поддержку шифрования.

Манифест service1-ingressroute-https.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service1-route-https
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`service1.example.com`)
      kind: Rule
      services:
        - name: service1
          port: 80
  tls:
    certResolver: le

Манифест service2-ingressroute-https.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: service2-route-https
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`service2.example.com`)
      kind: Rule
      services:
        - name: service2
          port: 80
  tls:
    certResolver: le

Применяем манифесты для новых роутов:

kubectl apply -f service1-ingressroute-https.yaml
kubectl apply -f service2-ingressroute-https.yaml

Проверка выпуска сертификатов

Проверить, что сертификаты успешно выпущены, можно с помощью команды:

kubectl logs -n traefik -l app.kubernetes.io/name=traefik | grep acme

Теперь доступ к сервисам осуществляется через HTTPS:

  • https://service1.example.com
  • https://service2.example.com

Таким образом, мы настроили автоматическое получение SSL-сертификатов с помощью Let's Encrypt в Traefik и обеспечили безопасное подключение к сервисам.

Настройка дашборда

Traefik предоставляет веб-интерфейс, который позволяет отслеживать состояние маршрутов, сервисов, middleware и других ресурсов, управляемых инстансом Traefik. Дашборд помогает диагностировать проблемы, анализировать маршрутизацию трафика и контролировать конфигурацию.

По умолчанию дашборд Traefik доступен без авторизации, что создает угрозу безопасности, так как любому пользователю будет доступна информация о запущенных сервисах. Чтобы защитить доступ, настроим базовую авторизацию с помощью middleware.

  1. Получим хэш желаемого пароля:

mkpasswd -m bcrypt "password"
  1. Данные для авторизации мы сохраним в секрете Kubernetes, поэтому их нужно закодировать в base64:

echo -n 'логин:полученный_ранее_хэш' | base64
  1. Теперь опишем секрет в манифесте dashboard-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: dashboard-auth-secret
  namespace: traefik
type: Opaque
data:
  users: |
    логин:пароль_закодированный_в_base64
  1. Применим манифест:

kubectl apply -f dashboard-secret.yaml
  1. Теперь опишем middleware в файле dashboard-auth.yaml:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: dashboard-auth
  namespace: traefik
spec:
  basicAuth:
    secret: dashboard-auth-secret
  1. Применяем манифест:

kubectl apply -f dashboard-auth.yaml
  1. Наконец, опишем IngressRoute для дашборда в файле dashboard-ingress.yaml:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: traefik
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`dashboard.example.com`)
      kind: Rule
      middlewares:
        - name: dashboard-auth
      services:
        - kind: TraefikService
          name: api@internal
  tls:
    certResolver: le

Этот манифест задает маршрут для доступа к дашборду Traefik через HTTPS, применяя базовую авторизацию. Описание параметров:

  • entryPoints: websecure — указывает, что маршрут будет доступен только через HTTPS.
  • match: Host(dashboard.example.com) — направляет запросы, полученные для dashboard.example.com, к дашборду.
  • middlewares — применяет созданную ранее middleware dashboard-auth, обеспечивающую базовую HTTP-аутентификацию.
  • services — указывает, что запросы должны направляться к встроенному сервису api@internal, который отвечает за отображение дашборда.
  • tls.certResolver: le — активирует автоматическое получение SSL-сертификата через Let's Encrypt.
  1. Применим манифест:

kubectl apply -f dashboard-ingress.yaml
  1. Теперь обратимся к https://dashboard.example.com. После авторизации вы увидите дашборд.

Была ли статья полезна?
Ваша оценка очень важна
Пока нет комментариев