Русский
Русский
English
Статистика
Реклама

Ip camera

Стриминг множества RTSP IP камер на YouTube иили Facebook

07.06.2021 18:08:54 | Автор: admin

Как известно, у YouTube отсутствует фича захвата RTSP потока. Возможно, это сделано не случайно, а исходя из голой прагматики, чтобы люди не повесили на YouTube статическое видеонаблюдение за своими подъездами и не утилизировали его каналы, которые, как оказалось в пандемию, вовсе не резиновые. Напомним, что некоторое время назад имели место истории с ухудшением и ограничением качества стримов до 240p. Или есть еще одно предположение: стримы с IP камер это зло для YouTube, потому что у них чуть более ноля зрителей, на которых не накрутишь миллион просмотров рекламы. Так или иначе, фича не представлена, и мы постараемся заполнить этот пробел - помочь YouTube осчастливить пользователей.

Допустим, мы хотим взять обычную уличную IP камеру, которая отдает H.264 поток по RTSP и перенаправить ее на YouTube. Для этого потребуется принять RTSP поток и сконвертировать в RTMPS поток, который принимает YouTube. Почему именно в RTMPS, а не RTMP? Как известно несекьюрные протоколы отмирают. HTTP предан гонениям, и его участь постигла другие протоколы, не имеющие буквы S - значит Secure на конце. От RTMP потока отказался Facebook, но спасибо, оставил RTMPS. Итак, конвертируем RTSP в RTMPS. Делаем это Headless способом (без использования UI), т.е. на сервере.

Для одного RTSP потока потребуется один YouTube аккаунт, который будет принимать поток. Но что делать если камер не одна, а много?

Да, можно насоздавать вручную несколько YouTube-аккаунтов, например, чтобы покрыть видеонаблюдением приусадебный участок. Но это с огромной вероятностью нарушит условия пользовательского соглашения. А если камер не 10, а все 50? Создавать 50 аккаунтов? А дальше что? Смотреть это как? В этом случае на помощь может прийти микшер, который объединит камеры в один поток.

Посмотрим, как это работает на примере двух RTSP камер. Результирующий поток mixer1 = rtsp1 + rtsp2. Отправляем стрим mixer1 на YouTube. Все работает - обе камеры идут в одном потоке. Здесь стоит заметить, что микширование - достаточно ресурсоемкая по использованию CPU операция.

При этом, так как мы уже имеем RTSP поток на стороне сервера, мы можем перенаправить этот поток на другие RTMP endpoints, не неся при этом дополнительных расходов по CPU и памяти. Просто снимаем трафик с RTSP стрима и тиражируем на Facebook, Twitch, куда угодно без дополнительного RTSP захвата и депакетизации.

Меня, как девопса, будет мучать совесть, если я не заскриптую то, что можно было бы заскриптовать. Автоматизации способствует наличие REST API для управления захватом видео с камеры и ретрансляцией.

Например, с помощью запроса:

/rtsp/startup

можно захватить видеопоток от IP камеры.

Запрос:

/rtsp/find_all

позволит получить список захваченных сервером RTSP потоков.

Запрос для завершения RTSP сессии выглядит так:

/rtsp/terminate

Захватом и ретрансляцией видеопотоков можно управлять или с помощью простого браузера и любого удобного REST клиента, или с помощью минимального количества строчек кода встроить функционал управления сервером в свой web проект.

Давайте подробно рассмотрим, как это можно сделать.

Небольшой мануал, как с помощью минимального кода организовать Live трансляцию на YouTube и Facebook

В качестве серверной части мы используем demo.flashphoner.com. Для быстрого развертывания своего WCS сервера воспользуйтесь этой инструкцией или запустите один из виртуальных инстансов на Amazon, DigitalOcean или в Docker.

Предполагается, что у вас имеется подтвержденный аккаунт на YouTube и вы уже создали трансляцию в YouTube Studio, а так же создали прямую видеотрансляцию в своем аккаунте на Facebook.

Для работы Live трансляций на YouTube и Facebook нужно указать в файле настроек WCS flashphoner.properties следующие строки:

rtmp_transponder_stream_name_prefix= Убирает все префиксы для ретранслируемого потока.

rtmp_transponder_full_url=true В значении "true" игнорирует параметр "streamName" и использует RTMP адрес для ретрансляции потока в том виде, в котором его указал пользователь.

rtmp_flash_ver_subscriber=LNX 76.219.189.0 - для согласования версий RTMP клиента между WCS и YouTube.

Теперь, когда все подготовительные действия выполнены, перейдем к программированию. Разместим в HTML файле минимально необходимые элементы:

Подключаем скрипты основного API и JS скрипт для работы live трансляции, который мы создадим чуть позже:

 <script type="text/javascript" src="../../../../flashphoner.js"></script> <script type="text/javascript" src="rtsp-to-rtmp-min.js"></script>

Инициализируем API на загрузку web-страницы:

<body onload="init_page()">

Добавляем нужные элементы и кнопки поля для ввода уникальных кодов потоков для YouTube и Facebook, кнопку для републикации RTSP потока, div элемент для вывода текущего статуса работы программы и кнопку для остановки републикации:

<input id="streamKeyYT" type="text" placeholder="YouTube Stream key"/><input id="streamKeyFB" type="text" placeholder="FaceBook Stream key"/><button id="repubBtn">Start republish</button><div id="republishStatus"></div><br><button id="stopBtn">Stop republish</button>

Затем переходим к созданию JS скрипта для работы републикации RTSP. Скрипт представляет собой мини REST клиент.

Создаем константы:

Константа "url", в которую записываем адрес для запросов REST API . Замените "demo.flashphoner.com" на адрес своего WCS.

Константа "rtspStream" указываем RTSP адрес потока с IP камеры. Мы для примера используем RTSP поток с виртуальной камеры.

var url = "https://demo.flashphoner.com:8444/rest-api";var rtspStream = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"

Функция "init_page()" инициализирует основной API при загрузке web - страницы. Так же в этой функции прописываем соответствие кнопок вызываемым функциям и вызываем функцию "getStream", которая захватывает RTSP видеопоток с IP камеры:

function init_page() {Flashphoner.init({});repubBtn.onclick = streamToYouTube;stopBtn.onclick = stopStream;getStream();}

Функция "getStream()" отправляет на WCS REST запрос /rtsp/startup который захватывает видеопоток RTSP адрес которого был записан в константу rtspStream

function getStream() {    fetchUrl = url + "/rtsp/startup";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "uri": rtspStream        }),    }    fetch(fetchUrl, options);console.log("Stream Captured");}

Функция "streamToYouTube()" републикует захваченный видеопоток в Live трансляцию на YouTube:

function streamToYouTube() {fetchUrl = url + "/push/startup";const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "streamName": rtspStream,"rtmpUrl": "rtmp://a.rtmp.youtube.com/live2/"+document.getElementById("streamKeyYT").value        }),    }  fetch(fetchUrl, options);streamToFB()}

Эта функция отправляет на WCS REST вызов /push/startup в параметрах которого передаются следующие значения:

"streamName" - имя потока, который мы захватили с IP камеры. Имя потока соответствует его RTSP адресу, который мы записали в константу "rtspStream"

"rtmpUrl" - URL сервера + уникальный код потока. Эти данные выдаются при создании Live трансляции в YouTube Studio. В нашем примере мы жестко закрепили URL в коде, вы можете добавить для него еще одно поле на свою web страницу. Уникальный код потока указывается в поле "streamKeyYT" на нашей Web странице.

Функция "streamToFB" републикует захваченный видеопоток в Live трансляцию на Facebook:

function streamToFB() {fetchUrl = url + "/push/startup";const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "streamName": rtspStream,"rtmpUrl": "rtmps://live-api-s.facebook.com:443/rtmp/"+document.getElementById("streamKeyFB").value        }),    }  fetch(fetchUrl, options);document.getElementById("republishStatus").textContent = "Stream republished";}

Эта функция так же отправляет на WCS REST вызов "/push/startup" в параметрах которого передаются значения:

"streamName" - имя потока, который мы захватили с IP камеры. Имя потока соответствует его RTSP адресу, который мы записали в константу "rtspStream"

"rtmpUrl" - URL сервера + уникальный код потока. Эти данные можно найти на странице Live трансляции в Facebook в секции Live API. Url сервера в этой функции мы указали в коде, как и для функции републикации на YouTube. Уникальный код потока берем из поля "streamKeyFB" на Web странице.

Функция "stopStream()" отправляет RTSP запрос "/rtsp/terminate" который прекращает захват потока с IP камеры на WCS и соответственно прекращает публикации на YouTube и Facebook:

function stopStream() {fetchUrl = url + "/rtsp/terminate";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "uri": document.getElementById("rtspLink").value        }),    }    fetch(fetchUrl, options);document.getElementById("captureStatus").textContent = null;document.getElementById("republishStatus").textContent = null;document.getElementById("stopStatus").textContent = "Stream stopped";}

Полные коды HTML и JS файлов рассмотрим немного ниже.

Итак. Сохраняем файлы и пробуем запустить.

Последовательность действий для тестирования

Создаем Live трансляцию в YouTube Studio. Копируем уникальный код видеопотока:

Открываем созданную ранее HTML страницу. Указываем в первом поле уникальный код видеопотока, который мы скопировали на YouTube:

Создаем Live трансляцию в своем аккаунте на Facebook. Копируем уникальный код видеопотока.

Возвращаемся на нашу web страничку, вставляем скопированный код во второе поле и нажимаем кнопку "Start republish

Теперь проверяем работу нашей републикации. Снова переходим в YouTube Studio и на Facebook, ждем несколько секунд и получаем превью потока.

Для завершения републикации нажмите кнопку "Stop"

Теперь, как и обещали, исходные коды примера полностью:

Листинг HTML файла "rtsp-to-rtmp-min.html"

<!DOCTYPE html><html lang="en">    <head>        <script type="text/javascript" src="../../../../flashphoner.js"></script>        <script type="text/javascript" src="rtsp-to-rtmp-min.js"></script>    </head>    <body onload="init_page()">        <input id="streamKeyYT" type="text" placeholder="YouTube Stream key" /> <input id="streamKeyFB" type="text" placeholder="Facebook Stream key" /> <button id="repubBtn">Start republish</button>        <div id="republishStatus"></div>        <br />        <button id="stopBtn">Stop republish</button>    </body></html>

Листинг JS файла "rtsp-to-rtmp-min.js":

var url = "https://demo.flashphoner.com:8444/rest-api";var rtspStream = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"function init_page() {    Flashphoner.init({});    repubBtn.onclick = streamToYouTube;    stopBtn.onclick = stopStream;    getStream();}function getStream() {    fetchUrl = url + "/rtsp/startup";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "uri": rtspStream        }),    }    fetch(fetchUrl, options);    console.log("Stream Captured");}function streamToYouTube() {    fetchUrl = url + "/push/startup";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "streamName": rtspStream,            "rtmpUrl": "rtmp://a.rtmp.youtube.com/live2/" + document.getElementById("streamKeyYT").value        }),    }    fetch(fetchUrl, options);    streamToFB()}function streamToFB() {    fetchUrl = url + "/push/startup";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "streamName": rtspStream,            "rtmpUrl": "rtmps://live-api-s.facebook.com:443/rtmp/" + document.getElementById("streamKeyFB").value        }),    }    fetch(fetchUrl, options);    document.getElementById("republishStatus").textContent = "Stream republished";}function stopStream() {    fetchUrl = url + "/rtsp/terminate";    const options = {        method: "POST",        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({            "uri": rtspStream        }),    }    fetch(fetchUrl, options);    document.getElementById("republishStatus").textContent = "Stream stopped";}

Для минимальной реализации требуется совсем немного кода. Конечно для итогового внедрения функционала еще потребуется небольшая доработка напильником - добавить стили на web страницу и разные проверки на валидность данных в код JS скрипта. Но это работает.

Удачного стриминга!

Ссылки

Наш демо сервер

WCS на Amazon EC2 - Быстрое развертывание WCS на базе Amazon

WCS на DigitalOcean - Быстрое развертывание WCS на базе DigitalOcean

WCS в Docker - Запуск WCS как Docker контейнера

Трансляция WebRTC видеопотока с конвертацией в RTMP - Функции сервера по конвертации WebRTC аудио видео потока в RTMP

Трансляция потокового видео с профессионального устройства видеозахвата (Live Encoder) по протоколу RTMP - Функции сервера по конвертации видеопотоков от Live Encoder в RTMP

HTML5-трансляции с RTSP-IP камер - Функции сервера по воспроизведению RTSP видеопотоков

Подробнее..

Автоматизируй это, или Контейнерные перевозки Docker для WebRTC

11.06.2021 08:06:47 | Автор: admin

Подавляющее большинство IT специалистов разных направлений стремится как можно меньше действий выполнять руками. Не побоюсь громких слов - то что может быть автоматизировано, должно быть автоматизировано!

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

Путей решения этой задачи может быть несколько:

  1. Использовать виртуальные машины. Несколько тяжеловесное решение. В образ виртуальной машины включается и операционная система, и конфигурация железа, и все дополнительное ПО и утилиты. Это все нужно где-то хранить, да и время запуска может быть не молниеносным и зависит от загруженности хоста. Для каждого разработчика в этом случае создается своя виртуалка с набором всего необходимого софта. Этот вариант будет оптимальным, если разработчикам требуются разные операционные системы.

  2. Использовать скрипты. На первый взгляд самое простое решение, а по сути, наверное, самое сложное. В этом случае, мы не тащим с собой операционку и дополнительное ПО. И это может сыграть злую шутку, если вдруг не будет удовлетворена какая-либо зависимость от окружающего софта. Попадется случайно в репозитории условный Python не той версии и все!

  3. Запускать основной продукт в контейнерах. Это самое современное на сегодняшний день решение. Контейнер - это некая изолированная от внешних факторов среда. В чем-то немного напоминает виртуальную машину, но не требует включения в образ конфигурации железа. В работе так же, как и виртуальная машина, использует ресурсы хоста. Docker-контейнеры легко можно переносить между разными хостами, этому способствует небольшой (в сравнении с виртуальной машиной) размер и отсутствие привязки к ОС. Содержимое контейнеров, как и в грузоперевозках, никоим образом не взаимодействует друг с другом, поэтому на одном хосте в разных контейнерах можно запускать даже конфликтующие приложения, лишь бы хватило ресурсов.

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

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

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

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

  • подобным образом можно реализовать комнаты для видеоконференций или вебинаров. Одна комната - один контейнер. ;

  • организовать систему видеонаблюдения за домами. Один дом - один контейнер;

  • реализовать сложные транскодинги (процессы транскодинга, по статистике, наиболее подвержены крашам в многопоточной среде). Один транскодер - один контейнер.

    и т.п.

Контейнеры можно использовать везде, где необходима изоляция процесса и защита работы процесса от соседей. Таким нехитрым образом можно значительно улучшить качество обслуживания не связанных друг с другом клиентов, например у блогера свой контейнер, у дома под видеонаблюдением свой. С помощью скриптов можно автоматизировать создание, удаление и изменение таких клиентских стриминговых контейнеров.

Почему все таки контейнеры, а не виртуалки?

Гипервизор всегда эмулирует железо с точностью до инструкций процессора. Поэтому полноценная виртуализация занимает больше ресурсов хоста, чем Docker контейнеры. Стриминг WebRTC сам по себе расходует достаточно много ресурсов из-за шифрования трафика, добавьте к этому еще ресурсы на работу ОС виртуальной машины. Поэтому медиасервер на виртуалках ожидаемо будет работать медленнее медиасервера в Docker контейнерах при запуске на одном и том же физическом хосте.

Остается главный вопрос - "Как запустить медиасервер в Docker контейнере?

Разберем на примере Web Call Server.

Легче легкого!

В Docker Hub уже загружен образ Flashphoner Web Call Server 5.2.

Развертывание WCS сводится к двум командам:

  1. Загрузить актуальную сборку с Docker Hub

    docker pull flashponer/webcallserver
    
  2. Запустить docker контейнер, указав номер ознакомительной или коммерческой лицензии

    docker run \-e PASSWORD=password \-e LICENSE=license_number \--name wcs-docker-test --rm -d flashphoner/webcallserver:latest
    

    где:

    PASSWORD - пароль на доступ внутрь контейнера по SSH. Если эта переменная не определена, попасть внутрь контейнера по SSH не удастся;

    LICENSE - номер лицензии WCS. Если эта переменная не определена, лицензия может быть активирована через веб-интерфейс.

Но, если бы все было настолько просто не было бы этой статьи.

Первые сложности

На своей локальной машине с операционной системой Ubuntu Desktop 20.04 LTS я установил Docker:

sudo apt install docker.io

Создал новую внутреннюю сеть Docker с названием "testnet":

sudo docker network create \ --subnet 192.168.1.0/24 \ --gateway=192.168.1.1 \ --driver=bridge \ --opt com.docker.network.bridge.name=br-testnet testnet

Cкачал актуальную сборку WCS с Docker Hub

sudo docker pull flashphoner/webcallserver

Запустил контейнер WCS

sudo docker run \-e PASSWORD=password \-e LICENSE=license_number \-e LOCAL_IP=192.168.1.10 \--net testnet --ip 192.168.1.10 \--name wcs-docker-test --rm -d flashphoner/webcallserver:latest

Переменные здесь:

PASSWORD - пароль на доступ внутрь контейнера по SSH. Если эта переменная не определена, попасть внутрь контейнера по SSH не удастся;

LICENSE - номер лицензии WCS. Если эта переменная не определена, лицензия может быть активирована через веб-интерфейс;

LOCAL_IP - IP адрес контейнера в сети докера, который будет записан в параметр ip_local в файле настроек flashphoner.properties;

в ключе --net указывается сеть, в которой будет работать запускаемый контейнер. Запускаем контейнер в сети testnet.

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

ping 192.168.1.10

Открыл Web интерфейс WCS в локальном браузере по ссылке https://192.168.1.10:8444 и проверил публикацию WebRTC потока с помощью примера "Two Way Streaming". Все работает.

Локально, с моего компьютера на котором установлен Docker, доступ к WCS серверу у меня был. Теперь нужно было дать доступ коллегам.

Замкнутая сеть

Внутренняя сеть Docker является изолированной, т.е. из сети докера доступ "в мир" есть, а "из мира" сеть докера не доступна.

Получается, чтобы предоставить коллегам доступ к тестовому стенду в Docker на моей машине, я должен предоставить консольный доступ к своей машине. Для тестирования внутри группы разработчиков такой вариант с натяжкой допустим. Но мне то хотелось это все запустить в продакшен. Неужели, миллиарды контейнеров во всем мире работают только локально?

Конечно же нет. Путем курения мануалов был найден ответ. Нужно пробросить порты. Причем проброс портов нужен не на сетевом маршрутизаторе, а в самом Dockere.

Отлично! Список портов известен. Пробрасываем:

docker run \-e PASSWORD=password \-e LICENSE=license_number \-e LOCAL_IP=192.168.1.10 \-e EXTERNAL_IP=192.168.23.6 \-d -p8444:8444 -p8443:8443 -p1935:1935 -p30000-33000:30000-33000 \--net testnet --ip 192.168.1.10 \--name wcs-docker-test --rm flashphoner/webcallserver:latest

В этой команде используем следующие переменные:

PASSWORD, LICENSE и LOCAL_IP мы рассмотрели выше;

EXTERNAL_IP IP адрес внешнего сетевого интерфейса. Записывается в параметр ip в файле настроек flashphoner.properties;

Так же в команде появляются ключи -p это и есть проброс портов. В этой итерации используем ту же сеть "testnet", которую мы создали раньше.

В браузере на другом компьютере открываю https://192.168.23.6:8444 (IP адрес моей машины с Docker) и запускаю пример "Two Way Streaming"

Web интерфейс WCS работает и даже WebRTC трафик ходит.

И все было бы прекрасно, если бы не одно но!

Ну что ж так долго!

Контейнер с включенным пробросом портов запускался у меня около 10 минут. За это время я бы успел вручную поставить пару копий WCS. Такая задержка происходит из-за того, что Docker формирует привязку для каждого порта из диапазона.

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

Получается, что вариант с пробросом портов мне не подходит из-за медленного старта контейнера и необходимости менять порты для запуска второго и последующих контейнеров.

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

Запускаем контейнер в сети хоста (на это указывает ключ --net host)

docker run \-e PASSWORD=password \-e LICENSE=license_number \-e LOCAL_IP=192.168.23.6 \-e EXTERNAL_IP=192.168.23.6 \--net host \--name wcs-docker-test --rm -d flashphoner/webcallserver:latest

Отлично! Контейнер запустился быстро. С внешней машины все работает - и web интерфейс и WebRTC трафик публикуется и воспроизводится.

Потом я запустил еще пару контейнеров. Благо на моем компьютере несколько сетевых карт.

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

Рабочий вариант

Начиная с версии 1.12 Docker предоставляет два сетевых драйвера: Macvlan и IPvlan. Они позволяют назначать статические IP из сети LAN.

  • Macvlan позволяет одному физическому сетевому интерфейсу (машине-хосту) иметь произвольное количество контейнеров, каждый из которых имеет свой собственный MAC-адрес.

    Требуется ядро Linux v3.93.19 или 4.0+.

  • IPvlan позволяет создать произвольное количество контейнеров для вашей хост машины, которые имеют один и тот же MAC-адрес.

    Требуется ядро Linux v4.2 + (поддержка более ранних ядер существует, но глючит).

Я использовал в своей инсталляции драйвер IPvlan. Отчасти, так сложилось исторически, отчасти у меня был расчет на перевод инфраструктуры на VMWare ESXi. Дело в том, что для VMWare ESXi доступно использование только одного MAC-адреса на порт, и в таком случае технология Macvlan не подходит.

Итак. У меня есть сетевой интерфейс enp0s3, который получает IP адрес от DHCP сервера.

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

Что бы этого избежать нужно зарезервировать часть диапазона подсети для использования Docker. Это решение состоит из двух частей:

  1. Нужно настроить службу DHCP в сети таким образом, чтобы она не назначала адреса в некотором определенном диапазоне.

  2. Нужно сообщить Docker об этом зарезервированном диапазоне адресов.

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

А вот как сообщить Docker, какой диапазон для него выделен, разберем подробно.

Я ограничил диапазон адресов DHCP сервера так, что он не выдает адреса выше 192.168.23. 99. Отдадим для Docker 32 адреса начиная с 192.168.23.100.

Создаем новую Docker сеть с названием "new-testnet":

docker network create -d ipvlan -o parent=enp0s3 \--subnet 192.168.23.0/24 \--gateway 192.168.23.1 \--ip-range 192.168.23.100/27 \new-testnet

где:

ipvlan тип сетевого драйвера;

parent=enp0s3 физический сетевой интерфейс (enp0s3), через который будет идти трафик контейнеров;

--subnet подсеть;

--gateway шлюз по умолчанию для подсети;

--ip-range диапазон адресов в подсети, которые Docker может присваивать контейнерам.

и запускаем в этой сети контейнер с WCS

docker run \-e PASSWORD=password \-e LICENSE=license_number \-e LOCAL_IP=192.168.23.101 \-e EXTERNAL_IP=192.168.23.101 \--net new-testnet --ip 192.168.23.101 \--name wcs-docker-test --rm -d flashphoner/webcallserver:latest

Проверяем работу web интерфейса и публикацию/воспроизведение WebRTC трафика с помощью примера "Two-way Streaming":

Есть один маленький минус такого подхода. При использовании технологий Ipvlan или Macvlan Docker изолирует контейнер от хоста. Если, например, попробовать пропинговать контейнер с хоста, то все пакеты будут потеряны.

Но для моей текущей задачи запуска WCS в контейнере это не критично. Всегда можно запустить пинг или подключиться по ssh с другой машины.

Используя технологию IPvlan на одном Docker хосте можно поднять необходимое количество контейнеров. Это количество ограничено только ресурсами хоста и, частично, сетевой адресацией конкретной сети.

Запуск контейнеров в Dockere может быть сложным только для новичков. Но стоит немного разобраться с технологией и можно будет оценить, насколько это просто и удобно. Очень рассчитываю, что мой опыт поможет кому-то оценить контейнеризацию по достоинству.

Ссылки

WCS в Docker

Документация по развертыванию WCS в Docker

Образ WCS на DockerHub

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru