Traefik — это ингресс контроллер и реверс прокси для работы в облачных средах и Kubernetes. Он автоматически обнаруживает сервисы, обеспечивает SSL/TLS-терминацию и расширенные возможности маршрутизации. Использование Traefik в Kubernetes позволяет гибко управлять маршрутизацией трафика к сервисам внутри кластера.
Перейдите во вкладку «Дополнения» в панели управления кластером.
Найдите Traefik и нажмите на него.
values.yaml
для кастомизации установки или оставить настройки по умолчанию. Запустите установку, нажав на кнопку «Установить».traefik
запущены и находятся в статусе «Running»:kubectl get pods -n traefik
По умолчанию в установленной конфигурации Traefik использует четыре entryPoints
(входные точки):
web
)websecure
)traefik
)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
, который:
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-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>
Манифест 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
Определим сервисы, к которым 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
В манифесте 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, обеспечили маршрутизацию и балансировку нагрузки.
При использовании Traefik можно получать SSL-сертификаты двумя способами:
Выбор метода зависит от конфигурации кластера. Если используются другие Ingress-контроллеры, рекомендуется cert-manager для централизованного управления сертификатами. Если же в кластере используется только Traefik, можно воспользоваться встроенной функцией получения сертификатов.
Для включения поддержки Let's Encrypt необходимо изменить конфигурацию Traefik:
Перейдите в панель управления кластером → «Дополнения» → выберите Traefik.
Включите режим продвинутой установки.
Приведите конфигурацию к виду:
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"
Что изменилось:
DaemonSet
. В этом режиме сертификаты средствами Traefik получить невозможно. Поэтому тип развёртывания меняется на Deployment
.additionalArguments
. В --certificatesresolvers.le.acme.email
укажите свою почту для регистрации в Let's Encrypt.После обновления убедитесь, что конфигурация применена корректно:
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
Создадим 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
, добавив 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
Теперь нам необходимо создать отдельные 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.
Получим хэш желаемого пароля:
mkpasswd -m bcrypt "password"
Данные для авторизации мы сохраним в секрете Kubernetes, поэтому их нужно закодировать в base64:
echo -n 'логин:полученный_ранее_хэш' | base64
Теперь опишем секрет в манифесте dashboard-secret.yaml
:
apiVersion: v1
kind: Secret
metadata:
name: dashboard-auth-secret
namespace: traefik
type: Opaque
data:
users: |
логин:пароль_закодированный_в_base64
Применим манифест:
kubectl apply -f dashboard-secret.yaml
Теперь опишем middleware в файле dashboard-auth.yaml
:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
namespace: traefik
spec:
basicAuth:
secret: dashboard-auth-secret
Применяем манифест:
kubectl apply -f dashboard-auth.yaml
Наконец, опишем 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.Применим манифест:
kubectl apply -f dashboard-ingress.yaml
Теперь обратимся к https://dashboard.example.com
. После авторизации вы увидите дашборд.