Пример манифеста Kubernetes для запуска Swagger

Обновлено и опубликовано Опубликовано:

Используемые термины: SwaggerKubernetes.

Swagger — стандартный способ дать любому REST API удобный интерфейс для просмотра и тестирования. В этой инструкции разберем манифесты для развертывания Swagger UI и Swagger Editor в кластере Kubernetes: ConfigMap, Deployment, Ingress и Service.

Примеры манифестов для Swagger

Создадим каталог для файлов манифестов и перейдем в него:

mkdir -p /opt/swagger && cd /opt/swagger

Рассмотрим по отдельности минимальный набор манифестов.

ConfigMap с адресом Swagger-спецификации

Создадим ConfigMap, в котором зададим адрес OpenAPI-спецификации и базовый путь интерфейса:

vi config.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: swagger-ui-config
  namespace: default
  labels:
    app.kubernetes.io/name: swagger
    app.kubernetes.io/part-of: swagger
data:
  URL: "https://petstore.swagger.io/v2/swagger.json"
  BASE_URL: /

* где:

  • URL — адрес спецификации, которую загрузит Swagger UI. По умолчанию указан тестовый Petstore API, но сюда же можно подставить и Kubernetes API documentation в формате OpenAPI — тогда интерфейс покажет Kubernetes API reference прямо в браузере.
  • BASE_URL — путь, по которому интерфейс будет доступен внутри контейнера.

Deployment для Swagger UI и Swagger Editor

В одном Deployment запустим два контейнера — интерфейс просмотра (ui) и редактор спецификаций (editor). Для обоих настроены запросы/лимиты ресурсов и проверки готовности и живучести. Отдельно зафиксируем стратегию обновления, чтобы при выкатке новой версии не было простоя:

vi deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: swagger
  namespace: default
  labels:
    app.kubernetes.io/name: swagger
    app.kubernetes.io/part-of: swagger
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app.kubernetes.io/name: swagger
  template:
    metadata:
      labels:
        app.kubernetes.io/name: swagger
        app.kubernetes.io/part-of: swagger
    spec:
      containers:
        - name: ui
          image: swaggerapi/swagger-ui:v5.17.14
          imagePullPolicy: IfNotPresent
          ports:
            - name: ui
              containerPort: 8080
              protocol: TCP
          envFrom:
            - configMapRef:
                name: swagger-ui-config
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 256Mi
          readinessProbe:
            httpGet:
              path: /
              port: ui
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /
              port: ui
            initialDelaySeconds: 10
            periodSeconds: 20
        - name: editor
          image: swaggerapi/swagger-editor:v4.13.1
          imagePullPolicy: IfNotPresent
          env:
            - name: PORT
              value: "8081"
            - name: BASE_URL
              value: /editor
          ports:
            - name: editor
              containerPort: 8081
              protocol: TCP
          resources:
            requests:
              cpu: 50m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
          readinessProbe:
            httpGet:
              path: /editor
              port: editor
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /editor
              port: editor
            initialDelaySeconds: 15
            periodSeconds: 20

* readinessProbe и livenessProbe проверяют корневой путь каждого контейнера — если ответ не приходит вовремя, под будет перезапущен. strategy с maxUnavailable: 0 гарантирует, что при обновлении старый под не остановится, пока новый не пройдет readinessProbe.

Ingress для доступа по HTTPS

Настроим Ingress через Traefik: путь /editor ведет на Swagger Editor, а корневой / — на Swagger UI. Оба маршрута защищены TLS-сертификатом.

В вашем кластере кубернетис может использоваться другой ingress-контроллер. Необходимо уто учитывать и использовать свои настройки.

Создадим файл:

vi ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: swagger
  namespace: default
  labels:
    app.kubernetes.io/part-of: swagger
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
    traefik.ingress.kubernetes.io/router.tls.certresolver: default
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - swagger.dmosk.ru
  rules:
    - host: swagger.dmosk.ru
      http:
        paths:
          - path: /editor
            pathType: Prefix
            backend:
              service:
                name: swagger
                port:
                  name: editor
          - path: /
            pathType: Prefix
            backend:
              service:
                name: swagger
                port:
                  name: ui

* замените swagger.dmosk.ru на свой домен — от него зависит, для какого хоста будет выпущен TLS-сертификат.

Service для проксирования портов

Опишем Service, который свяжет порты Ingress с портами контейнеров ui и editor:

vi services.yml

apiVersion: v1
kind: Service
metadata:
  name: swagger
  namespace: default
  labels:
    app.kubernetes.io/name: swagger
    app.kubernetes.io/part-of: swagger
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: swagger
  ports:
    - name: ui
      port: 80
      targetPort: ui
      protocol: TCP
    - name: editor
      port: 8081
      targetPort: editor
      protocol: TCP

Применение манифестов

Применим все файлы из каталога разом и проверим, что поды запустились:

kubectl apply -f ./

kubectl get pods

Мы должны увидеть один под swagger-xxx в статусе Running — внутри него работают оба контейнера, ui и editor. Swagger развернут и доступен через Ingress.

Просмотр Kubernetes API через Swagger UI

Рассмотрим, как можно применить наш свагер на практике.

Kubernetes API — тоже REST API, и он отдает свою спецификацию через discovery api по пути /openapi/v2 (Swagger 2.0) или /openapi/v3 (OpenAPI 3.0). Для быстрого просмотра поднимем прокси к API-серверу:

kubectl proxy --port=8001

* команда открывает локальный прокси к API-серверу кластера с авторизацией из текущего kubeconfig, но слушает только 127.0.0.1 — доступ есть только с вашей машины. Кластерный под со Swagger UI из предыдущих разделов до него не достучится, они в разных сетевых пространствах.

Для просмотра проще поднять отдельный локальный контейнер Swagger UI в сетевом режиме host — тогда он увидит localhost:8001 напрямую:

docker run --rm --network host -e URL=http://localhost:8001/openapi/v2 swaggerapi/swagger-ui

* режим --network host работает на Linux. На Docker Desktop (macOS/Windows) вместо localhost используем host.docker.internal.

Открываем http://localhost:8080 и получаем Kubernetes API reference: все встроенные ресурсы (pods, deployments, services) и агрегированные через Kubernetes APIService — например, metrics-server, если он установлен в кластере. Это удобная замена ручным запросам вида Kubernetes API curl — тот же результат, но с навигацией и возможностью отправить запрос прямо из браузера.

Решение проблем

Рассмотрим наиболее частые ошибки, с которыми можно столкнуться.

Ошибка сертификата

При попытке открыть страницу свагера по настройному URL-адресу мы видим предупреждение от системы безопасности браузера, что сертификат не проходит проверку подлинности.

Причина: сертификат для домена не выпускается, Ingress остается без TLS.

Решение: проверяем, что A-запись домена указывает на IP кластера, и что порт 80 доступен извне — без него Traefik не пройдет HTTP-01 challenge.

Не запускается pod для swagger

При просмотре статуса Pod видим, что swagger падает в CrashLoopBackOff.

Причина: приложение при запуске сталкивается с критической ошибкой, что приводит к перезапуску контейнера.

Решение: смотрим логи контейнера editor — чаще всего дело в занятом порту 8081 или в неверном значении BASE_URL, не совпадающем с путем в Ingress.

Что учесть для продакшена

Если Swagger UI начнет запрашивать свои статические файлы по абсолютным путям, единый Ingress с путями /editor и / может повести себя нестабильно — для продакшена надежнее развести UI и Editor по разным поддоменам. Также стоит добавить securityContext с runAsNonRoot: true, чтобы контейнеры не работали от root — конкретный UID нужно проверить в документации к используемым образам swagger-ui и swagger-editor.

# DevOps # Kubernetes # Интернет # Контейнеризация
Дмитрий Моск — частный мастер
Был ли вам полезен этот скрипт?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Заказать настройку контейнеризации

Нужна бесплатная консультация?

Скрипты

Пример манифеста для запуска Swagger в Kubernetes

Пример скрипта для миграции запущенной виртуальной машины Proxmox с ZFS репликацией

Пример манифеста для развертывания Hermes AI в Kubernetes

Пример файла docker-compose для развертывания брокера Kafka

Пример сценария docker-compose для запуска сервера Dependency-Track

Запуск SonarQube Server в контейнере с помощью docker-compose

Пример docker-compose файла для запуска сервера rustdesk в docker

Другие скрипты

Все статьи

Нужен скрипт? Опишите его назначение:





Реклама