用 Plex 打造家裡的電影伺服器

用 Plex 打造家裡的電影伺服器

在前一篇文章提到搭了家裡的 home lab Kubernetes 集群,還有一個目的就是搭設一個可以在區域網路看電影的伺服器,這樣用手機也能順暢存取伺服器上的電影隨時看。

使用 kubeadm 搭設屬於自己的 home-lab
家裡架站的樹梅派用了一段時間之後,有時候還是想在上面裝一些別的軟體來玩,例如之前文章提到的 n8n,不過樹梅派就只有一張運算效能等資源都還是不太夠,所以就有了自建 Kubenetes 的念頭這樣就能玩更多東西,所以寫一下這篇文章記錄一下安裝過程,萬一之後搞壞了可以不用從頭查文件。 網站,誕生在樹梅派本站作為一個有技術分享的網站,首先當然要介紹一下這個網站是怎麼搭建起來的。這篇文章會分別介紹,這個部落格網站的主體、樹梅派上的環境設定以及如何買域名跟配置公網連接。 開源的部落格 Ghost 其實要架設部落格網站目前還蠻多選擇的,例如像是:WordPress、Hexo、Hugo等...... 那其…

Plex 是什麼?

Plex 是一個整合媒體播放器跟媒體伺服器的軟體,可以讓使用者整理音樂、影片、照片等內容,並提供 Android、IOS 平台 APP 讓使用者在行動裝置上能存取媒體伺服器的內容。

Meet your TV concierge.
Enjoy all of your entertainment, no matter where it lives, plus 50,000+ free titles from us.

當然,如果你只是想快速的把桌上型電腦的影片內容,架設伺服器分享出去,那可以到下面的連結,官方有提供 Windows 版本的伺服器安裝程式可以直接用。那今天主要就是來介紹如何安裝媒體伺服器在 Kubernetes 的集群上。

Media Server Downloads | Plex Media Server for Windows, Mac, Linux, FreeBSD and More
Click here to Download the Plex media server for Windows, Mac, Linux FreeBSD and more free today.

註冊帳號

首先到官網註冊一下帳號。

然後就這樣,可以開始安裝了。

集群設定

硬體

這一次會挑一台 Kubernetes 的 Worker Node 接上這個行動硬碟,已經格式化成 NTFS 格式,並預先放好影片檔案到裡面,來當作媒體伺服器的儲存裝置。

Samsung T7 Portable SSD | Samsung Semiconductor Global
The light, pocket-sized Samsung T7 delivers fast speeds with easy and reliable data stroage for transfering large files. Available in 500GB, 1TB or 2TB.

設定開機自動掛載行動硬碟

首先登入到插好行動硬碟的 Worker Node 下,然後先創建要掛載行動硬碟的目錄。

sudo mkdir /media/PSSD_T7

接著取得硬碟的 UUID。

lsblk -o NAME,FSTYPE,UUID,MOUNTPOINTS

接著編輯 /etc/fstab 檔案。

sudo nano /etc/fstab

在最後一行後添加以下內容。

UUID=<UUID> <PATH_TO_MOUNT> <DRIVE_TYPE> defaults 0 0

最後跑一下這個指令檢查設定正確性。

sudo findmnt --verify

然後重開機,再次執行下列指令確認掛載成功就可以。

lsblk -o NAME,FSTYPE,UUID,MOUNTPOINTS

安裝 Kubernetes Intel Device Plugin

由於我購買的 ZimaBoard 單板電腦 CPU Intel N3450 是有內顯的,所以可以安裝 Intel 的 Device plugin 讓 Pod 裡可以存取到主機上的內顯裝置,可以讓影片轉檔或是解碼的效能更好。

设备插件
设备插件可以让你配置集群以支持需要特定于供应商设置的设备或资源,例如 GPU、NIC、FPGA 或非易失性主存储器。

安裝步驟可以照這份文件的教學來做。

intel-device-plugins-for-kubernetes/README.md at main · intel/intel-device-plugins-for-kubernetes
Collection of Intel device plugins for Kubernetes. Contribute to intel/intel-device-plugins-for-kubernetes development by creating an account on GitHub.

首先先執行以下命令確認當前 Kernal 有支援內顯的 Driver,且顯卡裝置有被主機偵測到。

grep i915 /sys/class/drm/card?/device/uevent
lspci | grep -e VGA -e Display | grep Intel

接著執行下面的指令安裝 Device Plugin。
最後的版本號可以到 Release 頁面看一下最新是第幾版。

kubectl apply -k 'https://github.com/intel/intel-device-plugins-for-kubernetes/deployments/gpu_plugin?ref=v0.27.0'

安裝成功之後,執行以下的指令確定 Device Plugin 有安裝成功。

kubectl describe node {NODE NAME}

安裝 Plex Media Server

Plex 官方有提供 Docker 版本的 Media Server 可以用。

GitHub - plexinc/pms-docker: Plex Media Server Docker repo, for all your PMS docker needs.
Plex Media Server Docker repo, for all your PMS docker needs. - GitHub - plexinc/pms-docker: Plex Media Server Docker repo, for all your PMS docker needs.

首先來寫一下部屬用的 yaml 檔案,想偷懶的朋友文章最後會有完整的安裝清單可以下載。

首先建立這樣的目錄結構跟檔案。

resources/statefulset.yaml 的內容為部屬 Plex Media Server 的設定。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: plex
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: plex
  volumeClaimTemplates:
  - metadata: # 存放 Plex Media Server 本身設定的持久捲
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-path
      resources:
        requests:
          storage: 5Gi
  template:
    metadata:
      labels:
        app.kubernetes.io/name: plex
    spec:
      enableServiceLinks: false
      hostNetwork: true # 如同官方 Docker 部屬範例需要用 hostNetwork 模式部署
      nodeSelector:
        node.kubernetes.io/additional-media: PSSD_T7 # 指定在有掛載行動硬碟的 Node 跑
      volumes:
      - name: video # 掛載 Node 上行動硬碟的資料夾
        hostPath:
          type: Directory
          path: /media/PSSD_T7/Video
      containers:
      - name: plex
        image: plexinc/pms-docker
        imagePullPolicy: IfNotPresent
        envFrom:
        - secretRef:
            name: env
        resources:
          limits:
            cpu: "3"
            memory: 3Gi
            gpu.intel.com/i915: 1 # 設定需要使用 GPU 裝置
          requests:
            cpu: 100m
            memory: 128Mi
            gpu.intel.com/i915: 1
        ports:
        - name: http
          protocol: TCP
          containerPort: 32400
        readinessProbe:
          httpGet:
            port: http
            path: /identity
        livenessProbe:
          httpGet:
            port: http
            path: /identity
        volumeMounts:
        - name: data
          mountPath: /config
          subPath: config
        - name: data
          mountPath: /transcode 
          subPath: transcode
        - name: video
          mountPath: /Video

configs/env.txt 是要掛載進容器的環境變數列表,內容如下:
TZ 是時區容易理解,PLEX_CLAIM 是伺服器啟動時用來認證帳號的 Token,到下面的網址去取得一把。

Claim | Plex
Stream smarter.
TZ=Asia/Taipei
PLEX_CLAIM=claim-xxxxxxxxxxxxxxxxxxxx

最後是 kustomization.yaml 的檔案內容。

Image 的 Tag 可以到這個頁面取得最新版的版號。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./resources/statefulset.yaml
secretGenerator:
- name: env
  envs:
  - ./configs/env.txt
images:
- name: plexinc/pms-docker
  newTag: 1.32.2.7100-248a2daf0

最後執行這個指令來安裝。

kubectl apply -n plex -k .

設定 Plex Media Server

等待 Pod 都就緒之後,透過安裝 Plex Media Server 的主機位置連上
http://{NODE IP}:32400/web/index.html

設定伺服器名稱,以及看你的需求有沒有要讓伺服器在網際網路上能連上。

新增掛載到 Pod 內的行動碟的目錄成媒體庫目錄。

最後可以去手機上下載 Plex APP 登入帳號,等待媒體伺服器掃描完影片後就能看了。

‎Plex: Stream Movies & TV
‎Watch live TV free and hop into TV series you know and love on Plex. Discover brand new shows and enjoy on-demand TV channels and shows, all in one place. Watch TV anywhere, on any device, together with your friends! Streaming movies has never been easier with Plex. Watch your favorite movies fro…
Plex: Stream Movies & TV - Apps on Google Play
Watch TV shows and stream full movies across all of your devices seamlessly.

安裝 Samba Server

安裝完 Plex Media Server 之後,眼下還有一個問題,我如果下載了新的影片,難道我每次去拔行動硬碟嗎?

當然不是,所以我們需要來安裝一個 Samba Server 讓我在 Windows 電腦的檔案總管,就能直接簡單的複製檔案。

關於 Samba Server 可以看鳥歌的文章裏面有介紹這是一個什麼東西。

鳥哥私房菜 - 第十六章、檔案伺服器之二: SAMBA 伺服器

這次要拿來安裝的,是下面這個 Samba Server 的 Docker 版本。

GitHub - dperson/samba: Samba docker container
Samba docker container. Contribute to dperson/samba development by creating an account on GitHub.

我們在安裝的清單中 resources/statefulset.yaml 再加上下面的內容。

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: samba
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: samba
  template:
    metadata:
      labels:
        app.kubernetes.io/name: samba
    spec:
      enableServiceLinks: false
      hostNetwork: true # 同樣需要 hostNetwork 模式才能工作
      nodeSelector:
        node.kubernetes.io/additional-media: PSSD_T7 # 指定在有掛載行動硬碟的 Node 跑
      volumes:
      - name: pssd-t7 # 掛載 Node 上行動硬碟的資料夾
        hostPath:
          type: Directory
          path: /media/PSSD_T7
      - name: config
        configMap:
          name: samba
      containers:
      - name: samba
        image: dperson/samba
        imagePullPolicy: IfNotPresent
        env:
        - name: TZ # 設定伺服器時區
          value: Asia/Taipei
        - name: RECYCLE # 關閉資源回收桶功能
          value: "false"
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 100m
            memory: 128Mi
        ports:
        - name: samba-legacy
          protocol: TCP
          containerPort: 139
        - name: samba
          protocol: TCP
          containerPort: 445
        readinessProbe:
          tcpSocket:
            port: 445
        livenessProbe:
          tcpSocket:
            port: 445
        volumeMounts:
        - name: pssd-t7
          mountPath: /media/PSSD_T7
        - name: config
          mountPath: /etc/samba/smb.conf
          subPath: smb.conf
          readOnly: true

接著新增 configs/smb.conf 檔案添加以下內容。

# This is the main Samba configuration file. You should read the
# smb.conf(5) manual page in order to understand the options listed
# here. Samba has a huge number of configurable options (perhaps too
# many!) most of which are not shown in this example
#
# For a step to step guide on installing, configuring and using samba, 
# read the Samba-HOWTO-Collection. This may be obtained from:
#  http://www.samba.org/samba/docs/Samba-HOWTO-Collection.pdf
#
# Many working examples of smb.conf files can be found in the 
# Samba-Guide which is generated daily and can be downloaded from: 
#  http://www.samba.org/samba/docs/Samba-Guide.pdf
#
# Any line which starts with a ; (semi-colon) or a # (hash) 
# is a comment and is ignored. In this example we will use a #
# for commentry and a ; for parts of the config file that you
# may wish to enable
#
# NOTE: Whenever you modify this file you should run the command "testparm"
# to check that you have not made any basic syntactic errors. 
#
#======================= Global Settings =====================================
[global]

# workgroup = NT-Domain-Name or Workgroup-Name, eg: MIDEARTH
   workgroup = MYGROUP

# server string is the equivalent of the NT Description field
   server string = Samba Server

# Server role. Defines in which mode Samba will operate. Possible
# values are "standalone server", "member server", "classic primary
# domain controller", "classic backup domain controller", "active
# directory domain controller".
#
# Most people will want "standalone server" or "member server".
# Running as "active directory domain controller" will require first
# running "samba-tool domain provision" to wipe databases and create a
# new domain.
   server role = standalone server

# This option is important for security. It allows you to restrict
# connections to machines which are on your local network. The
# following example restricts access to two C class networks and
# the "loopback" interface. For more examples of the syntax see
# the smb.conf man page
;   hosts allow = 192.168.1. 192.168.2. 127.

# Uncomment this if you want a guest account, you must add this to /etc/passwd
# otherwise the user "nobody" is used
;  guest account = pcguest

# this tells Samba to use a separate log file for each machine
# that connects
   log file = /dev/stdout

# Put a capping on the size of the log files (in Kb).
   max log size = 50

# Specifies the Kerberos or Active Directory realm the host is part of
;   realm = MY_REALM

# Backend to store user information in. New installations should 
# use either tdbsam or ldapsam. smbpasswd is available for backwards 
# compatibility. tdbsam requires no further configuration.
;   passdb backend = tdbsam

# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting.
# Note: Consider carefully the location in the configuration file of
#       this line.  The included file is read at that point.
;   include = /usr/local/samba/lib/smb.conf.%m

# Configure Samba to use multiple interfaces
# If you have multiple network interfaces then you must list them
# here. See the man page for details.
;   interfaces = 192.168.12.2/24 192.168.13.2/24 

# Where to store roving profiles (only for Win95 and WinNT)
#        %L substitutes for this servers netbios name, %U is username
#        You must uncomment the [Profiles] share below
;   logon path = \\%L\Profiles\%U

# Windows Internet Name Serving Support Section:
# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
;   wins support = yes

# WINS Server - Tells the NMBD components of Samba to be a WINS Client
#       Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
;   wins server = w.x.y.z

# WINS Proxy - Tells Samba to answer name resolution queries on
# behalf of a non WINS capable client, for this to work there must be
# at least one  WINS Server on the network. The default is NO.
;   wins proxy = yes

# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
# via DNS nslookups. The default is NO.
   dns proxy = no 

# These scripts are used on a domain controller or stand-alone 
# machine to add or delete corresponding unix accounts
;  add user script = /usr/sbin/useradd %u
;  add group script = /usr/sbin/groupadd %g
;  add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u
;  delete user script = /usr/sbin/userdel %u
;  delete user from group script = /usr/sbin/deluser %u %g
;  delete group script = /usr/sbin/groupdel %g


   pam password change = yes
   map to guest = bad user
   usershare allow guests = yes
   create mask = 0664
   force create mode = 0664
   directory mask = 0775
   force directory mode = 0775
   force user = smbuser
   force group = smb
   follow symlinks = yes
   load printers = no
   printing = bsd
   printcap name = /dev/null
   disable spoolss = yes
   strict locking = no
   aio read size = 0
   aio write size = 0
   vfs objects = catia fruit streams_xattr

   # Security
   client ipc max protocol = SMB3
   client ipc min protocol = SMB2_10
   client max protocol = SMB3
   client min protocol = SMB2_10
   server max protocol = SMB3
   server min protocol = SMB2_10

   # Time Machine
   fruit:delete_empty_adfiles = yes
   fruit:time machine = yes
   fruit:veto_appledouble = no
   fruit:wipe_intentionally_left_blank_rfork = yes

[PSSD_T7] # 掛載行動硬碟的相關設定
   path = /media/PSSD_T7 # Pod 中的路徑
   browsable = yes # 目錄可以被瀏覽
   read only = no # 目錄受否唯讀
   guest ok = yes # 匿名使用者是否可以存取
   veto files = /.apdisk/.DS_Store/.TemporaryItems/.Trashes/desktop.ini/ehthumbs.db/Network Trash Folder/Temporary Items/Thumbs.db/ # 禁止寫入的檔案
   delete veto files = yes # 刪除禁止寫入的檔案
   hide files = /System Volume Information/$RECYCLE.BIN/ # 隱藏檔案,這兩個是 Windows 的系統資料夾,直接隱藏避免誤刪

最後 kustomization.yaml 增加內容最後如下:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./resources/statefulset.yaml
configMapGenerator: # 新增掛載 Samba Server 設定檔
- name: samba
  files:
  - smb.conf=./configs/smb.conf
secretGenerator:
- name: env
  envs:
  - ./configs/env.txt
images:
- name: plexinc/pms-docker
  newTag: 1.32.2.7100-248a2daf0

最後執行這個指令來安裝。

kubectl apply -n plex -k .

安裝完成後,到檔案總管,用 NODE IP 就能看到分享出來的資料夾,透過檔案總管就能輕鬆的新增影片到伺服器上。

最後

到這邊,Plex Media Server 算是架完了,也有 Samba Server 可以方便的新增影片檔案,那就祝大家看得愉快了。

完整安裝清單