转载请注明出处,本文仅用于学习交流,不对之处,恳请指正 ,部分图片摘取网络,如有侵权请联系
Proxmox VE(PVE) 7.x中,使用Ubuntu LXC安装Jellyfiy,并开启硬解码,直通网卡,修复Ubuntu中文乱码,修复Jellyfin中文显示框框,开启https,挂载NAS网络磁盘等,也解决了群晖没有部分核显驱动的问题
前因
为什么选择用LXC来部署Jellyfin,而非在NAS虚拟机中部署Jellyfin?
- Intel GPU很多都支持虚拟化,可供多个虚拟机或者LXC使用,故不使用直通的方式。
- 我的NAS并没有用到硬转码的功能
- 我的核显型号是P630,在NAS系统中安装驱动相对麻烦
使用LXC安装Ubuntu 22.04系统
-
先在CT Templates中下载对应的系统模板,这里我使用的是最新的 Ubuntu-22.04-standard
-
在对应的宿主机节点上右键创建CT(LXC),根据提示一步步完成即可,其中应该注意的是,我们需要取消选中非特权容器的按钮,以便访问宿主机的显卡或者开启SMB的功能,其他步骤就不再赘述。
-
根据提示完成安装后,启动LXC容器,并进入容器中
-
更新源
apt-get update
-
更新软件
apt-get dist-upgrade
-
Proxmox VE(PVE) 7.x 下,LXC"直通"核显
宿主机中操作
-
关闭LXC容器
-
获取显卡文件ID
ls -l /dev/dri/ # drwxr-xr-x 2 root root 80 Jul 14 01:29 by-path # crw-rw---- 1 root video 226, 0 Dec 29 11:20 card0 # crw-rw---- 1 root render 226, 128 Jul 14 01:29 renderD128
-
修改LXC容器配置映射显卡
编辑对应的LXC配置文件,如
,将上面查询到的ID写入到配置文件中nano /etc/pve/lxc/101.conf
# Proxmox VE(PVE) 6.x # lxc.cgroup.devices.allow: c 226:0 rwm # lxc.cgroup.devices.allow: c 226:128 rwm # Proxmox VE(PVE) 7.x lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.autodev: 1 lxc.hook.autodev: /var/lib/lxc/101/mount_hook.sh # lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file # lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
-
编写mount_hook脚本
nano /var/lib/lxc/101/mount_hook.sh
写入以下代码
mkdir -p ${LXC_ROOTFS_MOUNT}/dev/dri mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/card0 c 226 0 mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/renderD128 c 226 128
修改脚本权限为可执行
chmod +x /var/lib/lxc/101/mount_hook.sh
(可选) Proxmox VE(PVE) 7.x下, LXC"直通"网卡
宿主机中操作
如果你没有特定的硬件网卡需要绑定可以跳过此步骤。!!!如果你有绑定网卡的需求,需要在桥接网卡下,最少启动过LXC容器一次!!!
-
因为视频播放占用的流量较大,使用桥接网卡可能会导致占用过多性能,我们可以通过以下方式绑定特定的网卡。
lxc.net.0.type: phys lxc.net.0.link: enp7s0f0 lxc.net.0.ipv4.address: 192.168.1.101/24 lxc.net.0.ipv4.gateway: 192.168.1.100 lxc.net.0.flags: up
-
删除原先的桥接网卡
我们可以选择在Proxmox的管理页面删除,也可以在配置文件中删除。
-
启动LXC容器并测试网卡是否可用
ping 114.114.114.114
解决LXC容器内Ubuntu Server 22.04显示中文乱码问题
编辑/etc/default/locale文件
nano /etc/default/locale
修改为以下内容
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
修改Linux的时区
查看当前设置的时区
timedatectl
列出所有可用时区
timedatectl list-timezones
设置时区为上海时区
timedatectl set-timezone Asia/Shanghai
开启NTP时钟同步
timedatectl set-ntp true
Proxmox VE(PVE) 7.x下,LXC中安装Jellyfin
-
安装apt-transport-https,software-properties-common
# Install HTTPS transport for APT as well as gnupg and lsb-release if you haven't already. apt-get install apt-transport-https software-properties-common -y
-
加入Universe仓库
# Enable the Universe repository to obtain all the FFMpeg dependencies: add-apt-repository universe
-
获取密钥
# Import the GPG signing key (signed by the Jellyfin Team): wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | apt-key add -
-
添加Jellyfin源
# Add a repository configuration at /etc/apt/sources.list.d/jellyfin.list: echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | tee /etc/apt/sources.list.d/jellyfin.list
-
更新源
apt-get update
-
安装Jellyfin
apt-get install jellyfin -y
-
查看Jellyfin运行状态
service jellyfin status
-
开机启动
systemctl enable jellyfin
-
打开网站
http://192.168.1.101:8096
Proxmox VE(PVE) 7.x下,LXC中开启Jellyfin硬解
经过测试,我们并不需要在宿主机安装驱动。本着不污染宿主机的精神,不对宿主机进行任何操作
-
安装 gpg-agent
apt-get install -y gpg-agent
-
获取密钥
wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | apt-key add -
-
新增安装源
echo "deb [trusted=yes arch=amd64] https://repositories.intel.com/graphics/ubuntu focal main" > /etc/apt/sources.list.d/intel-graphics.list
-
更新源
apt-get update
-
安装驱动
apt-get install -y intel-media-va-driver-non-free intel-gpu-tools vainfo
-
测试驱动是否正常
vainfo
输出以下内容则正常
-
在Jellyfin控制台中选中播放,并启用硬解,注意你的核显或显卡支持哪些格式,如果需要启动低功耗模式,需要在宿主机进行一些配置,这里我就不进行修改了
解决Jellyfin中文显示框框的问题
因为Jellyfin对中文字体支持不好,所以我们可以通过Jellyfin管理页面的备用字体来解决这个问题。为了后续可以一次性配置完成,所以我选择先上传字体
-
启动Root账号登陆
nano /etc/ssh/sshd_config
-
修改PermitRootLogin项为yes,如该项为被注释状态(最前面有个#),则先取消该项注释(删掉#号)
-
重启ssh
systemctl restart sshd
-
复制字体,我选择的是微软雅黑,直接在Windows中复制的,如果你是想要公开使用你的视频网站,甚至是商用,请注意版权问题....
在ubuntu中先新建一个存放字体的目录,Jellyfin的默认目录为:
,所以我选择在相同目录下新建一个文件夹/usr/share/fonts/truetype/dejavu
mkdir /usr/share/fonts/truetype/msyh
在windows或者其他你所使用的操作系统
scp -R ~/Desktop/msyh* root@192.168.1.101:/usr/share/fonts/truetype/msyh/
在控制台中选择播放,启用备用字体,这里需要注意的是路径最后需要有一个斜杆,否则无法找到字体
-
修改完成之后需要重启
systemctl restart jellyfin
或者直接重启服务器
reboot
Jellyfin挂载群晖或者其他NAS系统的Samba服务
1. 安装CIFS,并挂载Samba
-
安装CIFS
apt-get install cifs-utils -y
-
创建被挂载的文件目录
mkdir -p /mnt/nas/nasname/samba
-
挂载Samba(非永久,可自行在/etc/fstab中配置开机自动挂载,我使用的是另一种方式)
mount -t cifs //你的NAS的IP/你的共享目录 /mnt/nas/nasname/samba -o user=你的账号,password=你的密码,vers=2.1,mfsymlinks
2. Proxmox VE(PVE) 7.x 安装虚拟交换机
如果你的NAS跟你的LXC容器均在同一台Proxmox主机下,你可以通过虚拟交换机来实现内部通讯,只要你的CPU性能够强,是完全可以跑满硬盘速度的。
- 安装openvswitch
apt-get install openvswitch-switch -y
-
Network->Create->OVSBridge
IPV4中写入: 10.0.0.1/8
-
Network->Create->OVSIntPort
name中写入: ovseno1, OVS Bridge中选中vmbr1
-
分别在LXC容器与你的NAS虚拟机中新建网卡,均选中vmbr1,并输入你想要的IP地址,切记LXC的IP段与你的NAS的IP段相同,且都不输入网关
3. (可选) 延迟挂载Samba,并自动识别NAS是否在线
相信很多朋友在使用Proxmox的同时,会将NAS系统安装在Proxmox之中,所以其他虚拟机想要挂载对应的Samba或者NFS服务,一般都是采用延迟启动的方式,这是一个方案。但考虑到有时候我会关闭NAS虚拟机,所以我更期望的方式是自动检测到对应的NAS系统启动后,自动挂载。于是我编写了以下脚本
-
创建脚本存放的目录
mkdir /usr/script
-
编写脚本
nano /usr/script/nasname-smb.sh
写入以下代码,需要注意的是,我将离线日志写入到系统日志中,如果你有长时间不在线的情况下,请自行修改对应的脚本内容,以免出现过多的日志内容
#!/bin/bash # author alain # site:https://www.alainlam.cn # 循环检测Samba服务器是否在线,并自动挂载 server_ip="10.0.0.101" server_path="/media" mount_point="/mnt/nasname/media" # 是否循环检查是否在线(没有挂载时) online_check=true # 循环检查是否在线的间隔时间(没有挂载时) online_check_interval=10 # 离线检查 offline_check=true # 离线检查间隔时间 offline_check_interval=60 # SMB账号 smb_username="你的账号" # SMB密码 smb_pwd="你的密码" # 是否已经挂载 isMounted=false while :; do if mountpoint -q $mount_point; then if ! $isMounted; then # 设置为挂载状态 isMounted=true echo "SMB挂载成功" if $offline_check; then echo "开启在线状态检测,间隔时间${offline_check_interval}s" fi fi if $offline_check; then sleep $offline_check_interval continue fi else # 设置为非挂载状态 isMounted=false echo "SMB没有挂载,ping ${server_ip} ..." if (ping -c 1 -w 5 $server_ip >/dev/null 2>&1); then echo "${server_ip}在线,尝试挂载" # 判断挂载目录是否存在 if [ ! -d $mount_point ]; then echo "挂载目录不存在,新建目录" mkdir -p $mount_point fi if [ ! -d $mount_point ]; then echo "挂载目录不存在,取消挂载,请检查权限, code:403" exit 403 fi # 挂载SMB网络硬盘 mount.cifs -o vers=2.1,username=$smb_username,password=$smb_pwd //$server_ip$server_path $mount_point if mountpoint -q $mount_point; then continue else echo "挂载失败" if $online_check; then echo "继续尝试挂载${server_ip},间隔时间${online_check_interval}s" sleep $online_check_interval continue else echo "不继续尝试挂载,退出脚本,code:404" exit 404 fi fi else if $online_check; then echo "${server_ip}离线,上线检查间隔时间${online_check_interval}s" sleep $online_check_interval continue else echo "不循环检查,退出脚本,code:404" exit 404 fi fi fi done
-
加入执行权限
chmod +x /usr/script/nasname-smb.sh
-
编写开机启动服务
nano /etc/systemd/system/nasname-smb.service
写入以下代码
[Unit] Description=Automatically mount the SMB folder from nasname After=network.target [Service] Type=simple ExecStart=/usr/script/nasname-smb.sh [Install] WantedBy=multi-user.target
-
设置开机启动
systemctl enable --now nasname-smb.service
-
查看运行效果
Jellyfin开启Https
当你希望使用Nginx进行反向代理时,你可以跳过此步骤,直接看Nginx反向代理部分
-
新建存放SSL证书的目录
mkdir -p /etc/ssl/certificates
-
上传证书到指定目录
scp -R ~/Desktop/alainlam.cn* root@192.168.1.101:/etc/ssl/certificates/
-
进入证书目录,并生成pfx证书
进入证书目录
cd /etc/ssl/certificates/
生成pfx证书
openssl pkcs12 -export -out alainlam.cn.pfx -inkey alainlam.cn.key -in alainlam.cn.pem
根据提示输入密码,可设置为空
-
修改证书所有者
chown jellyfin:jellyfin /etc/ssl/certificates/ -R
-
在Jellyfin控制台中启用Https
-
填写证书路径
其中强制HTTPS为可选
-
完成配置后需要重启Jellfyfin
文章评论
文章不错, 但是不知道你有没有实际长时间运行你的服务.
首先exit 404完全没必要, 只会导致服务结束, 而最重要的断线重连就无从提起了.
而且LXC容器运行一段时间后会断连, 而实际上smb服务器(我直接用的win server 2022)并没有离线.
此时你的systemd服务mount会报错
mount error(11): Resource temporarily unavailable
解决方法只有umount -a -t cifs再mount -a -t cifs
有时甚至umount都无响应, 只能重启容器.
最后我发现最简单实现断线重连的办法就是在pve->datacenter->storage里添加cifs存储(Content随便选一个就行).
添加完后会被挂载到/mnt/pve/底下
然后修改你的LXC配置文件
nano /etc/pve/lxc/107.conf
在最后面加上
lxc.mount.entry: /mnt/pve/f-serv01/NAS/media media none bind 0 0
lxc.mount.entry: /mnt/pve/f-serv01/NAS/downloads downloads none bind 0 0
重启容器.
这样你就拥有了自动挂载自动断线重连的bind mount了, 稳定度比LXC容器内的挂载脚本或者systemd服务高得多.
PS:
创建LXC容器可以试试现成的一键脚本:
https://tteck.github.io/Proxmox/
显卡直接直通的, 只需要自己加上网桥和挂载就能用了.
@TriATK 很高兴您的阅读,但是你可能没仔细看
1. exit 404就是不再继续挂载了,输出日志就是怎么写的"不继续尝试挂载,退出脚本,code:404",前面我写了参数配置的,online_check
2. LXC容器运行一段时间后失联...我真没遇到过,我一直在用这个脚本。
3. pve->datacenter->storage这个方法我也写了,不过不在这篇文章,https://www.alainlam.cn/?p=278#toc-3,主要还是因为我是分开账号密码登录我的NAS的,HOST有自己的账号密码,其他部分容器也是,方便我自己管理
4. 感谢你的分享
@Alain 新年快乐! 谢谢您的回复, 我这可能是因为pve(v7.3-4) 用了6.1的内核问题还是啥的, LXC用脚本挂载稳定几个小时后就掉线而且大概率无法恢复, 只能重启容器.
这个问题只出现在LXC容器而不会出现在VM里.
出现问题的时候, dmesg会出现
CIFS: VFS: cifs_mount failed w/return code = -11
的错误.
此时你容器内ping NAS是可以ping通的, 但是就是LXC容器的smb挂了, 其它vm里甚至docker里挂载的smb一点问题也没有, LXC和NAS本身的网络也是正常的.
你的脚本, 在这种情况下会在执行到exit 403的时候自动跳出循环然后停止.
虽然你本意是通过! -d $mount_point检测挂载点是否存在, 但是在出错的时候.
! -d $mount_point 返回的也是true, 虽然挂载点实际上存在, 只是temporarily unavailable.
此时跳出就不会再尝试挂载目录了, 也就没有达到断线重连的目的.
其实pve->datacenter->storage的办法也能用不同账号密码, 只是会先挂载在HOST里面罢了. 而且你用
lxc.mount.entry的这种写法的话. Snapshot和增量backup亲测都没有问题, 我是用的独立的proxmox backup server(v2.3-2).
我之前jellyfin一直是用的docker, 最近为了试试12代iGPU硬解才移到LXC容器的, 没想到就碰到这个频繁掉线的问题.
@TriATK 我用的是也是7.3-4,但是我没有升级内核。
所以结论是在6.1内核上,检查挂载正常代码正常,因为离线所以返回为false,而判断文件夹是否还在的代码也正常,因为目录已经不在了,所以非条件下返回为true,好像逻辑上没什么问题。
关键点是在上一个判断创建目录的地方mkdir -p $mount_point,并无法创建成功,所以判定为无权限操作,退出程序。所以这里可以优化一下代码,把文件夹创建放到最前面,后续在在线检测不再创建文件夹,只是尝试断开重新挂载。
嗯,确实是可以。考虑到安全问题,所以我NAS上的文件夹也是不同权限访问的,所以我本来也有不想把账号都扔在一起的目的。
@TriATK 另外,祝你新年快乐,早点休息!
@TriATK 使用这个配置后,权限怎么配置呢?挂载后是root权限,jellyfin要使用的话还得都改一下权限吗?
lxc.mount.entry: /mnt/pve/f-serv01/NAS/media media none bind 0 0
lxc.mount.entry: /mnt/pve/f-serv01/NAS/downloads downloads none bind 0 0
@Owen 邮箱回复你了,这里备注下
----------------------------
看起来你似乎是想挂载主机的目录,如果你是特权容器的话(Jellfyin根据一系列操作也可以做到非特权),那么你容器的root是可以修改权限的,将目录权限分配给Jellfin即可。但是这样修改后,host主机的权限有可能会跟容器内对应不上,所以更推荐的做法就是容器内用户映射到host主机的用户。
假设你容器外目录权限给了1005,那么在你的lxc.conf中加入
# uid map: from uid 0 map 1005 uids (in the ct) to the range starting 100000 (on the host), so 0..1004 (ct) → 100000..101004 (host)
lxc.idmap = u 0 100000 1005
lxc.idmap = g 0 100000 1005
# we map 1 uid starting from uid 1005 onto 1005, so 1005 → 1005
lxc.idmap = u 1005 1005 1
lxc.idmap = g 1005 1005 1
# we map the rest of 65535 from 1006 upto 101006, so 1006..65535 → 101006..165535
lxc.idmap = u 1006 101006 64530
lxc.idmap = g 1006 101006 64530
/etc/subuid中加入
root:1005:1
/etc/subgid中加入
root:1005:1
你也可以将这两个id分配给指定用户
sudo useradd -u 1005 -g 1005 -s /usr/sbin/nologin username
@TriATK '创建LXC容器可以试试现成的一键脚本:
https://tteck.github.io/Proxmox/
显卡直接直通的, 只需要自己加上网桥和挂载就能用了.'
我仔細研究了一下大神的腳本,他裡面的 CT 創建裡面,真的有針對 Jellyfin, Plex, Frigate 等等的直通設定,確實牛:
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 29:0 rwm
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
EOF
fi
谢谢,帮我解决了pve+lxc显卡直通问题