feat(plex): initial commit of plex

This commit is contained in:
David Landry 2024-05-27 16:11:47 -04:00
parent e8c2cdca94
commit 91f64320f9
17 changed files with 934 additions and 0 deletions

View file

@ -0,0 +1,73 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: plex
labels:
app: plex
spec:
replicas: 1
selector:
matchLabels:
app: plex
template:
metadata:
annotations:
labels:
app: plex
spec:
volumes:
- name: plex-config
persistentVolumeClaim:
claimName: plex-config
containers:
- name: plex
image: plexinc/pms-docker:plexpass
imagePullPolicy: Always
resources:
requests:
cpu: 1
memory: 512Mi
ports:
- containerPort: 32400
name: http
- containerPort: 32400
name: plex-udp
protocol: UDP
- containerPort: 32469
name: plex-dlna
- containerPort: 1900
name: plex-dlna-udp
protocol: UDP
- containerPort: 5353
name: plex-discovery
protocol: UDP
- containerPort: 3005
name: plex-comp
- containerPort: 32410
name: plex-gdm1
protocol: UDP
- containerPort: 32412
name: plex-gdm2
protocol: UDP
- containerPort: 32413
name: plex-gdm3
protocol: UDP
- containerPort: 32414
name: plex-gdm4
protocol: UDP
env:
- name: GID
value: "1000"
- name: UID
value: "1000"
- name: PLEX_GID
value: "1000"
- name: PLEX_UID
value: "1000"
- name: CHANGE_CONFIG_DIR_OWNERSHIP
value: "false"
- name: TZ
value: UTC
volumeMounts:
- mountPath: /config
name: plex-config

View file

@ -0,0 +1,545 @@
# NOTE: this is not tested and not currently included in kustomization.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: plex-grafana
namespace: grafana #Needs to match the Grafana installation namespace
labels:
grafana-dashboard: "1" #Required to have the Grafana sidecar container pick up the new dashboard
data:
plex-prometheus.json: |
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 3,
"links": [],
"panels": [
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"text": {},
"textMode": "auto"
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum(plex_library_section_size_count)",
"instant": true,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Total Library items",
"type": "stat"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 8,
"y": 0
},
"id": 5,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"text": {},
"textMode": "auto"
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum(plex_sessions_active_count)",
"instant": true,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Active sessions",
"type": "stat"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 16,
"y": 0
},
"id": 6,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"text": {},
"textMode": "auto"
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum(plex_transcode_sessions_active_count)",
"instant": true,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Transcode sessions",
"type": "stat"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum (plex_library_section_size_count) by (name)",
"interval": "",
"legendFormat": "{{name}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Library items by Name",
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum (plex_sessions_active_count)",
"interval": "",
"legendFormat": "Sessions",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Active sessions",
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": true
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 16
},
"id": 8,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"plex.*\",pod!~\"plex-exporter.*\"}[1m]))by(pod)",
"interval": "",
"legendFormat": "{{container}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Pod CPU usage",
"type": "timeseries"
},
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": true
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 16
},
"id": 9,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.5.6",
"targets": [
{
"exemplar": true,
"expr": "sum (container_memory_working_set_bytes{pod=~\"plex.*\",pod!~\"plex-exporter.*\"}) by (container_name, pod_name)",
"interval": "",
"legendFormat": "Memory",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Pod Memory usage",
"type": "timeseries"
}
],
"refresh": "10s",
"schemaVersion": 27,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Plex",
"uid": "w8ttuLbnk",
"version": 10
}

View file

@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- pvc.yaml
- service.yaml
# - graphana.yaml
# - prometheus-exporter.yaml

View file

@ -0,0 +1,68 @@
# NOTE: this is not tested and not currently included in kustomization.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: plex-exporter
data:
config.yaml: |
address: ":9594"
logLevel: "info"
logFormat: "text"
autoDiscover: false
token: "<your-token>"
servers:
- baseUrl: http://plex-tcp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: plex-exporter
namespace: plex
labels:
app: plex-exporter
spec:
replicas: 1
selector:
matchLabels:
app: plex-exporter
template:
metadata:
labels:
app: plex-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/scheme: "http"
prometheus.io/path: "/metrics"
prometheus.io/port: "9594"
spec:
containers:
- name: plex-exporter
image: granra/plex_exporter:v0.2.3
imagePullPolicy: Always
ports:
- containerPort: 9594
name: metrics
volumeMounts:
- name: config
mountPath: /etc/plex_exporter/config.yaml
subPath: config.yaml
volumes:
- name: config
configMap:
name: plex-exporter
---
kind: Service
apiVersion: v1
metadata:
name: plex-exporter
namespace: plex
spec:
selector:
app: plex-exporter
ports:
- port: 9594
name: metrics
protocol: TCP
type: ClusterIP #Change to LoadBalancer if you want to check out the metrics page directly

10
apps/plex/base/pvc.yaml Normal file
View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: plex-config
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi

View file

@ -0,0 +1,38 @@
kind: Service
apiVersion: v1
metadata:
name: plex-udp
# annotations:
# metallb.universe.tf/allow-shared-ip: plexserver # annotation name to combine the Service IP, make sure it's same name as in the service UDP yaml
spec:
selector:
app: plexserver
ports:
- port: 1900
targetPort: plex-dlna-udp
name: dlna-udp
protocol: UDP
- port: 5353
targetPort: plex-discovery
name: discovery-udp
protocol: UDP
---
kind: Service
apiVersion: v1
metadata:
name: plex-tcp
# annotations:
# metallb.universe.tf/allow-shared-ip: plexserver
spec:
selector:
app: plexserver
ports:
- port: 80
targetPort: http
name: http
protocol: TCP
- port: 32469
targetPort: plex-dlna
name: dlna-tcp
protocol: TCP