Skip to content

Документация по использованию CRD Streamer

Кастомный тип Streamer отвечает за запуск одного экземпляра видеостримингового сервера.

Он нужен для того, чтобы:

  • обеспечить правильный запуск стримера с сохранением гарантий надежного рестарта при проблемах связи с серверами лицензий
  • безопасно разделить доступ к видеоконтенту и API
  • обновлять все основные параметры без рестарта медиасервера
  • забирать апи ключи из kubernetes Secret

Описание Streamer

Оператор для CRD Streamer описывает управление одним экземпляром медиасервера, подразумевая наличие одного экземпляра на ноду, но не делает это жестким требованием.

Оператор поддерживает ровно один Pod на каждый экземпляр Streamer.

Все изменения настроек, которые можно сделать без рестарта Pod, происходят без этого рестарта, что снижает количество даунтаймов.

Основные настройки с апи ключами, которые надо держать в безопасности, достаются из kubernetes Secret:

  • Настройка edit_auth, отвечающая за авторизацию API
  • cluster_key
  • config_external auth

Quickstart

Для запуска достаточно сделать минимальные шаги, позволяющие запуститься в hostPort режиме.

Вам нужно подготовить:

  • экземпляр кубернетеса
  • название ноды, например stream-node
  • IP адрес этой ноды, далее IP
  • лицензионный ключ LICENSE_KEY

Подготовить следующий файл simple-streamer.yaml:

apiVersion: media.flussonic.com/v1alpha1
kind: Streamer
metadata:
  name: simple
spec:
  version: "v26.01-5"
  licenseKey:
    secretKeyRef:
      name: flussonic-license
      key: license_key
      optional: false
  nodeName: "stream-node"
  adminHostPort: 81
kubectl apply -f https://flussonic.github.io/media-server-operator/latest/operator.yaml
kubectl create secret generic flussonic-license --from-literal=license_key="${LICENSE_KEY}"
kubectl apply -f simple-streamer.yaml

Пароль можно будет забрать из секрета:

kubectl get -o json secret/streamer-sample-license-storage | jq -r .data.edit_auth | base64 -d ; echo

Логин-пароль будут через двоеточие.

После чего можно обратиться к http://${IP}:81/ и получите доступ к интерфейсу.

Использование с Ingress

Как правило забрать порты 80 и 443 на компьютере под управлением кубернетеса не получается, они используются самим оркестратором.

Балансировщик стримингового трафика может отправить клиента проигрывать видео напрямую на нужную ноду.

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

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

Другой вариант - с использованием локального трафика:

apiVersion: v1
kind: Service
metadata:
  name: mediaserver
spec:
  ports:
  - port: 80
    targetPort: 80
    name: payload
  - port: 81
    targetPort: 81
    name: api
  selector:
    app.kubernetes.io/component: streamer
  internalTrafficPolicy: Local
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mediaserver
  annotations:
    traefik.ingress.kubernetes.io/service.nativelb: "true"
    nginx.ingress.kubernetes.io/service-upstream: "true"
spec:
  rules:
    - host: node1-mycluster.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mediaserver
                port:
                  number: 80

В этой конфигурации указаны две аннотации: для traefik и для nginx в качестве ingress controller.

Конфигурация стримера

Оператор позволяет добавлять дополнительный текст в конфиг медиасервера через опцию configExtra:

apiVersion: media.flussonic.com/v1alpha1
kind: Streamer
metadata:
  name: simple
spec:
  version: "26.01-5"
  configExtra:
    auth.conf: |
      auth_backend watcher {
        backend http://central/vsaas/api/camera_auth;
      }

Все перечисленные в configExtra секции будут склеены вместе в конфиг и загружены в стример.

При обновлении этого конфига рестарта не будет, оператор загрузит новый конфиг на лету.

Хранение видео

Запись видео осуществляется на локальный диск каждой ноды (оптимальное по цене и скорости решение).

Резервирование и репликация осуществляются оркестратором уровнем выше, чем оператор Streamer.

Основной подход следующий:

apiVersion: media.flussonic.com/v1alpha1
kind: Streamer
metadata:
  name: simple
spec:
  version: "v26.01-5"
  configExtra:
    dvr.conf: |
      dvr watcher {
        root /storage;
        limits 7d;
      }
  volumes:
    - name: storage
      mountPath: /storage
      hostPath:
        path: /storage
        type: DirectoryOrCreate

Используется hostPath для локального хранения данных.

Мониторинг и статусы

Оператор отслеживает состояние стримера и выставляет условия (Conditions) в статусе ресурса Streamer. Эти условия можно использовать для мониторинга и алертинга.

Условие StreamerReady

Показывает готовность стримера к работе. Может иметь следующие значения:

  • True - стример готов и работает (StatefulSet имеет готовую реплику)
  • False - стример не готов (StatefulSet не найден или не имеет готовых реплик)
  • Unknown - состояние неизвестно (ошибка при получении информации о StatefulSet)

Проверить статус можно командой:

kubectl get streamer <name> -o jsonpath='{.status.conditions[?(@.type=="StreamerReady")]}'

Так же можно дождаться работоспособности стримера:

kubectl wait --for=condition=StreamerReady=true streamer/<name> --timeout=300s

Условие StreamerConfigSaved

Показывает результат последней попытки сохранения конфигурации через API. Может иметь следующие значения:

  • True - конфигурация успешно сохранена (HTTP статус 200)
  • False - сохранение конфигурации запрещено (HTTP статус 403)
  • Unknown - ошибка при сохранении конфигурации (HTTP статус 500+, сетевые ошибки или другие проблемы)

Проверить статус можно командой:

kubectl get streamer <name> -o jsonpath='{.status.conditions[?(@.type=="StreamerConfigSaved")]}'

Health Checks

Оператор автоматически настраивает пробы здоровья для Pod стримера:

  • Liveness Probe - проверяет, что стример жив. Использует endpoint /streamer/api/v3/monitoring/liveness. Начинает проверку через 10 секунд после старта, проверяет каждые 3 секунды.
  • Readiness Probe - проверяет, что стример готов принимать трафик. Использует endpoint /streamer/api/v3/monitoring/readiness. Начинает проверку через 2 секунды после старта, проверяет каждые 2 секунды.
  • Startup Probe - проверяет, что стример запустился. Использует endpoint /streamer/api/v3/monitoring/readiness. Начинает проверку через 2 секунды после старта, проверяет каждые 2 секунды, допускает до 30 неудачных попыток.

Аннотации на подах

Оператор автоматически устанавливает аннотации на подах стримера, которые могут использоваться внешними системами для обнаружения и маршрутизации:

  • streamer.flussonic.com/api-endpoint - URL для доступа к API стримера. Формат: http://<pod-name>-0.<headless-service>.<namespace>.svc.cluster.local:<port>/streamer/api/v3
  • streamer.flussonic.com/private-payload - URL для доступа к стриминговому трафику (приватный endpoint). Обычно совпадает с api-endpoint.
  • streamer.flussonic.com/public-payload - публичный URL для стримингового трафика. Устанавливается только если в spec указан publicUrl.

Просмотреть аннотации можно командой:

kubectl get pod <pod-name> -o jsonpath='{.metadata.annotations}' | jq

Автоматическая генерация edit_auth

Если в spec не указан editAuth, оператор автоматически генерирует логин и случайный пароль для авторизации API и сохраняет его в секрете <streamer-name>-license-storage под ключом edit_auth.

Формат записи: <login>:<password>.

Сгенерированный пароль сохраняется в секрете и не изменяется в дальнейшем. Это гарантирует стабильность доступа к API.

Получить пароль можно командой:

kubectl get secret <streamer-name>-license-storage -o jsonpath='{.data.edit_auth}' | base64 -d

Если вы поменяете этот пароль, то Streamer прийдет в состояние StreamerConfigSaved=False и надо будет вручную удалять Pod со стримером:

kubectl delete pod <streamer-name>-0

Создаваемые ресурсы

Оператор автоматически создает и управляет следующими ресурсами Kubernetes для каждого экземпляра Streamer:

  • StatefulSet (<streamer-name>-streamer) - управляет Pod стримера
  • Service (<streamer-name>-headless) - headless service для доступа к стримеру
  • ConfigMap (<streamer-name>-config) - содержит сгенерированную конфигурацию медиасервера
  • Secret (<streamer-name>-license-storage) - хранит секретные данные (edit_auth, license_key и т.д.)
  • ServiceAccount (<streamer-name>-sa) - service account для Pod стримера
  • Role (<streamer-name>-role) - роль с правами на работу с секретами
  • RoleBinding (<streamer-name>-rb) - привязывает Role к ServiceAccount

Все эти ресурсы автоматически удаляются при удалении ресурса Streamer.

Список не является постоянным и может меняться без предупреждения.

Список настроек оператора

Обязательные настройки

version: "v26.01-5" - надо явно указать выбранную версию. latest очень не рекомендуется

nodeName: "stream-node" - имя ноды на которой должен запускаться экземпляр сервера.

Необязательные настройки

image: "flussonic/flussonic" - можно поменять образ самого медиасервера.

env - можно указать Environment переменные для Pod так же, как они указываются для Pod, StatefulSet, и т.п. При изменении будет рестартиться медиасервер.

Пример:

env:
  - name: MY_ENV_VAR
    value: "my-value"
  - name: SECRET_VALUE
    valueFrom:
      secretKeyRef:
        name: my-secret
        key: secret-key

hostPort: 80 - порт для стримингового трафика, который будет проброшен на хост. Используется для прямого доступа к стримеру без Ingress. Значение должно быть в диапазоне 1-65535. По умолчанию используется порт 80 внутри контейнера. Если изменить это значение, то и порт контейнера поменяется на такой же.

adminHostPort: 81 - порт для административного API, который будет проброшен на хост. Используется для прямого доступа к административному интерфейсу стримера. Значение должно быть в диапазоне 1-65535. По умолчанию используется порт 81 внутри контейнера.

publicUrl: "https://example.com/stream" - публичный URL для стримингового трафика. Устанавливается в аннотацию пода под ключом streamer.flussonic.com/public-payload для использования внешними системами.

licenseKey - ссылка на Kubernetes Secret, содержащий лицензионный ключ. Формат аналогичен envFrom или env с secretKeyRef:

licenseKey:
  secretKeyRef:
    name: flussonic-license
    key: license_key

editAuth - ссылка на Kubernetes Secret, содержащий авторизационные данные для API стримера. Если не указано, оператор автоматически сгенерирует случайный пароль и сохранит его в секрете <streamer-name>-license-storage под ключом edit_auth. Формат:

editAuth:
  secretKeyRef:
    name: my-edit-auth-secret
    key: edit_auth

configExternalUrl: "http://config-server/config" - URL внешнего сервера конфигурации, откуда стример будет загружать дополнительные настройки.

configExternalAuth - ссылка на Kubernetes Secret, содержащий данные аутентификации для внешнего сервера конфигурации. Используется вместе с configExternalUrl. Формат:

configExternalAuth:
  secretKeyRef:
    name: config-auth-secret
    key: auth_token

logLevel: "info" - уровень логирования медиасервера. Возможные значения: debug, info, warn, error. По умолчанию используется стандартный уровень логирования медиасервера.

configExtra - дополнительный конфигурационный текст для медиасервера. Ключи этого map будут использованы как комментарии в конфиге, а значения будут добавлены как есть. Описание и примеры использования смотрите в разделе "Конфигурация стримера".

volumes - список дополнительных томов для монтирования в Pod. Каждый том должен содержать name, mountPath и тип тома (например, hostPath, persistentVolumeClaim и т.д.). Описание и примеры использования смотрите в разделе "Хранение видео".