Traefik как Ingress-контроллер для K8S

от автора

Не секрет, что у K8S отличное коммьюнити и в целом хорошая документация. В ней можно легко найти ответ на многие вопросы. Но как и любая другая документация, она не может покрывать абсолютно всё. В данной статье я попытаюсь привести подробную инструкцию, как развернуть и настроить Traefik для использования в качестве Ingress-контроллера.

image

Что такое Ingress?

Ingress — это объект API, который управляет внешним доступом к сервисам в кластере, главным образом через HTTP / HTTPS. Чтобы Ingress-ресурс заработал, нужен Ingress-контроллер. Если вы используете GCE, то контроллер Ingress уже развернут в мастер. Однако, если вы самостоятельно загрузили кластер, например с kops на AWS, вам нужно развернуть Ingress-контроллер самостоятельно. На minikube это решается включением надстройки Ingress.

Ingress-контроллеры

Роль Ingress-контроллера могут выполнять NGINX Ingress Controller, Kong, Octavia Ingress Controller и др. В этой статье мы рассмотрим такой инструмент как Traefik и посмотрим, как можно использовать его в качестве Ingress-контроллера для сервисов в кластере.

Зачем?

Зачем использовать Ingress-контроллер, если можно предоставить доступ к каждому сервису через NodePort или LoadBalancer? Если кратко, это позволяет получить одну центральную точку для проксирования всего трафика. То есть, с использованием Ingress-контроллера вам понадобится всего один LoadBalancer для Traefik и ничего больше. Эта связка и будет разруливать весь трафик.

Traefik-компоненты

Traefik объявил о поддержке Kubernetes Ingress в версии 1.4. Однако недавно выпущенный Traefik 1.7 имеет опцию publishedService, которая умеет обновлять поле status в Ingress, чего не было в предыдущих версиях. Ниже представлен список компонентов, которые потребуются для работы.

Создайте:

  • namespace
  • service account
  • TLS secret
  • cluster role
  • cluster role binding
  • configmap
  • deployment
  • service for http and https
  • service для Traefik dashboard
  • Ingress

Namespace

Создайте namespace:

kubectl create namespace traefik

TLS Secret

(прим. пер. — в примере далее автор зачем-то дублирует один и тот же конфиг, актуальный конфиг смотрите в README-файле, представленном по ссылке ниже)

Сначала создайте сертификат:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./tls.key -out ./tls.crt -subj "/CN=*.example.com"

Создайте сертификат TLS:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./tls.key -out ./tls.crt -subj "/CN=*.example.com"

Создайте Secret:

kubectl create secret tls traefik-ui-tls-cert --key ./tls.key --cert ./tls.crt

Для удобства я сделал README-файл с этими командами и выложил его в свой GitHub.

ConfigMap

--- apiVersion: v1 kind: ConfigMap metadata:  name: traefik-configmap  namespace: traefik data:  traefik.toml: |    defaultEntryPoints = ["http","https"]     [entryPoints]       [entryPoints.http]      address = ":80"       [entryPoints.https]      address = ":443"        [entryPoints.https.tls]          [[entryPoints.https.tls.certificates]]          CertFile = "/ssl/tls.crt"          KeyFile = "/ssl/tls.key"       [entryPoints.traefik]        address = ":8080"        [entryPoints.traefik.auth.basic]        users = ["admin:$apr1$zjjGWKW4$W2JIcu4m26WzOzzESDF0W/"]     [kubernetes]      [kubernetes.ingressEndpoint]        publishedService = "traefik/traefik"     [ping]    entryPoint = "http"     [api]    entryPoint = "traefik"

По умолчанию EntryPoints это порты 80 и 443.

EntryPoint http слушает :80 и не имеет дополнительных правил

EntryPoint https слушает :443 и содержит правило для подключения TLS-сертификатов.

EntryPoint traefik слушает :8080 и использует basic-аутентификацию. Имя пользователя — admin, пароль — admin.

Определение соответствующего endpoint Ingress в Kubernetes выполняется путем задания publishService и должно состоять из значения namespace и имени service для Traefik. В данном случае это traefik / traefik.

ping или проверка работоспособности будет использовать entryPoint http.

api или dashboard / ui будут использовать entryPoint traefik.

Обратите внимание, что можно определить дополнительные entryPoints с указанием порта. Этот порт может проксировать трафик на какой-либо порт, вместо динамических портов и NodePort.

ClusterRole

Service account для Traefik должен иметь разрешение на обновление поля Ingress status. Это важный параметр, и он еще не представлен в официальной документации Traefik:

--- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata:  name: traefik-ingress-controller rules: - apiGroups:  - ""  resources:  - services  - endpoints  - secrets  verbs:  - get  - list  - watch - apiGroups:  - extensions  resources:  - ingresses  verbs:  - get  - list  - watch - apiGroups:  - extensions  resources:  - ingresses/status  verbs:  - update

Последние 6 строк очень важны для корректной работы.

Deployment

Deployment довольно простой и понятный. Давайте коротко пройдемся по основным блокам:

volumes:  - name: traefik-ui-tls-cert    secret:      secretName: traefik-ui-tls-cert  - name: traefik-configmap    configMap:      name: traefik-configmap

Определите volumes для ConfigMap и Secret, которые затем можно будет использовать в volumeMounts.

volumeMounts:  - mountPath: "/ssl"    name: "traefik-ui-tls-cert"  - mountPath: "/config"    name: "traefik-configmap"

Проверка работоспособности выполняется по 80 порту, как это было определено в ConfigMap.

Откройте порты для всех entryPoints, указанных в конфигурационном файле:

ports:  - name: http    containerPort: 80  - name: https    containerPort: 443  - name: dashboard    containerPort: 8080

Напоминаю, что некоторые примеры и документация в Интернете устарели, поэтому не упустите секцию args, необходимую для работы Traefik:

args: - --logLevel=INFO - --configfile=/config/traefik.toml

Не передавайте дополнительные флаги и аргументы, такие как -api, -ping или -kubernetes, потому что это переопределит настройки, указанные в конфиг-файле.

Service

Первый из сервисов определяет Loadbalancer для entryPoints http и https. Если вы посмотрите Security Group (Ingress) для LoadBalancer, то увидите там открыты порты 80 и 443. K8s создаст LoadBalancer и подключит к узлам, на которых работает Traefik. Если вы хотите создать внутренний ELB, как и я, вам нужно определить аннотации:

--- kind: Service apiVersion: v1 metadata:  name: traefik  namespace: traefik  annotations: {}    # service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0 spec:  selector:    k8s-app: traefik-ingress  ports:  - protocol: TCP    port: 80    name: http  - protocol: TCP    port: 443    name: https  type: LoadBalancer

Service (for Dashboard)

Теперь самое интересное! Поскольку Dashboard использует basic-аутентификацию, мне потребовался https. Для использования SSL нам нужно перенаправлять трафик на порт :8080, на котором работает Dashboard. Как видите, он очень прост. Вся магия происходит в Ingress.

--- kind: Service apiVersion: v1 metadata:  name: traefik-dashboard  namespace: traefik spec:  selector:    k8s-app: traefik-ingress  ports:  - port: 8080    name: dashboard

Ingress (for Dashboard)

Магия заключается в том, что проксирование защищенного трафика к Dashboard’у производится через сам Traefik. Управление Traefik в Ingress производится с помощью аннотаций Traefik:

--- apiVersion: extensions/v1beta1 kind: Ingress metadata:  name: traefik-dashboard-ingress  namespace: traefik  annotations:    kubernetes.io/ingress.class: traefik    traefik.ingress.kubernetes.io/frontend-entry-points: http,https    traefik.ingress.kubernetes.io/redirect-entry-point: https    traefik.ingress.kubernetes.io/redirect-permanent: "true" spec:  rules:  - host: traefik-ui.example.com    http:      paths:      - path: /        backend:          serviceName: traefik-dashboard          servicePort: 8080

Потребовалось всего 4 простые и понятные аннотации.

Разумеется, для обеспечения полной работоспособности нужно создать DNS-запись traefik-ui.example.com, которая будет указывать на ваш ELB.

Было бы здорово, если бы это (прим. пер.: имеется в виду создание DNS-записей) производилось автоматически? Не проблема, я напишу об автоматическом создании DNS-записей в следующей статье.

Ссылки

Готовый deployment.yaml файл можно скачать в моём репозитории Github. Если в процессе настройки у вас возникнут трудности, не стесняйтесь — спрашивайте.

Напутствие от переводчика

Читайте другие статьи в нашем блоге:

Бэкапы Stateful в Kubernetes

Резервное копирование большого количества разнородных web-проектов

Telegram-бот для Redmine. Как упростить жизнь себе и людям


ссылка на оригинал статьи https://habr.com/company/nixys/blog/427655/


Комментарии

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

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