I’m looking for some feedback on my Plex system architecture.

All my media is stored on a Synology DS 1621+, six 4 TB drives in RAID 6 with one acting as a hot spare. All four network ports are bonded into a 4G link to an Ubiquiti USW-48-POE.

Previously, I ran Plex in a Docker container on the NAS. This setup was stable; however, the NAS only has 4 GB of memory shared between Plex, several other Docker services, and regular DSM overhead. Plus, the processor is not very powerful (AMD Ryzen V1500B, ~5400 PassMark).

A few months ago I repurposed some old desktop PC parts to build a home lab Proxmox server (Core i7-6700K [~8900 PassMark], 32 GB memory, GTX 970, an old 2.5” SATA SSD for guest OS disks, 1G networking on the motherboard). I’m running Plex on an Ubuntu VM, with the GPU passed through directly to the guest OS. Plex is not containerized in Ubuntu. The VM has 8 CPU cores and 8 GiB memory (different units in Proxmox). My Plex media is accessed via a persistent NFS mount in Ubuntu (had been SMB before a DSM update broke something and the VM could no longer read the directory contents.)

The main purpose of the change from NAS to VM was to utilize the increased CPU/GPU horsepower and memory that I had lying around, but I worry that the added layers of complexity (hypervisor/VM, PCIe pass through, NFS mounts) will introduce more opportunities for performance issues. I have noticed more frequent hiccups/buffering/transcoding since the change but I’m not sure if it’s related to my setup or if those issues lie with client devices and/or the files themselves (e.g. weird file container type that the client can’t play natively).

Any critique or recommendations on system architecture? Should I get a dedicated NIC to pass through to my VM? Dedicated NVMe drive passed through as a guest OS disk? Ditch Proxmox altogether and go back to Synology Docker container?

  • liara
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    1 year ago

    I mean you could just use docker and if all you want is a plex container, it may be the way to go. Kubernetes is definitely a lot to learn if you are kind of hesitant to get started with it in the first place. I would just say that single binary distribution like k0s just basically becomes a docker on steroids when used in a single node environment. I’ve become so familiar with k8s that going back to docker feels like a massive downgrade for anything but a simple and straightforward task (which a single plex container, admittedly is).

    Just do yourself a favour and if you go that route, at least use docker-compose to template your container. Searching through your bash history to find the command you used to start the container is just a recipe for frustration waiting to happen.

    One major feature that k8s has which docker doesn’t (I mean, there are lots tbh) is the ability to use helm charts. These are basically install templates, if you don’t like the defaults then you can provide your own (assuming the chart author has written good charts) and the helm chart will template your values into the default chart and spin up a bespoke version for you.

    For instance, a theoretical helm chart whose purpose is to install qbittorrent would likely provide the following:

    • the manifest to run a version of qbittorrent
    • a cluster IP to expose the plex web port internally
    • an “ingress” object to connect your nginx frontend to the qbittorrent web port so that you can go to mydomain.com/qbittorrent and qbittorrent appears
    • a volume mount to store your data in

    However, say this ingress by default doesn’t use SSL, but you want to ensure you’re using https when you enter the password on your web interface, but the rest of the chart defaults meet your needs – then a well written chart would allow you to provide values that let you template the SSL setup for the ingress object and provide for cert-manager to go and provision some certificates for your provided hostname with Let’s Encrypt.

    Helm charts basically are a way to provide a sane set of defaults which can be extended and customized to personal needs.

    k8s (or the lightweight cousins) may not be ideal for you and, as I said, I’m biased because I’m a certified k8s admin, so tinkering with k8s resembles something like fun for me. Your mileage may vary :)

    Terms:

    • batteries: this isn’t a kubernetes term, just a figure of speech. You got a new toy and it came with batteries – you didn’t have to supply them yourself. The batteries were included (i.e. the installation was opinionated and came with a pre-existing notion of how you should use the application). I wrote that last comment from my phone, so I may have misused the term in an attempt to get a response written on my phone
    • pod: a collection of containers running in tandem – for instance, if you had nginx and plex running in the same pod, then plex can find nginx ports as if they were sharing the same machine (127.0.0.1 is the same for both containers). If you had nginx and plex running in different pods, then you would need to use a service to allow them to communicate with each other (which they could easily do with the cluster’s dns service)
    • manifest: a yaml file containing the spec of your containers (name, container port, image to use, volumes to mount). This would basically equate to a docker compose file, but manifests can also define services, namespaces, volumes, etc. In that regard a manifest is a yaml file that defines an object in kubernetes
    • nodeport: a type of service. This one will direct traffic to a given pod and potentially open that service to external services. By default nodeports are given in the 30000-32767 range and will bind to the hosts network interface. The result is that the service becomes available on a port externally. The other service type is clusterip which only assigns an IP which can be accessed internally (i.e. by other pods/services in your cluster – for instance if you had a mysql service you wanted to expose to a web/application pod but not let the world access it, then clusterIP lets you do this). The final service type is loadbalancer which is a bit more complicated (TLDR, these are frequently integrated with cloud providers to automatically spin up actual load balancer objects, for instance, at AWS, but can also be used to bind services to privileged ports on your external IP while leveraging something like “MetalLB”)