Skip to content

bgelov/xiu-compose

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Реализация rtmp-кластера на базе https://github.com/harlanc/xiu.git стрим-сервера из 3 инстансов

Реализация xiu кластера для проверки функционала в локальной среде, используя docker-compose. Просмотр потока в httpflv и hls с каждого члена кластера и наличие rtmp потока у всех членов кластера

  • Сборка и запуск в несколько стадий. В качестве раннера используется alpine.
  • Для запуска по умолчанию используется стандартный toml конфиг application/xiu/src/config/config_rtmp.toml.
  • Для подачи и просмотра потоков используется ffmpeg и ffplay. Семплы из https://sample-videos.com/

Описание решения

Сборка образа

Согласно требованиям, необходимо использовать multi-stage, собирать приложение в одном контейнере и копировать исполняемые файлы в другой контейнер с Alpine. Проект xiu написан на Rust. Следовательно, для сборки оптимально использовать образ из официального репозитория Rust.

Создаём рабочий каталог и клонируем в него проект xiu:

mkdir xiu-image && cd xiu-image
git clone https://github.com/harlanc/xiu.git 

Пишем Dockerfile.

vi Dockerfile
  • Так как runner у нас Alpine, добавляем дополнительно musl-dev.
  • Не забываем о том, что нам необходимо добавить toml конфиг для запуска по-умолчанию.
  • По дефолту запускаем xiu -c <путь-до конфига>.
  • По best practice указываем версии образов и не плодим RUN.
FROM rust:alpine3.18 as builder
COPY ./ ./
WORKDIR /xiu/application/xiu
RUN apk add --no-cache musl-dev openssl-dev && \
    rustup target add x86_64-unknown-linux-musl && \
    cargo build --release --target x86_64-unknown-linux-musl
	
FROM alpine:3.18 as runner
COPY --from=builder /xiu/target/x86_64-unknown-linux-musl/release/xiu /usr/local/bin/xiu
COPY --from=builder /xiu/application/xiu/src/config/config_rtmp.toml /etc/xiu/config_rtmp.toml
CMD ["xiu", "-c", "/etc/xiu/config_rtmp.toml"]

Собираем образ:

docker image build -t bgelov/xiu:1.0.0 .

Тестирование образа

Пробуем запустить контейнер:

docker run -d -p 1935:1935 --name xiu bgelov/xiu:1.0.0

Проверяем, что контейнер запущен и смотрим на логи:

docker ps
docker logs xiu

Всё ок:

docker logs xiu
[2023-06-22T20:11:41Z INFO  rtmp::rtmp] Rtmp server listening on tcp://0.0.0.0:1935
[2023-06-22T20:11:41Z INFO  xiu::api] Http api server listening on http://:8000

Тестируем работу с использованием ffmpeg и ffplay. Скачиваем приложения. Скачиваем сэмпл видео. Запускаем ffmpeg, давая ему на вход скачанное видео (big_buck_bunny_720p_30mb.mp4):

ffmpeg -re -stream_loop -1 -i big_buck_bunny_720p_30mb.mp4 -c:a copy -c:v copy -f flv -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live/test

Для просмотра запускаем ffplay:

ffplay -i rtmp://localhost:1935/live/test

Успех! Мы видим мультики.

Публикация образа

После успешного теста публикуем образ в registry.

Формируем имя образа в формате <timestamp>-<md5 хеш от Dockerfile>, версия 1.0.0:

IMAGE_NAME="$(date --utc -d "2023-06-21 11:15" +%s)-$(md5sum Dockerfile | awk '{print $1}'):1.0.0"
echo $IMAGE_NAME

Тегаем образ необходимым для публикаци в registry именем и публикуем:

docker tag bgelov/xiu:1.0.0 bgelov/$IMAGE_NAME
docker push bgelov/$IMAGE_NAME

Ссылка на образ: https://hub.docker.com/r/bgelov/1687346100-977d03e7f0746077d90baa216bbf61c2

Реализуем кластер

Необходимо реализовать rtmp-кластер из 3 инстансов, используя docker compose. Согласно документации, в xiu можно реализовать кластер путём push на остальные ноды или pull с другой ноды. Выбираем вариант с pull. Это значит, что у нас будет 2 типа конфигурации xiu, для мастер ноды и для обычных нод.

Создаём рабочий каталог:

mkdir xiu-compose && cd xiu-compose

Пишем docker compose файл vi docker-compose.yml. Для упрощения файла, вынесем название образа в переменную:

services:
  xiu-server-1:
    container_name: xiu-server-1
    image: ${XIU_IMAGE}
    ports:
      - 1935:1935
      - 8081:8081
      - 8080:8080
    volumes:
      - ./conf/master/config_rtmp.toml:/etc/xiu/config_rtmp.toml

  xiu-server-2:
    container_name: xiu-server-2
    image: ${XIU_IMAGE}
    ports:
      - 1936:1935
      - 8181:8081
      - 8180:8080
    volumes:
      - ./conf/node/config_rtmp.toml:/etc/xiu/config_rtmp.toml

  xiu-server-3:
    container_name: xiu-server-3
    image: ${XIU_IMAGE}
    ports:
      - 1937:1935
      - 8281:8081
      - 8280:8080
    volumes:
      - ./conf/node/config_rtmp.toml:/etc/xiu/config_rtmp.toml

Рядом с docker-compose.yml создаём файл vi .env и добавим в него переменную XIU_IMAGE:

XIU_IMAGE=bgelov/1687346100-977d03e7f0746077d90baa216bbf61c2:1.0.0

Рядом с docker-compose.yml так же создадим структуру с конфигурациями xiu для мастер ноды и для обычной ноды. Так как нам нужны потоки rtmp, httpflv и hls, за пример возьмём конфиг application\xiu\src\config\config_rtmp_httpflv_hls.toml.

Пишем конфигурацию для мастер ноды по пути conf/master/config_rtmp.toml с добавление блока [[rtmp.push]]:

#live server configurations
#######################################
#     RTMP configurations(cluster)    #
#######################################
[rtmp]
enabled = true
port = 1935

#######################################
#  push streams to other server node  #
#######################################
[[rtmp.push]]
enabled = true
address = "xiu-server-2"
port = 1935
[[rtmp.push]]
enabled = true
address = "xiu-server-3"
port = 1935


######################################
#    HLS configurations              #
######################################
[hls]
enabled = true
port = 8080


########################################
# HTTPFLV configurations               #
########################################
[httpflv]
enabled = true
port = 8081


#######################################
#   LOG configurations                #
#######################################
[log]
level = "info"

Пишем конфигурацию для обычных нод conf/node/config_rtmp.toml

#live server configurations
#######################################
#   RTMP configurations(stand-alone)  #
#######################################
[rtmp]
enabled = true
port = 1935


######################################
#    HLS configurations              #
######################################
[hls]
enabled = true
port = 8080


########################################
# HTTPFLV configurations               #
########################################
[httpflv]
enabled = true
port = 8081


#######################################
#   LOG configurations                #
#######################################
[log]
level = "info"

Запускаем кластер:

docker compose up -d

Тестируем работоспособность кластера

Успешным результатом считаем:

  • Наличие rtmp потока у всех членов кластера
  • Просмотр потока в httpflv и hls с каждого члена кластера

Запускаем ffmpeg на мастер ноду rtmp://127.0.0.1:1935, давая на вход тестовое видео (big_buck_bunny_720p_30mb.mp4):

ffmpeg -re -stream_loop -1 -i big_buck_bunny_720p_30mb.mp4 -c:a copy -c:v copy -f flv -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live/test

Для просмотра rtmp потока запускаем ffplay на каждую ноду:

ffplay -i rtmp://localhost:1935/live/test
ffplay -i rtmp://localhost:1936/live/test
ffplay -i rtmp://localhost:1937/live/test

Для просмотра потока в httpflv и hls запускаем:

# xiu-server-1
ffplay -i http://localhost:8081/live/test.flv
ffplay -i http://localhost:8080/live/test/test.m3u8

# xiu-server-2
ffplay -i http://localhost:8181/live/test.flv
ffplay -i http://localhost:8180/live/test/test.m3u8

# xiu-server-3
ffplay -i http://localhost:8281/live/test.flv
ffplay -i http://localhost:8280/live/test/test.m3u8