acgnhiki / blrec

Bilibili Live Streaming Recorder 哔哩哔哩直播录制
GNU General Public License v3.0
579 stars 40 forks source link

[教程分享]在阿里云ECS上直接录制到OSS #117

Open frankcui95 opened 2 years ago

frankcui95 commented 2 years ago

在阿里云 ECS 上录制到 OSS

TL;DR

Ubuntu on ECS + K3S + Traefik v2 + Aliyun OSS + (Public or Private) Domain

可选 + SSL + Cloudflare + WireGuard + ZeroTier


前言

这篇文档面向容器运维人员。

这并不是一篇对新手友好的教程。

确切来说是我想蹭个热度怕忘了整理个部署文档在这。

用了几个月,在服务器上的录制效果我很满意。


这个文档里面可能包含错误,欢迎各路大神指正

在阅读正文之前,已经默认读者已经熟悉或者掌握以下知识或技能

不要担心, 如果你不熟悉上面说的是什么,你可以尝试乱拳打死老师傅敲对命令


本篇文章有的

本篇文章没有的


准备工作

阿里云专有网络 VPC 不要经典网络

专有网络基本信息 内容
ID vpc-xxxxxxxxxx
IPv4 网段 10.20.30.0/24 (主)
路由表 1
交换机 1
云服务器 1
地域 华东 2(上海)
路由器基本信息 内容
ID vrt-xxxxxxxxxx
交换机基本信息 内容 备注
ID vsw-xxxxxxxxxx
IPv4 网段 10.20.30.128/25 随便定义
专有网络 ID vpc-xxxxxxxxxx
可用区 上海 可用区 B 可用区要一致
已绑定路由表 vtb-xxxxxxxx
路由表基本信息 内容 备注
路由表 ID vtb-xxxxxxxx
专有网络 ID vpc-xxxxxxxx 上面那个网
自定义路由条目 内容 备注
目标网段 192.168.192.0/24 这是我 ZeroTier 网络
目标网段 172.19.0.2/32 这是我 WireGuard 网络
目标网段 192.168.2.0/24 这是我家里的网络
下一跳 i-xxxxxxxxx 指向你的 ECS

阿里云 ECS

*标注的需要重点关注

基本信息 内容 备注
ID* i-xxxxxxxx 路由表那里用
弹性公网 IP* 101.xxx.yyy.zzz
安全组 2 1 个自带安全组,一个 Cloudflare 安全组
地域 华东 2(上海) 地域要一致
所在可用区 上海 可用区 B 可用区要一致
CPU&内存* 2 核(vCPU) 2 GiB 建议至少 2 核 2G
操作系统 Ubuntu 20.04 64 位 要用阿里云的 OSS 工具,最好是 Ubuntu
实例规格 ecs.t6-c1m1.large (性能约束实例) 突发性能实力便宜
实例规格族 ecs.t6
当前使用带宽* 200Mbps (峰值) 其实不会用很多流量
网络信息 内容 备注
网络类型 专有网络 不要经典网络
弹性网卡 eni-xxxxxxxxxxxxxxx
主私网 IP 10.20.30.129
IPv6 地址 -
专有网络 vpc-xxxxxxxxxx 网络要一致
虚拟交换机 vsw-xxxxxxxxxx 交换机要一致
弹性 IP 实例 ID eip-xxxxxxxxx
付费信息 内容 备注
付费类型 包年包月
带宽计费方式* 按使用流量 不要固定带宽
其它信息 内容 备注
无性能约束模式* 已关闭 要加钱,没有必要
实例类型* I/O 优化 别的类型不卖
密钥对* xxxxxx 这个是免密登录,不说了

RAM 访问控制

创建用户 内容 备注
登录名称 blrec 你随便,下面用到
显示名称 blrec 你随便,下面用到
控制台访问 关闭 不需要
Open API 调用访问* 开启 必要
权限管理 内容 备注
权限策略* AliyunOSSReadOnlyAccess 要给这个访问 OSS
创建 AccessKey * 内容 备注
AccessKey ID * 系统生成 一定要记录好,后面用到
AccessKey Secret * 系统生成 一定要记录好,后面用到

阿里云 OSS

创建 Bucket 内容 备注
Bucket 名称 yukiko-live-recording 你随便
地域* 华东 2 (上海) 和你 ECS VPC 在一起
存储类型* 低频访问存储 一个人看比标准存储省钱,人多看录播还是选标准
同城冗余存储* 关闭 没必要,多花钱
服务端加密方式* 没必要,后面解密麻烦
读写权限* 公共读 CDN 方便
定时备份 关闭 多花钱,看你需求

OSS 这里比较麻烦,新建一个目录,blrec

Bucket 授权策略 内容 备注
授权资源 指定资源
资源路径 yukiko-live-recording/blrec 名字和你上面的 bucket 名称和目录对应
授权用户 子账号 blrec 要自己去 RAM 管理新建子账号并授权 OSS
授权操作* 完全控制 这里只给读写会让 blrec 软件产生无法删除文件,没有权限的错误
条件* VPC=vpc-xxxxxxxx 这里限制高一些,不怕访问令牌泄漏

准备域名和证书

阿里云域名 + 阿里云 1 年免费证书 (推荐)

域名信息 内容 备注
域名 example.com 挑便宜的来
DNS 个人版 不要 用 Cloudflare
备案 你懂的 懂得都懂
证书 免费版 白嫖,格式要 Nginx 格式

有 OpenWrt 或者 AIO

用 DNSMASQ (或 BIND9 或 ADGuardHome 或其他同类 DNS 解析软件) 自己随便写一个不存在的域名,自己做解析,不讲

网络拓扑

公网访问 6443 管理端口会经常被 reset by peer

所以建议组建私有网络在本机或者登录到服务器上操作 Kubernetes

给 ECS 和本地 OpenWrt 搭建 ZeroTier 和 WireGuard 环境不在本文档范围内,可邮件我私聊

ECS 的安全组需要开启 22 9993 51820 80 443 端口,搭建私网后后续可以禁用 22

软件环境搭建

将系统软件包都更新到最新

sudo apt update
sudo apt upgrade -y
reboot

安装 K8S

众所周知的原因无法在服务器上下载某些资源

# 将二进制下载到本地
curl -LO 'https://github.com/k3s-io/k3s/releases/download/v1.25.0%2Bk3s1/k3s'
curl -Lo k3s-install.sh 'https://get.k3s.io'
curl -Lo k3s-install.sh 'https://get.k3s.io'
# 复制到服务器上
scp ./k3s root@101.xxx.yyy.zzz:/root
scp ./k3s-install.sh root@101.xxx.yyy.zzz:/root
# ssh登录到服务器
ssh root@101.xxx.yyy.zzz
# 离线安装
install -m 0755 ./k3s /usr/local/bin
# 这个--tls-san example.com写你申请的域名,没有可以不加
# 这个traefik不用他内嵌的v1,用v2或更高
cat ./k3s-install.sh | INSTALL_K3S_SKIP_DOWNLOAD=true sh -s - --disable=traefik  --tls-san example.com
# 安装helm
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | tee /usr/share/keyrings/helm.gpg > /dev/null
apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | tee /etc/apt/sources.list.d/helm-stable-debian.list
apt-get update
apt-get install helm -y
# 安装traefik
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik traefik/traefik
# 安装阿里云oss相关工具
apt install build-essential git -y
git clone https://github.com/aliyun/ossfs.git
cd ossfs/
./autogen.sh autoupdate
./autogen.sh
./configure
make
make install
touch /etc/passwd-ossfs
chmod 640 /etc/passwd-ossfs
# 这里写你自己的
echo 'Bucket名称:AccessKey ID:AccessKey Secret' | tee /etc/passwd-ossfs
# 写一个系统启动脚本,开机挂载oss
# 如果你OSS和ECS不在上海 oss-cn-shanghai-internal.aliyuncs.com改成对应的内网地址,记住,内网
cat <<EOF | tee /etc/systemd/system/mount-oss
[Unit]
Description=Mount OSS via ossfs for %I
Before=k3s.service
After=network-online.target nss-lookup.target
Wants=network-online.target nss-lookup.target
Documentation=https://github.com/aliyun/ossfs/blob/master/README-CN.md

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/bin/mkdir -p /mnt/oss/%i
ExecStart=/usr/local/bin/ossfs %i /mnt/oss/%i -ourl=oss-cn-shanghai-internal.aliyuncs.com -o noxattr -o allow_other
ExecStop=/usr/bin/umount /mnt/oss/%i

[Install]
WantedBy=multi-user.target
EOF
# 应用变更
systemctl daemon-reload
# 这里面@符号后面的是bucket名称
systemctl enable mount-oss@yukiko-live-recording
systemctl start mount-oss@yukiko-live-recording
# 可以试着去网页版OSS控制台添加几个文件
# 回来ls看看/mnt/oss/bucket名称下面有没有文件
# 如果没有,就是挂载失败或者权限配置不对

将这个文件修改修改保存为blrec-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blrec
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: blrec
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: blrec
    spec:
      containers:
        # 以后想升级改这里的镜像tag,重新 kubectl apply -f blrec-deployment.yaml
        - image: acgnhiki/blrec:v1.10.0
          imagePullPolicy: IfNotPresent
          name: blrec
          ports:
            - containerPort: 2233
              protocol: TCP
          resources:
            limits:
              cpu: "1"
              memory: 1000Mi
            requests:
              cpu: 100m
              memory: 256Mi
          volumeMounts:
            - mountPath: /cfg
              name: cfg
            - mountPath: /rec
              name: rec
            - mountPath: /log
              name: log
      restartPolicy: Always
      volumes:
        - hostPath:
            # 这里路径改一下,你想录制到哪个OSS文件夹就改哪个 bucket名称后面的文件夹是你在OSS里面的文件夹
            path: /mnt/oss/yukiko-live-recording/files/
            type: ""
          name: rec
        - hostPath:
            path: /mnt/oss/yukiko-live-recording/cfg/
            type: ""
          name: cfg
        - hostPath:
            path: /tmp/blrec/
            type: ""
          name: log

将这个文件保存为blrec-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: blrec
spec:
  clusterIP: None
  ports:
    - name: tcp-http
      port: 2233
      protocol: TCP
      targetPort: 2233
  selector:
    app: blrec
  type: ClusterIP

将这个文件修改修改保存为blrec-ingressroute.yaml

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: blrec
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      # 这里example.com修改成你自己的域名
      match: Host(`blrec.example.com`)
      services:
        - kind: Service
          name: blrec
          port: 2233
# 在服务器上运行
kubectl apply -f blrec-deployment.yaml
# 检查是否部署成功
kubectl get pods -l app=blrec | grep Running
# 如果有返回,就是部署成功,大概长下面这样
NAME                     READY   STATUS    RESTARTS   AGE
blrec-6fbbd6ff64-mvcxk   1/1     Running   0          1m
# 继续部署,以便可以浏览器远程访问控制台
kubectl apply -f blrec-service.yaml
kubectl apply -f blrec-ingressroute.yaml

DNS 设置

给你的域名添加指向 ECS 的 IP 的 A 记录

blrec.example.com A 101.xxx.yyy.zzz

浏览器打开blrec.example.com 看看能不能进入 blrec 的页面


进阶配置

使用 SSL

Traefik 配置 SSL 和 http 重定向 https

使用 Cloudflare

Cloudflare 接管 DNS

Cloudflare 配置 CDN 给网站

Cloudflare 配置 CDN 给 OSS

Cloudflare 配置 IP 访问限制

阿里云 ECS 安全组配置 80 和 443 端口允许 Cloudflare 访问

随便写个 web 的目录浏览器方便下载

这个我有现成的

配置内网穿透http服务

用Traefik

私网访问阿里云没有公网IP的内网数据库

通过webhook读取弹幕数据将礼物和上舰记录保存到数据库


总结

和腾讯云的方案比,不用自己手动同步虚拟机的系统盘里面的录播文件到OSS

缺点是OSS的写入请求次数有很多

用ffmpeg转mp4耗时很长也多花钱

添加元数据到flv文件也多花钱

好处是不用管剩余磁盘空间,只要管好马内~

录播到ECS不收费网络流量费

不直接从ECS下载录播文件不花流量费

ECS转存OSS的流量费呢,挂载的时候要用内网地址,才不会多收费

OSS存储费用和下载费用参考官方文档

Cloudflare的CDN是阿里云收OSS流出流量费用

Cloudflare白嫖不额外收费的

frankcui95 commented 2 years ago

@acgnhiki 如果你觉得有用,可以Pin在首页(狗头)