--- # Namespace (trust zone; default-deny + policies apply) apiVersion: v1 kind: Namespace metadata: name: seerr labels: homelab.keithjackson.dev/app-namespace: 'true' gateway-access: shared annotations: homelab.keithjackson.dev/backup-policy: daily-offcluster --- # Default-deny baseline (R-NET-01): deny all, allow only DNS apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: seerr labels: homelab.keithjackson.dev/baseline: default-deny spec: podSelector: {} policyTypes: - Ingress - Egress ingress: [] egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53 - protocol: TCP port: 53 --- # PVC seerr-config (R-STATE) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: seerr-config namespace: seerr labels: app.kubernetes.io/name: seerr spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi --- # Deployment (R-PLAT-02) apiVersion: apps/v1 kind: Deployment metadata: name: seerr namespace: seerr labels: app.kubernetes.io/name: seerr spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: seerr template: metadata: labels: app.kubernetes.io/name: seerr homelab.keithjackson.dev/egress-class: internet homelab.keithjackson.dev/auth-mode: native spec: containers: - name: seerr image: ghcr.io/seerr-team/seerr:v3.5.1 ports: - containerPort: 5055 volumeMounts: - name: config mountPath: /app/config securityContext: runAsUser: 1000 runAsGroup: 1000 runAsNonRoot: true fsGroup: 1000 volumes: - name: config persistentVolumeClaim: claimName: seerr-config --- # Service apiVersion: v1 kind: Service metadata: name: seerr namespace: seerr labels: app.kubernetes.io/name: seerr spec: selector: app.kubernetes.io/name: seerr ports: - name: port-5055 port: 5055 targetPort: 5055 --- # CiliumNetworkPolicy egress allow (R-NET-02): seerr-allow-sonarr-8989 apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: seerr-allow-sonarr-8989 namespace: seerr labels: app.kubernetes.io/name: seerr spec: endpointSelector: matchLabels: app.kubernetes.io/name: seerr egress: - toEndpoints: - matchLabels: app.kubernetes.io/name: sonarr k8s:io.kubernetes.pod.namespace: sonarr toPorts: - ports: - port: '8989' protocol: TCP --- # CiliumNetworkPolicy egress allow (R-NET-02): seerr-allow-radarr-7878 apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: seerr-allow-radarr-7878 namespace: seerr labels: app.kubernetes.io/name: seerr spec: endpointSelector: matchLabels: app.kubernetes.io/name: seerr egress: - toEndpoints: - matchLabels: app.kubernetes.io/name: radarr k8s:io.kubernetes.pod.namespace: radarr toPorts: - ports: - port: '7878' protocol: TCP --- # CiliumNetworkPolicy egress allow (R-NET-02): seerr-allow-plex-32400 apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: seerr-allow-plex-32400 namespace: seerr labels: app.kubernetes.io/name: seerr spec: endpointSelector: matchLabels: app.kubernetes.io/name: seerr egress: - toEndpoints: - matchLabels: app.kubernetes.io/name: plex k8s:io.kubernetes.pod.namespace: plex toPorts: - ports: - port: '32400' protocol: TCP --- # CiliumNetworkPolicy gateway-ingress allow (R-NET-01/02): seerr-allow-gateway-ingress apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: seerr-allow-gateway-ingress namespace: seerr labels: app.kubernetes.io/name: seerr spec: endpointSelector: matchLabels: app.kubernetes.io/name: seerr ingress: - fromEntities: - ingress toPorts: - ports: - port: '5055' protocol: TCP --- # CiliumNetworkPolicy world egress allow (egress class governs the path; R-NET-05): seerr-allow-internet-egress apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: seerr-allow-internet-egress namespace: seerr labels: app.kubernetes.io/name: seerr spec: endpointSelector: matchLabels: app.kubernetes.io/name: seerr egress: - toEntities: - world --- # HTTPRoute seerr-5055 (R-TLS/R-DNS) apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: seerr-5055 namespace: seerr labels: app.kubernetes.io/name: seerr spec: parentRefs: - name: shared namespace: gateway sectionName: https hostnames: - seerr.${BASE_DOMAIN} rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: seerr port: 5055 --- # PrometheusRule SLI alerts (R-OBS-01) apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: seerr-slis namespace: seerr labels: release: kube-prometheus-stack app.kubernetes.io/name: seerr spec: groups: - name: seerr.slis rules: - alert: seerr-down expr: kube_deployment_status_replicas_available{namespace="seerr", deployment="seerr"} == 0 or absent(kube_deployment_status_replicas_available{namespace="seerr", deployment="seerr"}) for: 5m labels: severity: critical service: seerr annotations: summary: seerr is down description: 'seerr: its Deployment has no available/ready replica for 5m, or the signal is gone entirely (SLI: up, via kube_deployment_status_replicas_available).'