автоматизировать letsencrypt в приложении kubernetes с большим количеством доменов - PullRequest
2 голосов
/ 11 января 2020

У меня есть приложение узла, которое загружает свои данные на основе доменного имени. домены настроены с CNAME, например app.service.com (это приложение узла).

Приложение Node видит домен запроса и отправляет запрос API для получения данных приложения.

, например: domain.com CNAME app.service.com -> затем приложение узла запрашивает API для домена. com data

проблема заключается в настройке HTTPS (с letsencrypt) для всех доменов. Я думаю, что cert-manager может помочь, но понятия не имеет, как автоматизировать это без необходимости вручную изменять конфигурационный файл для каждого нового домена.

или есть лучший способ добиться этого в Kubernetes?

1 Ответ

1 голос
/ 14 января 2020

Стандартный метод поддержки более чем одного имени домена и / или имени субдомена состоит в использовании одного сертификата SSL и реализации SAN (Subject Alternative Names). Дополнительные доменные имена хранятся вместе в SAN. Все SSL-сертификаты поддерживают SAN, но не все центры сертификации выдают многодоменные сертификаты. Let's Encrypt поддерживает SAN , поэтому их сертификаты будут соответствовать вашей цели.

Сначала вам нужно создать задание в нашем кластере, в котором для запуска оболочки используется образ. скрипт. Сценарий раскрутит службу HTTP, создаст сертификаты и сохранит их в заранее заданном секрете. Ваш домен и адрес электронной почты являются переменными среды, поэтому обязательно укажите их в:

apiVersion: batch/v1
kind: Job
metadata:
  name: letsencrypt-job
  labels:
    app: letsencrypt
spec:
  template:
    metadata:
      name: letsencrypt
      labels:
        app: letsencrypt
    spec:
      containers:
      # Bash script that starts an http server and launches certbot
      # Fork of github.com/sjenning/kube-nginx-letsencrypt
      - image: quay.io/hiphipjorge/kube-nginx-letsencrypt:latest
        name: letsencrypt
        imagePullPolicy: Always
        ports:
        - name: letsencrypt
          containerPort: 80
        env:
        - name: DOMAINS
          value: kubernetes-letsencrypt.jorge.fail # Domain you want to use. CHANGE ME!
        - name: EMAIL
          value: jorge@runnable.com # Your email. CHANGE ME!
        - name: SECRET
          value: letsencrypt-certs
      restartPolicy: Never

У вас есть работа, и вы можете создать службу для направления трафика c на эту работу:

apiVersion: v1
kind: Service
metadata:
  name: letsencrypt
spec:
  selector:
    app: letsencrypt
  ports:
  - protocol: "TCP"
    port: 80

Эта работа теперь будет в состоянии выполнить, но у вас все еще есть три вещи, которые нам нужно сделать, прежде чем наша работа действительно преуспеет, и мы сможем получить доступ к нашей службе через HTTP.

Во-первых, вам нужно создать секрет для работы, чтобы обновлять и хранить наши сертификаты. Поскольку у нас нет сертификатов при создании секрета, секрет будет начинаться пустым.

apiVersion: v1
kind: Secret
metadata:
  name: letsencrypt-certs
type: Opaque

# Create an empty secret (with no data) in order for the update to work

Во-вторых, вам нужно будет добавить секрет в контроллер Ingress, чтобы он извлек его. сертификаты Помните, что именно контроллер Ingress знает о нашем хосте, поэтому наши сертификаты должны быть указаны здесь. Добавление нашего секрета к контроллеру Ingress будет выглядеть примерно так:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "kubernetes-demo-app-ingress-service"
spec:
  tls:
  - hosts:
    - kubernetes-letsencrypt.jorge.fail # Your host. CHANGE ME
    secretName: letsencrypt-certs # Name of the secret
  rules:

Наконец, вам нужно перенаправить трафик c через хост, на работу, через наше развертывание Nginx. Для этого вы добавите новый маршрут и восходящий поток в нашу конфигурацию Nginx. Это можно сделать через контроллер Ingress, добавив запись /.well-known/* и перенаправив ее в службу letsencrypt. Это сложнее, потому что вам также необходимо добавить маршрут работоспособности к заданию, поэтому вместо этого вы просто перенаправите трафик c через развертывание Nginx:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  default.conf: |

...

    # Add upstream for letsencrypt job
    upstream letsencrypt {
      server letsencrypt:80 max_fails=0 fail_timeout=1s;
    }

    server {
      listen 80;

...

      # Redirect all traffic in /.well-known/ to letsencrypt
      location ^~ /.well-known/acme-challenge/ {
        proxy_pass http://letsencrypt;
      }
    }

После того, как вы примените все эти изменения, уничтожьте ваши Nginx Pod, чтобы убедиться, что ConfigMap правильно обновляется в новых Pod:

$ kubectl get pods | grep ngi | awk '{print $1}' | xargs kubectl delete pods

Убедитесь, что это работает.

Чтобы убедиться, что это работает, вы должны убедиться, что задание действительно успешно выполнено. Вы можете сделать это, получив работу через kubectl, вы также можете проверить панель управления Kubernetes.

$ kubectl get job letsencrypt-job
NAME              DESIRED   SUCCESSFUL   AGE
letsencrypt-job   1         1            1d

Вы также можете проверить секрет, чтобы убедиться, что сертификаты были правильно заполнены. Вы можете сделать это через kubectl или через панель инструментов:

$ kubectl describe secret letsencrypt-certs

Name:   letsencrypt-certs
Namespace:  default
Labels:   <none>
Annotations:
Type:   Opaque
Data
====
tls.crt:  3493 bytes
tls.key:  1704 bytes

Теперь, когда вы видите, что сертификаты были успешно созданы, вы можете сделать самый последний шаг во всем этом процессе. Чтобы контроллер Ingress мог уловить изменение секрета (от отсутствия данных до наличия сертификатов), необходимо обновить его, чтобы он был перезагружен. Чтобы сделать это, мы просто добавим метку времени в качестве метки в контроллер Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "kubernetes-demo-app-ingress-service"
  labels:
    # Timestamp used in order to force reload of the secret
    last_updated: "1494099933"
...

Пожалуйста, посмотрите на: kubernetes-letsencrypt .

...