В Kubernetes: защитите программу, работающую на порту 3000, с помощью Traefik, Cert Manager и http challenge.

Вопрос или проблема

Здравствуйте и спасибо за ваше время. Я постараюсь объяснить, что представляет из себя мой эксперимент.
В Kubernetes у меня развернуто приложение. Я могу получить к нему доступ с помощью балансировщика нагрузки. И с использованием Traefik я могу получить к нему доступ через HTTP. Я хотел бы получить к нему доступ через HTTPS. Чтобы достичь этого результата, я пытаюсь следовать видео на YouTube и документации Traefik и использовать Cert Manager.
Мне нравится работать с файлами YAML, но если есть лучший способ, пожалуйста, скажите мне, так как я учусь на практике.
Я опубликую все теоретические файлы YAML, надеясь, что Serverfault предоставит мне достаточно места, чтобы опубликовать их.

#001-role.yml
        kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: traefik-role
    
    rules:
      - apiGroups:
          - ""
        resources:
          - services
          - secrets
          - nodes
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - discovery.k8s.io
        resources:
          - endpointslices
        verbs:
          - list
          - watch
      - apiGroups:
          - extensions
          - networking.k8s.io
        resources:
          - ingresses
          - ingressclasses
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - extensions
          - networking.k8s.io
        resources:
          - ingresses/status
        verbs:
          - update
      - apiGroups:
          - traefik.io
        resources:
          - middlewares
          - middlewaretcps
          - ingressroutes
          - traefikservices
          - ingressroutetcps
          - ingressrouteudps
          - tlsoptions
          - tlsstores
          - serverstransports
          - serverstransporttcps
        verbs:
          - get
          - list
          - watch

#002-account.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-account

#003-role-binding.yml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-role
subjects:
  - kind: ServiceAccount
    name: traefik-account
    namespace: default 

#004-traefik.yml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: traefik-deployment
  labels:
    app: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-account
      containers:
        - name: traefik
          image: traefik:v3.2
          args:
            - --api.insecure
            - --providers.kubernetesingress
          ports:
            - name: web
              containerPort: 80
            - name: dashboard
              containerPort: 8080

#005-traefik-service.yml
apiVersion: v1
kind: Service
metadata:
  name: traefik-dashboard-service

spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: dashboard
  selector:
    app: traefik
---
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-service

spec:
  type: LoadBalancer
  ports:
    - targetPort: web
      port: 80
  selector:
    app: traefik

#006-program-frontend-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: kompose convert -f compose.yml
    kompose.version: 1.34.0 (HEAD)
  labels:
    io.kompose.service: program-frontend
  name: program-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: program-frontend
  template:
    metadata:
      annotations:
        kompose.cmd: kompose convert -f compose.yml
        kompose.version: 1.34.0 (HEAD)
      labels:
        io.kompose.service: program-frontend
    spec:
      containers:
        - env:
            - name: API_GATEWAY_BASE_URL
              value: http://edge-thinghy:9000
          image: program-image
          name: program-frontend
          ports:
            -  name: program-frontend
               containerPort: 3000
               protocol: TCP
      imagePullSecrets:
        - name: ghcr-secret
      restartPolicy: Always

#007-program-frontend-service.yml
apiVersion: v1
kind: Service
metadata:
  annotations:
    kompose.cmd: kompose convert -f compose.yml
    kompose.version: 1.34.0 (HEAD)
  labels:
    io.kompose.service: program-frontend
  name: program-frontend
spec:
  ports:
    - name: program-frontend
      protocol: TCP
      port: 3000
      targetPort: program-frontend
  selector:
    io.kompose.service: program-frontend

#008-edit-program-service.yml
apiVersion: v1
kind: Service
metadata:
  name: program-frontend
spec:
  ports:
    - name: program-frontend
      port: 80
      targetPort: 3000
  selector:
    io.kompose.service: program-frontend

#009-program-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: program-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: program-frontend
            port: 
              name: program-frontend

#010-challenge.yml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
 name: program-challenge
 namespace: default
spec:
 acme:
   email: [email protected]
   server: https://acme-v02.api.letsencrypt.org/directory
   privateKeySecretRef:
     name: program-issuer-account-key
   solvers:
     - http01:
         ingress:
           class: traefik

#011-ingress-rule.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: program-ssl-ingress
 namespace: default
 annotations:
   cert-manager.io/issuer: "program-challenge"
spec:
 tls:
   - hosts:
       - program-demo.example.domain
     secretName: tls-program-ingress-http
 rules:
   - host: program-demo.example.domain
     http:
       paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: program-frontend
               port:
                 name: program-frontend

#012-redirect-http-to-https.yml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: program-frontend-redirect
spec:
  redirectScheme:
    scheme: https
    permanent: true

Если я правильно понял, в этот момент я должен иметь возможность получить доступ к https://program-demo.example.domain, но я получаю доступ только к http://program-demo.example.domain. Я что-то неправильно понял в документации? Что-то не так в моем рассуждении? Спасибо за ваше время заранее.

Ответ или решение

Согласно вашему запросу, мы обсудим, как использовать Traefik и Cert-Manager для обеспечения HTTPS-доступа к вашему приложению в Kubernetes, которое работает на порту 3000. Анализируя ваши YAML-файлы и структуру, я помогу вам понять, как различить возможные ошибки и что может быть улучшено в вашей конфигурации.

Обзор архитектуры

  1. Traefik — это обратный прокси-сервер и балансировщик нагрузки, который предоставляет динамическое маршрутизирование на основе различных поставщиков (providers) и поддерживает автоматическое получение SSL-сертификатов через Cert-Manager.

  2. Cert-Manager — это инструмент для управления сертификатами в Kubernetes, который позволяет автоматизировать процесс получения и обновления SSL-сертификатов.

  3. HTTP Challenge — вызов, при котором Cert-Manager использует HTTP для проверки доменных прав, прежде чем выдать SSL-сертификат.

Проверка текущих конфигураций

Давайте рассмотрим ваши конфигурации и выделим возможные проблемные области:

1. Конфигурация Ingress

Ваш YAML-файл для Ingress (009-program-ingress.yml) выглядит корректно, поскольку он маршрутизирует трафик на ваш сервис program-frontend. Однако, стоит добавить middleware для перенаправления HTTP на HTTPS. Обратите внимание, что ваш Ingress должен использовать middleware, который вы создали в 012-redirect-http-to-https.yml.

Обновите ваш Ingress следующим образом:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: program-ssl-ingress
  annotations:
    cert-manager.io/issuer: "program-challenge"
    traefik.ingress.kubernetes.io/router.middlewares: default/program-frontend-redirect
spec:
  tls:
    - hosts:
        - program-demo.example.domain
      secretName: tls-program-ingress-http
  rules:
    - host: program-demo.example.domain
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: program-frontend
                port:
                  name: program-frontend

2. Актуальность Issuer

Убедитесь, что ваш Issuer (010-challenge.yml) настроен корректно. Проверьте, что Email-адрес, который вы указали, содержит корректный формат и доступ к нему возможен. Существует возможность, что у вас возникла проблема с валидацией ACME.

3. TLS-секрет

Ваш tls secret (tls-program-ingress-http в 011-ingress-rule.yml) должен быть создан, после того как Cert-Manager успешно получите сертификат. Проверьте наличие этого секрета:

kubectl get secrets -n default

Если секрета нет, возможно, Cert-Manager не смог получить сертификат, и затем это может быть проверено через логи:

kubectl logs -f deployment/cert-manager -n cert-manager

4. Перенаправление HTTP на HTTPS

Having added the middleware to the Ingress as indicated above, ensure your Traefik deployment supports middleware configuration:

args:
  - --api.insecure
  - --providers.kubernetesingress
  - --entrypoints.web.address=:80
  - --entrypoints.websecure.address=:443

Заключение

После всех изменений следует выполнить полную перезагрузку измененных ресурсов и проверить наличие новых логов. Исправьте конфигурацию, и вы должны получить доступ к вашему приложению через HTTPS по адресу https://program-demo.example.domain.

Если проблемы продолжаются, откройте логи Traefik и Cert-Manager, чтобы пошагово отследить ошибки. Также проверьте доступность вашего домена и сертификата через сеть (например, за пределами вашего локального окружения).

Этот подход поможет вам не только установить безопасную HTTPS-зависимость, но и улучшить ваши знания о Kubernetes и работе с сетевыми компонентами.

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

Капча загружается...