Traefik для Microk8s

Microk8s имеет достаточно хорошую систему плагинов. Один из них – это плагин Траефик (ссылка на исходник) для реализации концепции Ingress.

Простыми словами: у меня есть 1 публичный IP-адрес и несколько сайтов, которые хотелось бы сделать доступными. И еще чтобы сертификаты https сами бесплатно получались и обновлялись. Вот это и позволяет сделать Траефик.

При этом для https требуется браузер с поддержкой SNI (например, IE8/WindowsXP не поддерживает, а современные поддерживают), поэтому лучше на всякий случай не делать обязательное жесткое перенаправление на https (хотя пример как это сделать на уровне Траефика будет в последнем примере).

К сожалению, конкретно этим плагином не получилось воспользоваться. Приведу что хотелось по-другому:

  • достаточно одного экземпляра, т.к. в кластере есть metallb, а сам Траефик очень производительный
  • сервис должен быть типа LoadBalancer, т.к. в кластере есть metallb (это вообще общая болезнь плагинов – практически для всех с ui добавлял сервисы LoadBalancer, чтобы получить к ним доступ)
  • хочется видеть админские странички, но только внутри сети (не выкладывать их в Ingress, а оставить на отдельном сервисе LoadBalancer)
  • интеграция с Prometheus
  • версия не годовалой давности (не так, чтобы важно, но звоночек)

Так что воспользовалься helm:

helm repo add traefik https://helm.traefik.io/traefik
helm repo update
k create ns traefik
k ns traefik
helm -n traefik install traefik traefik/traefik --values traefik-values.yaml
k apply -f traefik-extra.yaml

Со своими настройками:

ingressRoute:
  dashboard:
    enabled: false
logs:
  general:
    level: INFO
  access:
    enabled: true
globalArguments:
  - "--global.checknewversion=false"
  - "--global.sendanonymoususage=false"
additionalArguments:
  - --providers.kubernetesingress.ingressendpoint.ip=my.publicInternet.ip.address
  - --api.insecure=true
service:
  spec:
    loadBalancerIP: my.publicLan.ip.address
persistence:
  enabled: true
certResolvers:
  letsencrypt:
    email: my@example.com
    tlsChallenge: true
    storage: /data/letsencrypt.json
# this is due to incorrect PV implementation in microk8s (storage plugin)
securityContext:
 runAsNonRoot: false
 runAsUser: 0
 runAsGroup: 0
podSecurityContext:
  fsGroup: 0

Отмечу, что со storage плагином права на папку были некорректными, поэтому пришлось снизить безопасность. Хотя для дома это и не особая проблема, но поменяю, когда перейду на openebs плагин для PV.

Cверх хелма еще добавил доступ к админке из локальной сети и использования только безопасных протоколов:

---
apiVersion: v1
kind: Service
metadata:
  name: traefik-ui
  namespace: traefik
spec:
  type: LoadBalancer
  loadBalancerIP: my.publicLan2.ip.address
  selector:
    app.kubernetes.io/name: traefik
    app.kubernetes.io/instance: traefik
  ports:
    - name: admin
      port: 80
      targetPort: 9000
      protocol: TCP
---
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
  name: default
  namespace: traefik
spec:
  minVersion: VersionTLS12

Пример как пользоваться (для http, https и redirect-to-https для автоматического редиректа на https):

---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  namespace: test1
  name: test1
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`my.example.com`)
    kind: Rule
    # middlewares:
    # - name: redirect-to-https
      # namespace: test1
    services:
    - name: test1
      port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: test1-tls
  namespace: test1
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`my.example.com`)
    kind: Rule
    services:
    - name: test1
      port: 80
  tls:
    certResolver: letsencrypt
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-to-https
  namespace: test1
spec:
  redirectScheme:
    scheme: https
    permanent: true