From c83c7d17acef3cb9cc85ed9b94347a9f0cfbb03b Mon Sep 17 00:00:00 2001 From: Sheogorath <sheogorath@shivering-isles.com> Date: Sun, 18 Feb 2024 02:38:29 +0100 Subject: [PATCH] feat(jellyfin): Add pdb-manager for jellyfin This patch introduces a new container to the jellyfin instance that talks to the kubernetes API and manages a PDB for jellyfin. It blocks evictions while at least one device is playing a video. This should prevent awkward situations during updates. --- apps/base/jellyfin/namespace.yaml | 3 +- apps/base/jellyfin/serviceaccount.yaml | 1 - .../jellyfin/jellyfin-pdb-mgr/deployment.yaml | 39 +++++++++++++ .../jellyfin-pdb-mgr/kustomization.yaml | 15 +++++ .../jellyfin-pdb-mgr/poddisruptionbudget.yaml | 10 ++++ .../k8s01/jellyfin/jellyfin-pdb-mgr/role.yaml | 25 ++++++++ apps/k8s01/jellyfin/jellyfin-token.yaml | 58 +++++++++++++++++++ apps/k8s01/jellyfin/kustomization.yaml | 6 +- .../networkpolicies/allow-to-kube-system.yaml | 16 +++++ 9 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 apps/k8s01/jellyfin/jellyfin-pdb-mgr/deployment.yaml create mode 100644 apps/k8s01/jellyfin/jellyfin-pdb-mgr/kustomization.yaml create mode 100644 apps/k8s01/jellyfin/jellyfin-pdb-mgr/poddisruptionbudget.yaml create mode 100644 apps/k8s01/jellyfin/jellyfin-pdb-mgr/role.yaml create mode 100644 apps/k8s01/jellyfin/jellyfin-token.yaml create mode 100644 shared/networkpolicies/allow-to-kube-system.yaml diff --git a/apps/base/jellyfin/namespace.yaml b/apps/base/jellyfin/namespace.yaml index 3afecf797..df6dd5379 100644 --- a/apps/base/jellyfin/namespace.yaml +++ b/apps/base/jellyfin/namespace.yaml @@ -1,4 +1,5 @@ apiVersion: v1 kind: Namespace metadata: - name: jellyfin \ No newline at end of file + name: jellyfin + labels: {} diff --git a/apps/base/jellyfin/serviceaccount.yaml b/apps/base/jellyfin/serviceaccount.yaml index 4271ce201..fb3202c9c 100644 --- a/apps/base/jellyfin/serviceaccount.yaml +++ b/apps/base/jellyfin/serviceaccount.yaml @@ -3,5 +3,4 @@ apiVersion: v1 kind: ServiceAccount metadata: name: jellyfin - namespace: jellyfin automountServiceAccountToken: false \ No newline at end of file diff --git a/apps/k8s01/jellyfin/jellyfin-pdb-mgr/deployment.yaml b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/deployment.yaml new file mode 100644 index 000000000..70477daf0 --- /dev/null +++ b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/deployment.yaml @@ -0,0 +1,39 @@ +- op: add + path: /spec/template/spec/containers/- + value: + command: + - /bin/bash + - -c + args: + - | + #!/bin/sh + + while true; do + if curl --variable %JELLYFIN_KEY 'http://localhost:8096/Sessions\?ApiKey\={{JELLYFIN_KEY:url}}' | jq -e '.[].NowPlayingItem != null'; then + kubectl patch --patch '{"spec": {"maxUnavailable:": 0}}' jellyfin + else + kubectl patch --patch '{"spec": {"maxUnavailable:": 1}}' jellyfin + fi + sleep 15 + done + env: + - name: JELLYFIN_KEY + valueFrom: + secretRef: + name: jellyfin-pdb-mgr + key: token + image: quay.io/shivering-isles/koolbox:0.5.1 + imagePullPolicy: IfNotPresent + name: jellyfin-pdb-mgr + resources: + requests: + memory: 64Mi + cpu: 10m + limits: + memory: 64Mi + cpu: 100m + securityContext: + allowPrivilegeEscalation: false +- op: add + path: /spec/template/spec/automountServiceAccountToken + value: true \ No newline at end of file diff --git a/apps/k8s01/jellyfin/jellyfin-pdb-mgr/kustomization.yaml b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/kustomization.yaml new file mode 100644 index 000000000..e10aa17be --- /dev/null +++ b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - poddisruptionbudget.yaml + - role.yaml + - ../../../../shared/networkpolicies/allow-to-kube-system.yaml + +patches: + - path: deployment.yaml + target: + kind: Deployment + group: apps + version: v1 + name: jellyfin \ No newline at end of file diff --git a/apps/k8s01/jellyfin/jellyfin-pdb-mgr/poddisruptionbudget.yaml b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/poddisruptionbudget.yaml new file mode 100644 index 000000000..8a97e97a9 --- /dev/null +++ b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/poddisruptionbudget.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: jellyfin +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: jellyfin \ No newline at end of file diff --git a/apps/k8s01/jellyfin/jellyfin-pdb-mgr/role.yaml b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/role.yaml new file mode 100644 index 000000000..301836322 --- /dev/null +++ b/apps/k8s01/jellyfin/jellyfin-pdb-mgr/role.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: jellyfin-pdb-mgr +rules: +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - patch + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: jellyfin-pdb-mgr +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: jellyfin-pdb-mgr +subjects: +- kind: ServiceAccount + name: jellyfin \ No newline at end of file diff --git a/apps/k8s01/jellyfin/jellyfin-token.yaml b/apps/k8s01/jellyfin/jellyfin-token.yaml new file mode 100644 index 000000000..567865333 --- /dev/null +++ b/apps/k8s01/jellyfin/jellyfin-token.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Secret +metadata: + name: jellyfin-pdb-mgr +stringData: + token: ENC[AES256_GCM,data:+a71royIE/6QLcM3KiHePXCR4BqSBhTWBSvHIVtcw9w=,iv:/m/PIqe+pCGNX6sGW90BW+2qRdZ9L5CmO2dMz6lxA38=,tag:0s6Ft3Ms20W7aKyC1KegWQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2024-02-18T01:38:22Z" + mac: ENC[AES256_GCM,data:HOpJetCDdSJmLdQ8LSQ5GS2j8V8rnzUBlI4EaWMLRMbkSWwoS/lJQ50KS91a55xZXS5xBgeO5STBvqKINo5JvOurmFYzYX2yRuO3gZ92yBLw6WwNYMwmAMJiey9Qr8E+Q2pJUPxxFllRQdAyjPqkhvIxefZ6bxyKbvYFSr/ZcM0=,iv:++g3Vkh3PGpXsSNIHFqz2h6QkoBAht/4s4RnvAeCduA=,tag:3rdBG+2R0Hn5LRc9QmqiWw==,type:str] + pgp: + - created_at: "2024-02-18T01:37:39Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + wcFMA7kpg2bgzVHcAQ//euYaemqol8lRFqeL8eIwASthHstLhYIOYsmjPRD2EPdJ + HdPd1GkV0+fXIEm5uT+hKFq52Ip12+l2GE3a51GUlunWZwLEEjuYpDZF+XaRNITq + yfFsnvHxKddpZHa9hZL8syOjlLgJIxneLw076PFAnkxc+4su3Ak92DcgRd7hsv6b + J/RbzV/F+kZ7BWI5IEzBlKYKq5BAI1o7WJ8frYWpeegdCgeBqFbfxEFIhnLOVxCs + xIVCM5nToV3vJh5LZK+JW3LuRAVVo35oIzmVC2WsbmHYp6uUTUHUN4si+So6xOzO + geYuuDEgwbOajcdlB/byjDBcBxFFJ3IkTVN5YqWSrVePJjf9fZ0LXwW2uhOs162b + uyMzvLRQ3x27KbHr6oxcwi0dQ3t4igmip2hBwpWFGwl4ZdGGbf7wrZ1ROteCMHUU + h/P4aMdGoDIzv0NQ2CS9SFDSlokWweFWcymKYDOx5l2dmSwi95x+tdWCAd9AeCrN + 7gClOSPv9SUcYzQwy+JjP4DVUmqFg7WQVILvuHIeV+sx7b9qjwKV5XLwFzzAdd3h + kkP7CK8umcku7eAeouPwkD686cOFBhl6orM2UUW9p8dR0IPsps45bz2M7yaaOvg6 + lWxYCWU10QbcH8Z5+Sx7iTzo7BCQcWMkpcNe2azVD78riYvkdd1B7aMCI840nBLS + UQGTqjkV2mcy7N+o20a3aG+GMZ+gokfc5fCjjcxeBrQP9eeS/6aM9J6COlTM7Oq9 + SRwTrPycAqzNwPMCvtd5WfkvJFKJDmhZa96XOTy71lS3yg== + =P6VL + -----END PGP MESSAGE----- + fp: 286791FB6648539775DB31B8FCB98C2A3EC6F601 + - created_at: "2024-02-18T01:37:39Z" + enc: | + -----BEGIN PGP MESSAGE----- + + hQIMA4oYbIHZIrAPAQ//QanePBkQOhPcQu0JuTEYt7Q/rAgMHqTcwxYeRNPp2r0g + CPsCBAjXb5+XDSiUxPHupGH0KJsbxQQUrMor/wHZN8f4UCye1uHWWf5RRXeqdkBB + PCkJhJOs5M+zq5LFNp4baG09pxIGAQytFSbFk5tcHM2UWu2ds/DqwZUgJoab2X/e + 07gp1liIG6huJ+6kSKh+Lhsy8BgVH6iV/y8yEE7vSRHTGkfjIjArBbk1fl/IJdne + sS03vlI1h64rGHE3Xyc5GXz7FONeUoWq+JLaq5wCZ1MBkDQvWB76aEjbzBrzT0wl + KJyCiUIsOPZCJXYoxEoANFLrb+Gekeyw3B2uSao2oFdElNfO+7qZ0IjPpAImiHJs + SMS4qg2Dx2qnR00GJo518xjefTC3PfrFVcZpRv9K9Vbf7D8H8TnsWbl3niVlVq4e + zwgKC9XbPD5CbxroUXj0ayJuYcXQP0rFWwCBWqqQcmrh9v0Uc6NXGGyGB+VTgle7 + aCwQWelo3mDlehsA7lt5ag9sHWpbKtfEVf6qoMmQHEousvq1OT1IXhZxKFmmafJQ + +03iBFonFQ0sqKbQUVVyfAjvBT8Fgqnh6b5AUqxyLBl20gHgBwbrUV4brcS7IJde + tRBXybUInCBMzwbsstVCOevhgh/BWnZNbCarPaJGVfHFbr6bAekBRSJXHmAxFBnU + aAEJAhDNb11du/FtFXCnXLOEWH+XuDnSLKHY9TXfauGoxsaOofZEvXKvdLE7UJqV + bADh+C9tgDOOHTS5n8LU/EXDF4jXaKUv7yLORdpfBSCxz2vM8vpIRg6F6wsAxBjU + OaBkuw7wMapR + =OT6k + -----END PGP MESSAGE----- + fp: B137EE1549DFAF960DD1E2B15147025FB9F09E07 + encrypted_regex: ^(data|stringData|email|dnsZones?|dnsNames?|.*(H|h)osts?|tang|externalURL|.*-secret|.*Secrets?|.*-domain|password|subjects|node|apiURL|.*(S|s)erverNames?|.*SecretKey|externalName)$ + version: 3.7.3 diff --git a/apps/k8s01/jellyfin/kustomization.yaml b/apps/k8s01/jellyfin/kustomization.yaml index c98b7c9f3..df4093d69 100644 --- a/apps/k8s01/jellyfin/kustomization.yaml +++ b/apps/k8s01/jellyfin/kustomization.yaml @@ -13,6 +13,7 @@ resources: - certificate.yaml - ingress.yaml - slo.yaml + - jellyfin-token.yaml - ../../../shared/resourcequotas/default.yaml patches: @@ -21,4 +22,7 @@ patches: kind: Deployment group: apps version: v1 - name: jellyfin \ No newline at end of file + name: jellyfin + +components: + - jellyfin-pdb-mgr \ No newline at end of file diff --git a/shared/networkpolicies/allow-to-kube-system.yaml b/shared/networkpolicies/allow-to-kube-system.yaml new file mode 100644 index 000000000..bbce0e223 --- /dev/null +++ b/shared/networkpolicies/allow-to-kube-system.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-to-kube-system +spec: + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + - to: + - ipBlock: + cidr: 192.168.100.0/24 # Kubernetes hosts + podSelector: + matchLabels: {} \ No newline at end of file -- GitLab