Вступление
Приветствую всех! Давеча сидел и думал о том что часто хочется что-то попеть, покричать в микрофон и было бы круто иметь какое-то решение у себя дома, скажем домашнее караоке.
В интернете смотрел много разных решений и все казались или странные, или неудобные, так уже и не вспомню что от них меня отталкивало, в общем не цепляло, но в один момент наткнулся на Karaoke Eternal (впервые наткнулся когда еще назывался как Karaoke Forever) и мне так понравилось что решил незамедлительно поднять у себя дома.
Чтобы быстро поднять изучить как это работает я использовал свой любимый LXC, склонил git репозиторий и развернул по инструкции разработчика, кстати написано всё на node.js.
Далее я загрузил кучу видео с караоке которые взял с ютюба, некоторые просто где-то в интернете нашёл и всё закинул на свой сервер. Далее просто запустил и стал изучать.
Что такое Karaoke Eternal?
Karaoke Eternal - это удобный инструмент для создания караоке сервер (веб сервер), через которое мы можем удобно разделить где будет происходить воспроизведение песен (телевизор, пк), а откуда можно будет управлять очередью песен (телефон, планшет).
Давайте рассмотрим более детально функционал:
Окно авторизации и выбора комнаты караоке. (Комнаты создаются за ранее администратором сервера.)
После авторизации нас встречает окно с библиотекой где все композиции разбиты по исполнителям, а также внизу есть три вкладки.
Далее переключимся на вкладку по середине, в ней будет показываться наша очередь песен, в ней мы можем:
Смотреть название песен
Смотреть сколько времени до воспроизведения любой песни в очереди
Также при выборе любой композиции выдвинется список действия над ней, а именно:
Добавить композиции в избранное
Передвинуть композиции сразу на самый верх и запустить
Информация о композиции
Удалить из очереди
И последняя вкладка это окно с настройками где есть управление комнатами, библиотекой и т.д.
Теперь покажу как это работает на практики, если коротко.
Загружаем медиафайлы в папку где у нас запущен сервер
Далее добавляем нашу папку и автоматически запускается сканирование файлов
-
Открываем на телевизор / ПК где угодно где есть браузер наш вебсервер, авторизовываемся и нажимаем Start Player
-
У нас открывается такое прекрасное окно. В котором и будет воспроизведение композиций.
Далее через браузер заходим на сервер с телефона или с устройства с которого планируется управлять воспроизведением композиций, выбираем музыку и жмём Play.
После того как нажали Play, на телевизоре или компьютере запускается композиция, далее можно уже не трогать устройство которое выступает в роли плеера, всё управление можно осуществлять с телефона.
Данное решение для караоке мне очень понравилось, поэтому в последствии я решил его перенести в свой домашний кластер kubernetes.
В целом я хотел быстро рассказать что это такое и для чего, а те кто хотят себе нечто подобное дома, велком =)
Поднимаем k3s
Для данной задачи в рамках статьи я сделал VM с 2 CPU, 2 RAM, 30 Gb, ОС ubuntu 20.04.
k3s в массы! И так я буду стараться вообще в каждой своей статье проходится от самого начала до полностью развернутого сервиса / приложения и т.д.
Подготовка ВМ или физического сервера не относиться к фазе от самого начала.
Hidden text
K3s (с офф сайт) — это сертифицированный дистрибутив Kubernetes с высокой доступностью, предназначенный для производственных рабочих нагрузок в автоматических, ограниченных по ресурсам, удаленных местах или внутри устройств IoT. (взято с офф сайт).
k3s (описание от меня) - это оркестратор контейнеров который может:
Запускать контейнеры (для контейнера мы можем также задать переменные, директории с нашего хоста или вообще с удаленного сервера, контейнер который будет запускаться до старта нашего основного контейнера, благодаря чему мы можем как пример подготовить какие либо файлы или выполнить скрипт для корректной работы нашего основного контейнера).
Ставить лимиты по ресурсам для контейнеров. (Как пример что приложение не сможет потреблять больше 2 Gb RAM или 2 CPU).
Задавать политики рестарта контейнеров.
Управлять доступностью к приложениям по сети.
Позволяет удобно читать логи.
Анализировать метрики.
Автомасштабированием контейнеров при повышении нагрузки ( к примеру если наше приложение в контейнере начинает грузится скажем под 80% по RAM или CPU оркестратор поднимет еще контейнеры и будет балансировать автоматическим сам нагрузку между ними).
И т.д.
И самое главное для нас мы можем описать это в манифесте один раз и потом переиспользовать и даже передавать кому угодно чтобы они могли запустить у себя или же наоборот мы можем запустить у себя чужой манифест.
И так я поставил чистую ubuntu 20.04 LTS, выделил ей 2 CPU 2 GB RAM, 20GB Disk и на неё первым делом мы будем ставить k3s.
-
Открываем сайт https://k3s.io, на нем нам говорят что установка k3s не займет много времени.
Копируем команду и дописываем параметр который понадобится нам потом дальше, выполняем.
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable servicelb" sh -
Hidden text
Как мне ранее указывали в прошлой статье в комментариях, внимательно смотрите что запускаете из интернета! Это важно! Особенно под sudo! Ссылка на комментарий: https://habr.com/ru/articles/703624/#comment_24988416
Далее всего менее 30 секунд и кластер готов.
Прописываем sudo kubectl get nodes и видим что наш кластер готов!
Возможно если вы также как и я выделили не очень много ресурсов, то сервер может чуть дольше подниматься, тут просто можно подождать минуту и сообщение как указано ниже уйдет.
Пример сообщения: couldn't get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
Далее, чтобы мы могли работать удобно из под своей УЗ нам требуется скопировать kubeconfig в свою домашнюю папку и выполнить пару команд:
mkdir ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER .kube/config
echo "export KUBECONFIG=~/.kube/config" >> ~/.bashrc
source ~/.bashrc
kubectl get node
Hidden text
Что делаем в коде выше:
Cоздаем папку где будет хранится кубконфиг по умолчанию.
Копируем kubeconfig в ранее созданную папку.
Задаем права для kubeconfig на нашего пользователя и группу.
Загружаем в bashrc строчку которая будет задавать kubeconfig по умолчанию для kubectl при каждом входе в систему.
И смотрим готов ли наш кластер с одной нодой.
Все управление кластером осуществляется через утилиту kubeclt
И так буквально пару действий и у нас есть есть готовый кластер k3s почти со всеми преимуществами kubernetes и готовый к работе.
Вы можете также со своего компьютера подключиться к кластеру k3s, для этого нужно скопировать себе config и скачать утилиту kubectl.
После выполненных команд выше у нас должен быть такой вывод.
Поднимаем Karaoke Eternal
Hidden text
И так давайте для тех кто не сильно погружен в специфику kubernetes я обозначу три его сущности с которыми мы будем работать сейчас:
Pods - Это абстрактный объект Kubernetes, представляющий собой «обертку» для одного или группы контейнеров. Контейнеры в поде запускаются и работают вместе, имеют общие сетевые ресурсы и хранилище. Kubernetes не управляет контейнерами напрямую, он собирает их в поды и работает с ими.
Deployments - Это ресурс предназначенный для развертывания приложений и их обновления декларативным образом.
namespace - пространство в котором мы запускаем поды, загружаем конфиги и в общем ведем всю свою деятельность (удобно для разделения разных проектов/приложений в одном кластере).
Начнем с того что создадим namespace karaoke
kubectl create ns karaoke
Перед тем как поднимать караоке сервер следует озаботится тем где будут храниться наши файлы для караоке и конфиги. Я создам в директории var еще две директории и выдам им права для пользователя который будет использоваться в контейнере.
sudo mkdir -p /var/karaoke-eternal/karaoke
sudo mkdir -p /var/karaoke-eternal/config
sudo chown -R 1000:1000 /var/karaoke-eternal
Вы можете задать и свои пути, тут как удобно.
Теперь нам нужно составить манифест деплоймента для нашего караоке сервера.
Все манифесты для kubernetes описываются в виде yaml, требуется внимательно следить за пробелами.
Откроем наш любимый ви.
vi karaoke-deploy.yaml
И наполним его по примеру ниже.
apiVersion: apps/v1
kind: Deployment
metadata:
name: karaoke
namespace: karaoke
labels:
app: karaoke
spec:
replicas: 1
selector:
matchLabels:
app: karaoke
template:
metadata:
labels:
app: karaoke
spec:
containers:
- name: karaoke-eternal
image: radrootllc/karaoke-eternal
resources:
requests:
memory: "500Mi"
cpu: "250m"
limits:
memory: "500Mi"
cpu: "1000m"
volumeMounts:
- mountPath: /mnt/karaoke
name: karaoke
- mountPath: /config
name: config
securityContext:
runAsUser: 1000
ports:
- containerPort: 8080
protocol: TCP
volumes:
- name: karaoke
hostPath:
path: /var/karaoke-eternal/karaoke
type: Directory
- name: config
hostPath:
path: /var/karaoke-eternal/config
type: Directory
Hidden text
spec - под первым мы описываем параметры deployment, по втором мы описываем работу нашего pod.
containers - описываем с какими параметрами будет подниматься наш контейнер.
image - какой образ нужно будет использовать.
selector - задаем по ним лейбл который нам понадобится дальше.
resources - описываем сколько выделяем фиксированно ресурсов для пода и сколько максимум он может забрать, то есть его лимиты и реквесты.
volumeMounts - прописываем куда монтировать наши PVC.
volumes - объявляем откуда с хоста где запущен k3s будут монтироватьcя папки.
port - указываем какие порты открыть из контейнеры.
Применим манифест
kubectl apply -f karaoke-deploy.yaml
Теперь нужно проверить что приложение запустилось, для этого выполним команду
kubectl get pods -n karaoke
Отлично всё работает! Теперь нам нужно вывести сервер наружу, чтобы мы могли к нему подключаться через браузер.
MetalLB
Для того чтобы вывести наш сервер наружу нужен service который будет перенаправлять трафик с пода наружу и наоборот.
Hidden text
Собственно он так и называется service, через него мы и можем перенаправить трафик наружу, и так service бывает:
ClusterIP — это тип службы по умолчанию в Kubernetes. Он создает службу внутри кластера Kubernetes, к которой могут обращаться другие приложения в кластере, не разрешая внешний доступ.
NodePort - открывает определенный порт на всех узлах в кластере, и любой трафик, отправляемый на этот порт, перенаправляется в службу. Доступ к службе невозможен с IP-адреса кластера.
LoadBalancer — это стандартный способ предоставления службы Kubernetes извне, чтобы к ней можно было получить доступ через Интернет. Если вы используете Google Kubernetes Engine (GKE), это создает балансировщик сетевой нагрузки с одним IP-адресом, к которому могут получить доступ внешние пользователи, а затем они перенаправляются на соответствующий узел в вашем кластере Kubernetes. Доступ к LoadBalancer можно получить так же, как к ClusterIP или NodePort.
И тут снова на помощь как в моей прошлой статье приходит metalLB! Мы развернем дома свой servicelb, направим его на наш домашний роутер и наш под будет прям с него получать свой IP и в нашей сети нам не придется мучиться с NodePort, пробросом портов и мы сможем сделать всё это красиво.
Кстати если на первом шаге не был отключен встроенный servicelb то будет конфликт и MetalLB не будет работать, тут описано как его отключить если вы не отключили его ранее.
Hidden text
Helm — это средство упаковки с открытым исходным кодом, которое помогает установить приложения Kubernetes и управлять их жизненным циклом.
Если упросить благодаря ему можно шаблонизировать наши манифесты таким образом чтобы из одних и тех же манифестов можно поднять разные инстансы приложения, достаточно в одном файле поменять значения или при установки helm указать новое имя и у нас уже отдельно приложение со своим уникальным именем.
И так, шаг первый нужно установить helm.
helm вы можете просто скачать как бинарный файл и положить руками в /usr/bin и сделать его исполняемым.
Ниже команды взяты отсюда https://helm.sh/docs/intro/install/
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
Далее клонируем репозиторий и запускаем helm с metalLB.
У вас должен стоять git чтобы у вас получилось сделать git clone, как альтернатива вы можете с github руками выгрузить файлы, тут как удобнее.
git clone https://github.com/general-rj45/metallb.git
helm install metallb metallb --create-namespace --namespace metallb
Hidden text
в команде helm мы указываем
install - установить
metallb - какое имя будет у хелм чарта когда он установиться
metallb - папка откуда нужно установить
--create-namespace --namespace metallb - создать неймспейс если его нет
Чтобы удалить хелм нужно ввести команду по примеру ниже:
helm delete -n metallb metallb
Проверим что metallb запустился и нет с ним проблем.
kubeclt get pods -n metallb
Теперь требуется задать пул IP адресов для metallb которые он будет присваивать для LoadBalancer.
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb
spec:
addresses:
- 192.168.1.100-192.168.1.200
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb
Hidden text
IPAddressPool - задаем диапазон ip для подов.
addresses - указываем диапазон ip.
L2Advertisement - для нас сейчас достаточно просто запустить, чтобы более конкретно погрузиться что это и для чего стоит почитать на офф сайте.
Применим манифест.
kubectl apply -f metallb-IPAddressPool.yaml
Теперь нам нужно создать service типа loadbalancer и вывести наружу наш сервер.
vi service-karaoke.yaml
apiVersion: v1
kind: Service
metadata:
name: karaoke-service-lb
namespace: karaoke
spec:
type: LoadBalancer
loadBalancerIP: 192.168.1.115
selector:
app: karaoke
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: karaoke-http
Hidden text
type - тут задается тип service.
port - порт который будет выведен наружу.
targetPort - порт пода который будет перенаправляться.
protocol - задаем протокол tcp или udp
selector - тут указывается лейб по которому service сможет понять к какому поду подключить и перенаправлять трафик.
Применим
kubectl apply -f service-karaoke.yaml
Проверяем что всё поднялось и мы можем зайти на сервер.
Далее обычная процедура регистрации, проходим её и у нас готовый сервер к работе.
Но вот теперь возникает еще проблема, а как закидывать файлы на сервер без костылей и лишней боли?
Samba-server
Так как большая часть машин у меня дома очень хорошо дружит с smb протоколом, то я подумал, а может это классное решение и я вам скажу да! К тому же очень удобное.
Про samba можно почитать по ссылке
И так что нам понадобится.
1. Требуется создать секрет, в нём будем содержать пароль и логин для входа в наш samba-server.
vi secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: karaoke-creds-samba
namespace: karaoke
type: Opaque
data:
password: a2FyYW9rZQ==
username: a2FyYW9rZQ==
Hidden text
При создании секрета он всегда указывается в base64
Почитать про секреты более подробно можно тут https://kubernetes.io/docs/concepts/configuration/secret/
Но если коротко для чего секреты в kubernetes, это для того чтобы секьюрные данные спрятать в отельную сущность и подгружать их только по необходимости в поды.
kubectl apply -f secret.yaml
После нам нужно прописать в нашем деплойменте еще один контейнер. Для него следует прописать ранее заданный секрет и папку где хранятся медиафайлы.
vi karaoke-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: karaoke
namespace: karaoke
labels:
app: karaoke
spec:
replicas: 1
selector:
matchLabels:
app: karaoke
template:
metadata:
labels:
app: karaoke
spec:
containers:
- name: karaoke-eternal
image: radrootllc/karaoke-eternal
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "300Mi"
cpu: "400m"
volumeMounts:
- mountPath: /mnt/karaoke
name: karaoke
- mountPath: /config
name: config
securityContext:
runAsUser: 1000
ports:
- containerPort: 8080
protocol: TCP
- name: smb-server
image: andyzhangx/samba:win-fix
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "300Mi"
cpu: "400m"
env:
- name: PERMISSIONS
value: "0777"
- name: USERNAME
valueFrom:
secretKeyRef:
name: karaoke-creds-samba
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: karaoke-creds-samba
key: password
args: ["-u", "$(USERNAME);$(PASSWORD)", "-s", "share;/smbshare/;yes;no;no;all;none", "-p"]
volumeMounts:
- mountPath: /smbshare
name: karaoke
volumes:
- name: karaoke
hostPath:
path: /var/karaoke-eternal/karaoke
type: Directory
- name: config
hostPath:
path: /var/karaoke-eternal/config
type: Directory
Hidden text
Рекомендую внимательно посмотреть как мы добавили новый контейнер и какие параметры передали ему.
Применяем и проверяем что у нас корректно всё запустилось.
kubectl apply -f karaoke-deploy.yaml
kubectl get pods -n karaoke
И заключительно это подправить LoadBalancer чтобы мы также по сети могли зайти на samba-server.
vi service-karaoke.yaml
apiVersion: v1
kind: Service
metadata:
name: karaoke-service-lb
namespace: karaoke
spec:
type: LoadBalancer
loadBalancerIP: 192.168.1.115
selector:
app: karaoke
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: karaoke-http
- port: 445
targetPort: 445
protocol: TCP
name: karaoke-smb
Hidden text
В данном манифесте тоже есть интересный момент, мы подняли ранее два контейнера в одном поде, а теперь их двоих мы привязали к одному LoadBalancer и используя один ip мы можем по разным портам подключиться как к вебсерверу, так и к samba-server
И применяем
kubectl apply -f service-karaoke.yaml
Проверяем, заходим через проводник по пути \\192.168.1.115 и вас должно встретить окно авторизации. (я заходил через windows, похожим способом можно и с mac и с linux зайти)
Попробуем авторизоваться ранее заданным логином и паролем. В нашем случае karaoke/karaoke.
-
Если всё корректно было сделано по инструкции то у нас выходит авторизоваться и мы видим папку share, теперь нужно вложить свои медиафайлы в папку.
Загружаем файлы и запускаем.
Всё самое легко позади, теперь остается только найти различные медиафайлы для караоке м загрузить их на сервер.
Я знаю что вроде бы не точно но можно использовать Download Master и через него скачивать видео с ютюба и даже целые альбомы, я конечно не пробовал, но вдруг у вас получиться. А так за подробностями можете в личку стучаться как и где доставать медиафайлы для караоке =)
И так допустим вы нашли файлы и загрузили их, что дальше?
Как ранее писал создаем пользователя на сервере.
Идём в настройки и выбираем Media Folders
Нажимаем Add folder
После проходим по пути /mnt/karaoke и нажимаем Add Folder
Далее автоматически начнется сканирование и прогресс будет показан сверху экрана.
Примечание. Треки лучше называть по типу Author - Track, тире служит разделителем между исполнителем и названием песни.
Примечание 2. Треки не стоит называть кириллицей так как одни названия будут затирать другие и не все песни будут показываться.
Заходим на вебсервер через телевизор/пк и в самом вверху нажимаем start player (так как я уже в самом начале описывал как это выглядит не хочу дублировать скрины сильно).
Заходим с телефона на сервер и ставим песни в очередь и запускаем через play.
Вот и всё =)
В заключение
Тут бы хотел еще добавить как у меня выглядит коммутация дома для караоке, может кому-то будет полезно
Есть микшерный пульт в который идёт звук с Микрофона 1 и 2, а также в него идёт звук с тв приставки по aux.
С тв приставки в телевизор идёт hdmi только для вывод картинки, на нём я запускаю плеер с браузера.
С микшера уже все вместе идёт на отдельно стоящие мониторы (колонки).
Вот так можно вроде бы по большей части рабочие инструменты можно использовать в таких интересных целях, как караоке сервер)
Спасибо что дочитали мою статью, надеюсь кому-то это будет интересно. Будут вопросы не стесняйтесь задавайте, постараюсь ответить)
Вот единственное фото смог найти как у меня выглядит, конечно 6 из 10 шакалов, но норм)
molnij
Эм, я правильно понимаю, вот эти вот все телодвижения чтобы на телевизоре запустить "видео с караоке которые взял с ютюба, некоторые просто где‑то в интернете нашёл"? о_О
Чувствуется лёёёёгкий оверхед :D
General_RJ-45 Автор
Удобно запустить что немало важно) В целом да замудрённо, но когда у тебя дома много всего поднято то понимаешь что так проще и удобнее становиться поддерживать всё, к тому же если убрать часть с metallb и k3s, статья становится в два раза короче .