diff --git a/kubernetes/apps/network/external-dns/cloudflare/externalsecret.yaml b/.archive/kubernetes/external-dns/cloudflare/externalsecret.yaml similarity index 100% rename from kubernetes/apps/network/external-dns/cloudflare/externalsecret.yaml rename to .archive/kubernetes/external-dns/cloudflare/externalsecret.yaml diff --git a/kubernetes/apps/network/external-dns/cloudflare/helmrelease.yaml b/.archive/kubernetes/external-dns/cloudflare/helmrelease.yaml similarity index 100% rename from kubernetes/apps/network/external-dns/cloudflare/helmrelease.yaml rename to .archive/kubernetes/external-dns/cloudflare/helmrelease.yaml diff --git a/kubernetes/apps/network/external-dns/cloudflare/kustomization.yaml b/.archive/kubernetes/external-dns/cloudflare/kustomization.yaml similarity index 100% rename from kubernetes/apps/network/external-dns/cloudflare/kustomization.yaml rename to .archive/kubernetes/external-dns/cloudflare/kustomization.yaml diff --git a/kubernetes/apps/network/external-dns/ks.yaml b/.archive/kubernetes/external-dns/ks.yaml similarity index 100% rename from kubernetes/apps/network/external-dns/ks.yaml rename to .archive/kubernetes/external-dns/ks.yaml diff --git a/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/httproute.yaml b/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/httproute.yaml new file mode 100644 index 000000000..b510696f5 --- /dev/null +++ b/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/httproute.yaml @@ -0,0 +1,27 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: pgadmin +spec: + hostnames: + - pgadmin.${SECRET_EXTERNAL_DOMAIN} + parentRefs: + - group: pgadmin.networking.k8s.io + kind: Gateway + name: internal + namespace: network + sectionName: https + rules: + - backendRefs: + - group: '' + kind: Service + name: pgadmin + namespace: database + port: 5050 + weight: 1 + matches: + - path: + type: PathPrefix + value: / diff --git a/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/ingress.yaml b/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/ingress.yaml deleted file mode 100644 index adc8c6f63..000000000 --- a/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/ingress.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -# trunk-ignore(checkov/CKV_K8S_21) -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: pgadmin - annotations: - gethomepage.dev/enabled: "true" - gethomepage.dev/name: pgAdmin - gethomepage.dev/description: PostgreSQL management tool. - gethomepage.dev/group: Infrrastructure - gethomepage.dev/icon: pgadmin.png - gethomepage.dev/pod-selector: >- - app in ( - pgadmin - ) -spec: - ingressClassName: internal - tls: - - hosts: - - &host pgadmin.${SECRET_EXTERNAL_DOMAIN} - rules: - - host: *host - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: pgadmin - port: - number: 5050 diff --git a/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/kustomization.yaml b/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/kustomization.yaml index 8261e3285..8810e1741 100644 --- a/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/kustomization.yaml +++ b/kubernetes/apps/database/crunchy-postgres-operator/pgadmin/kustomization.yaml @@ -4,6 +4,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ./externalsecret.yaml - - ./ingress.yaml + - ./httproute.yaml - ./pgadmin.yaml - ./service.yaml diff --git a/kubernetes/apps/database/dragonfly/app/helmrelease.yaml b/kubernetes/apps/database/dragonfly/app/helmrelease.yaml index f14393bee..b520f2860 100644 --- a/kubernetes/apps/database/dragonfly/app/helmrelease.yaml +++ b/kubernetes/apps/database/dragonfly/app/helmrelease.yaml @@ -93,5 +93,4 @@ spec: interval: 1m scrapeTimeout: 10s serviceAccount: - create: true - name: *app + dragonfly-operator: {} diff --git a/kubernetes/apps/database/dragonfly/ks.yaml b/kubernetes/apps/database/dragonfly/ks.yaml index 0494c23a2..d3d5a8d01 100644 --- a/kubernetes/apps/database/dragonfly/ks.yaml +++ b/kubernetes/apps/database/dragonfly/ks.yaml @@ -4,9 +4,9 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: &app dragonfly - namespace: flux-system + namespace: &namespace database spec: - targetNamespace: database + targetNamespace: *namespace commonMetadata: labels: app.kubernetes.io/name: *app @@ -29,9 +29,9 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: &app dragonfly-cluster - namespace: flux-system + namespace: &namespace database spec: - targetNamespace: database + targetNamespace: *namespace commonMetadata: labels: app.kubernetes.io/name: *app diff --git a/kubernetes/apps/database/influx/ks.yaml b/kubernetes/apps/database/influx/ks.yaml index ec6ad6f7a..a160a05a2 100644 --- a/kubernetes/apps/database/influx/ks.yaml +++ b/kubernetes/apps/database/influx/ks.yaml @@ -4,9 +4,9 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: &app influx - namespace: flux-system + namespace: &namespace database spec: - targetNamespace: database + targetNamespace: *namespace commonMetadata: labels: app.kubernetes.io/name: *app diff --git a/kubernetes/apps/database/mosquitto/app/helmrelease.yaml b/kubernetes/apps/database/mosquitto/app/helmrelease.yaml index 43bede629..e48a33809 100644 --- a/kubernetes/apps/database/mosquitto/app/helmrelease.yaml +++ b/kubernetes/apps/database/mosquitto/app/helmrelease.yaml @@ -94,8 +94,6 @@ spec: controller: *app type: LoadBalancer externalTrafficPolicy: Local - annotations: - external-dns.alpha.kubernetes.io/hostname: "mqtt.${SECRET_EXTERNAL_DOMAIN}" ports: mqtt: port: 1883 diff --git a/kubernetes/apps/database/mosquitto/ks.yaml b/kubernetes/apps/database/mosquitto/ks.yaml index 4157c8158..95c3bf49f 100644 --- a/kubernetes/apps/database/mosquitto/ks.yaml +++ b/kubernetes/apps/database/mosquitto/ks.yaml @@ -9,8 +9,6 @@ spec: commonMetadata: labels: app.kubernetes.io/name: *app - components: - - ../../../../components/gatus/guarded interval: 1h path: ./kubernetes/apps/database/mosquitto/app postBuild: diff --git a/kubernetes/apps/default/authelia/app/externalsecret.yaml b/kubernetes/apps/default/authelia/app/externalsecret.yaml index fea42babc..0e65cd42c 100644 --- a/kubernetes/apps/default/authelia/app/externalsecret.yaml +++ b/kubernetes/apps/default/authelia/app/externalsecret.yaml @@ -32,7 +32,7 @@ spec: PAPERLESS_OAUTH_DIGEST: "{{ .OUTLINE_OAUTH_DIGEST }}" KOMGA_OAUTH_CLIENT_SECRET: "{{ .OUTLINE_OAUTH_CLIENT_SECRET }}" KOMGA_OAUTH_DIGEST: "{{ .OUTLINE_OAUTH_DIGEST }}" - SECRET_PUBLIC_DOMAIN: "{{ .SECRET_PUBLIC_DOMAIN }}" + SECRET_EXTERNAL_DOMAIN: "{{ .SECRET_EXTERNAL_DOMAIN }}" dataFrom: - extract: key: authelia diff --git a/kubernetes/apps/default/exercisediary/ks.yaml b/kubernetes/apps/default/exercisediary/ks.yaml index 7e5004886..a0a0617bf 100644 --- a/kubernetes/apps/default/exercisediary/ks.yaml +++ b/kubernetes/apps/default/exercisediary/ks.yaml @@ -23,6 +23,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" VOLSYNC_CAPACITY: 2Gi prune: true retryInterval: 2m diff --git a/kubernetes/apps/default/flood/ks.yaml b/kubernetes/apps/default/flood/ks.yaml index 177dad791..413d2d334 100644 --- a/kubernetes/apps/default/flood/ks.yaml +++ b/kubernetes/apps/default/flood/ks.yaml @@ -24,6 +24,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" VOLSYNC_CAPACITY: 2Gi prune: true retryInterval: 2m diff --git a/kubernetes/apps/default/freshrss/app/helmrelease.yaml b/kubernetes/apps/default/freshrss/app/helmrelease.yaml index 865eb49b0..248c9f8fa 100644 --- a/kubernetes/apps/default/freshrss/app/helmrelease.yaml +++ b/kubernetes/apps/default/freshrss/app/helmrelease.yaml @@ -20,9 +20,6 @@ spec: values: controllers: freshrss: - annotations: - reloader.stakater.com/auto: "true" - secret.reloader.stakater.com/reload: authelia-secret containers: app: image: @@ -31,20 +28,25 @@ spec: env: TZ: ${TIMEZONE} CRON_MIN: 18,48 - DOMAIN: "https://freshrss.${SECRET_EXTERNAL_DOMAIN}/" - envFrom: - - secretRef: - name: freshrss-secret + DOMAIN: "freshrss.${SECRET_EXTERNAL_DOMAIN}" + LISTEN: &port 8080 + probes: + liveness: + enabled: true + readiness: + enabled: true resources: requests: - cpu: 50m - memory: 256Mi + cpu: 12m + memory: 128M + limits: + memory: 512M service: app: controller: *app ports: http: - port: &port 80 + port: *port route: app: hostnames: ["{{ .Release.Name }}.${SECRET_EXTERNAL_DOMAIN}"] @@ -58,7 +60,13 @@ spec: port: *port persistence: config: - enabled: true existingClaim: *app - globalMounts: - - path: /var/www/FreshRSS/data + advancedMounts: + freshrss: + app: + - path: /var/www/FreshRSS/data + subPath: data + readOnly: false + - path: /var/www/FreshRSS/extensions + subPath: extensions + readOnly: false diff --git a/kubernetes/apps/default/freshrss/app/kustomization.yaml b/kubernetes/apps/default/freshrss/app/kustomization.yaml index d6adbe135..09bc749a9 100644 --- a/kubernetes/apps/default/freshrss/app/kustomization.yaml +++ b/kubernetes/apps/default/freshrss/app/kustomization.yaml @@ -3,5 +3,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - ./externalsecret.yaml - ./helmrelease.yaml diff --git a/kubernetes/apps/default/freshrss/ks.yaml b/kubernetes/apps/default/freshrss/ks.yaml index 9a2f0b503..13a9feb99 100644 --- a/kubernetes/apps/default/freshrss/ks.yaml +++ b/kubernetes/apps/default/freshrss/ks.yaml @@ -18,7 +18,6 @@ spec: substitute: APP: *app GATUS_PATH: /i/ - GATUS_STATUS: "401" VOLSYNC_CAPACITY: 2Gi prune: true retryInterval: 2m diff --git a/kubernetes/apps/default/frigate/ks.yaml b/kubernetes/apps/default/frigate/ks.yaml index 06ba3a861..4b12200d2 100644 --- a/kubernetes/apps/default/frigate/ks.yaml +++ b/kubernetes/apps/default/frigate/ks.yaml @@ -23,6 +23,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" VOLSYNC_CAPACITY: 5Gi prune: true retryInterval: 2m diff --git a/kubernetes/apps/default/jobs-rbac.yaml b/kubernetes/apps/default/jobs-rbac.yaml deleted file mode 100644 index 876f25b3f..000000000 --- a/kubernetes/apps/default/jobs-rbac.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: jobs - namespace: default ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: jobs-edit - namespace: default -subjects: - - kind: ServiceAccount - name: jobs -roleRef: - kind: ClusterRole - name: edit - apiGroup: rbac.authorization.k8s.io diff --git a/kubernetes/apps/default/kustomization.yaml b/kubernetes/apps/default/kustomization.yaml index 23fb6ef69..81ecc35f0 100644 --- a/kubernetes/apps/default/kustomization.yaml +++ b/kubernetes/apps/default/kustomization.yaml @@ -51,5 +51,3 @@ resources: - ./vikunja/ks.yaml - ./webhook/ks.yaml - ./zigbee2mqtt/ks.yaml - # Default resources - - jobs-rbac.yaml diff --git a/kubernetes/apps/default/libmedium/ks.yaml b/kubernetes/apps/default/libmedium/ks.yaml index fb14d279e..515f07303 100644 --- a/kubernetes/apps/default/libmedium/ks.yaml +++ b/kubernetes/apps/default/libmedium/ks.yaml @@ -20,6 +20,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" VOLSYNC_CAPACITY: 2Gi prune: true retryInterval: 2m diff --git a/kubernetes/apps/default/lychee/app/kustomization.yaml b/kubernetes/apps/default/lychee/app/kustomization.yaml index 8bdcc99a0..d6adbe135 100644 --- a/kubernetes/apps/default/lychee/app/kustomization.yaml +++ b/kubernetes/apps/default/lychee/app/kustomization.yaml @@ -5,4 +5,3 @@ kind: Kustomization resources: - ./externalsecret.yaml - ./helmrelease.yaml - - ./sync diff --git a/kubernetes/apps/default/lychee/ks.yaml b/kubernetes/apps/default/lychee/ks.yaml index 124b13864..54ab8fb89 100644 --- a/kubernetes/apps/default/lychee/ks.yaml +++ b/kubernetes/apps/default/lychee/ks.yaml @@ -39,3 +39,28 @@ spec: targetNamespace: *namespace timeout: 5m wait: false +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app lychee-sync + namespace: &namespace default +spec: + commonMetadata: + labels: + app.kubernetes.io/name: *app + interval: 1h + path: ./kubernetes/apps/default/lychee/sync + postBuild: + substitute: + APP: *app + prune: true + retryInterval: 5m + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: *namespace + timeout: 15m + wait: false diff --git a/kubernetes/apps/default/lychee/app/sync/helmrelease.yaml b/kubernetes/apps/default/lychee/sync/helmrelease.yaml similarity index 80% rename from kubernetes/apps/default/lychee/app/sync/helmrelease.yaml rename to kubernetes/apps/default/lychee/sync/helmrelease.yaml index 46e4ebe32..2a4d2af7e 100644 --- a/kubernetes/apps/default/lychee/app/sync/helmrelease.yaml +++ b/kubernetes/apps/default/lychee/sync/helmrelease.yaml @@ -51,5 +51,19 @@ spec: controller: *app enabled: false serviceAccount: - create: false - name: jobs + lychee-sync: {} + rbac: + roles: + lychee-sync: + type: ClusterRole + rules: + - apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] + bindings: + gatus: + type: ClusterRoleBinding + roleRef: + identifier: lychee-sync + subjects: + - identifier: lychee-sync diff --git a/kubernetes/apps/default/lychee/app/sync/kustomization.yaml b/kubernetes/apps/default/lychee/sync/kustomization.yaml similarity index 100% rename from kubernetes/apps/default/lychee/app/sync/kustomization.yaml rename to kubernetes/apps/default/lychee/sync/kustomization.yaml diff --git a/kubernetes/apps/default/qbittorrent/app/helmrelease.yaml b/kubernetes/apps/default/qbittorrent/app/helmrelease.yaml index c283e3cb6..3f0ae14f9 100644 --- a/kubernetes/apps/default/qbittorrent/app/helmrelease.yaml +++ b/kubernetes/apps/default/qbittorrent/app/helmrelease.yaml @@ -68,7 +68,7 @@ spec: sectionName: https rules: - backendRefs: - - name: *app + - name: qbittorrent-app port: *port persistence: config: diff --git a/kubernetes/apps/default/qbittorrent/app/kustomization.yaml b/kubernetes/apps/default/qbittorrent/app/kustomization.yaml index d275ad833..09bc749a9 100644 --- a/kubernetes/apps/default/qbittorrent/app/kustomization.yaml +++ b/kubernetes/apps/default/qbittorrent/app/kustomization.yaml @@ -4,4 +4,3 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ./helmrelease.yaml - - ./upgrade-p2pblocklist diff --git a/kubernetes/apps/default/qbittorrent/ks.yaml b/kubernetes/apps/default/qbittorrent/ks.yaml index e6905cf1f..a75e5bf0b 100644 --- a/kubernetes/apps/default/qbittorrent/ks.yaml +++ b/kubernetes/apps/default/qbittorrent/ks.yaml @@ -32,3 +32,28 @@ spec: targetNamespace: *namespace timeout: 5m wait: false +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app qbittorrent-upgrade-p2pblocklist + namespace: &namespace default +spec: + commonMetadata: + labels: + app.kubernetes.io/name: *app + interval: 1h + path: ./kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist + postBuild: + substitute: + APP: *app + prune: true + retryInterval: 5m + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: *namespace + timeout: 15m + wait: false diff --git a/kubernetes/apps/default/qbittorrent/app/upgrade-p2pblocklist/helmrelease.yaml b/kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist/helmrelease.yaml similarity index 73% rename from kubernetes/apps/default/qbittorrent/app/upgrade-p2pblocklist/helmrelease.yaml rename to kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist/helmrelease.yaml index 2b50083a8..b54844cf8 100644 --- a/kubernetes/apps/default/qbittorrent/app/upgrade-p2pblocklist/helmrelease.yaml +++ b/kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist/helmrelease.yaml @@ -54,5 +54,22 @@ spec: controller: *app enabled: false serviceAccount: - create: false - name: jobs + qbittorrent-upgrade-p2pblocklist: {} + rbac: + roles: + qbittorrent-upgrade-p2pblocklist: + type: ClusterRole + rules: + - apiGroups: [""] + resources: ["pods", "pods/log", "pods/exec", "pods/ephemeralcontainers"] + verbs: ["get", "list", "create", "update", "patch"] + - apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "list", "patch", "update"] + bindings: + gatus: + type: ClusterRoleBinding + roleRef: + identifier: qbittorrent-upgrade-p2pblocklist + subjects: + - identifier: qbittorrent-upgrade-p2pblocklist diff --git a/kubernetes/apps/default/qbittorrent/app/upgrade-p2pblocklist/kustomization.yaml b/kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist/kustomization.yaml similarity index 100% rename from kubernetes/apps/default/qbittorrent/app/upgrade-p2pblocklist/kustomization.yaml rename to kubernetes/apps/default/qbittorrent/upgrade-p2pblocklist/kustomization.yaml diff --git a/kubernetes/apps/default/redlib/ks.yaml b/kubernetes/apps/default/redlib/ks.yaml index 0ac4beabf..742646407 100644 --- a/kubernetes/apps/default/redlib/ks.yaml +++ b/kubernetes/apps/default/redlib/ks.yaml @@ -17,6 +17,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" prune: true retryInterval: 2m sourceRef: diff --git a/kubernetes/apps/default/sharry/app/helmrelease.yaml b/kubernetes/apps/default/sharry/app/helmrelease.yaml index 86a0819d5..58426dae5 100644 --- a/kubernetes/apps/default/sharry/app/helmrelease.yaml +++ b/kubernetes/apps/default/sharry/app/helmrelease.yaml @@ -38,6 +38,14 @@ spec: memory: 250Mi limits: memory: 1Gi + defaultPodOptions: + securityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: { type: RuntimeDefault } service: app: controller: *app diff --git a/kubernetes/apps/default/tandoor/app/config/nginx-config b/kubernetes/apps/default/tandoor/app/config/nginx-config index c783f8e7d..16417ac39 100644 --- a/kubernetes/apps/default/tandoor/app/config/nginx-config +++ b/kubernetes/apps/default/tandoor/app/config/nginx-config @@ -3,18 +3,30 @@ events { worker_connections 1024; } http { - include /etc/nginx/mime.types; + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include mime.types; server { - listen 8080; + listen 8080 default_server; + listen [::]:8080 default_server; server_name _; client_max_body_size 128M; - # serve media files - location /media/ { - alias /media/; - } # serve static files location /static/ { alias /static/; } + # serve media files + location /media/ { + alias /media//; + } + # pass requests for dynamic content to gunicorn + location / { + proxy_set_header Host $host; + proxy_pass http://localhost:8888; + } } } diff --git a/kubernetes/apps/default/tandoor/app/helmrelease.yaml b/kubernetes/apps/default/tandoor/app/helmrelease.yaml index 151fd4e5d..e6a549471 100644 --- a/kubernetes/apps/default/tandoor/app/helmrelease.yaml +++ b/kubernetes/apps/default/tandoor/app/helmrelease.yaml @@ -46,7 +46,6 @@ spec: source /opt/recipes/venv/bin/activate echo "Updating database" python3 /opt/recipes/manage.py migrate - python3 /opt/recipes/manage.py collectstatic_js_reverse python3 /opt/recipes/manage.py collectstatic --noinput containers: app: @@ -59,7 +58,7 @@ spec: ALLOWED_HOSTS: "*" GUNICORN_MEDIA: "0" TZ: ${TIMEZONE} - TANDOOR_PORT: &port 8888 + TANDOOR_PORT: &tandoorPort 8888 FRACTION_PREF_DEFAULT: "0" COMMENT_PREF_DEFAULT: "1" SHOPPING_MIN_AUTOSYNC_INTERVAL: "5" @@ -74,6 +73,28 @@ spec: - --log-level - INFO - recipes.wsgi + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /accounts/login/ + port: *tandoorPort + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + startup: + enabled: true + custom: true + spec: + httpGet: + path: /accounts/login/ + port: *tandoorPort + failureThreshold: 30 + periodSeconds: 10 resources: requests: cpu: 100m @@ -89,41 +110,21 @@ spec: controller: *app ports: http: - port: *port + port: *tandoorPort nginx: - port: &port2 8080 - ingress: + port: &nginxPort 8080 + route: app: - enabled: true - className: internal - annotations: - gethomepage.dev/enabled: "true" - gethomepage.dev/name: Tandoor - gethomepage.dev/description: Managing recipes, planned meals, shopping lists. - gethomepage.dev/group: Applications - gethomepage.dev/icon: tandoor.png - gethomepage.dev/pod-selector: >- - app in ( - tandoor - ) - hosts: - - host: &host "{{ .Release.Name }}.${SECRET_EXTERNAL_DOMAIN}" - paths: - - path: / - service: - identifier: app - port: http - - path: /media - service: - identifier: app - port: *port2 - - path: /static - service: - identifier: app - port: *port2 - tls: - - hosts: - - *host + hostnames: + - "{{ .Release.Name }}.${SECRET_EXTERNAL_DOMAIN}" + parentRefs: + - name: internal + namespace: network + sectionName: https + rules: + - backendRefs: + - name: *app + port: *nginxPort persistence: config: existingClaim: *app diff --git a/kubernetes/apps/default/tdarr/app/helmrelease.yaml b/kubernetes/apps/default/tdarr/app/helmrelease.yaml index d0a9ca712..6de972a28 100644 --- a/kubernetes/apps/default/tdarr/app/helmrelease.yaml +++ b/kubernetes/apps/default/tdarr/app/helmrelease.yaml @@ -40,7 +40,7 @@ spec: controller: *app ports: http: - port: 8265 + port: &port 8265 server: controller: *app type: LoadBalancer @@ -50,7 +50,7 @@ spec: server: enabled: true protocol: TCP - port: &port 8266 + port: 8266 route: app: hostnames: ["{{ .Release.Name }}.${SECRET_EXTERNAL_DOMAIN}"] diff --git a/kubernetes/apps/default/tdarr/ks.yaml b/kubernetes/apps/default/tdarr/ks.yaml index a1fe6de93..9d778c47b 100644 --- a/kubernetes/apps/default/tdarr/ks.yaml +++ b/kubernetes/apps/default/tdarr/ks.yaml @@ -24,6 +24,7 @@ spec: postBuild: substitute: APP: *app + GATUS_STATUS: "401" VOLSYNC_CACHE_CAPACITY: 20Gi VOLSYNC_CAPACITY: 50Gi prune: true diff --git a/kubernetes/apps/default/unifi/app/backendtlspolicy.yaml b/kubernetes/apps/default/unifi/app/backendtlspolicy.yaml new file mode 100644 index 000000000..204ab9122 --- /dev/null +++ b/kubernetes/apps/default/unifi/app/backendtlspolicy.yaml @@ -0,0 +1,15 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/backendtlspolicy_v1alpha3.json +apiVersion: gateway.networking.k8s.io/v1alpha3 +kind: BackendTLSPolicy +metadata: + name: unifi-backend-tls +spec: + targetRefs: + - group: '' + kind: Service + name: unifi + sectionName: https + validation: + wellKnownCACertificates: System + hostname: unifi.${SECRET_EXTERNAL_DOMAIN} diff --git a/kubernetes/apps/default/unifi/app/certificate.yaml b/kubernetes/apps/default/unifi/app/certificate.yaml new file mode 100644 index 000000000..04a39ae69 --- /dev/null +++ b/kubernetes/apps/default/unifi/app/certificate.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: '${SECRET_EXTERNAL_DOMAIN/./-}-unifi' +spec: + secretName: '${SECRET_EXTERNAL_DOMAIN/./-}-unifi' + issuerRef: + name: letsencrypt-production + kind: ClusterIssuer + commonName: 'unifi.${SECRET_EXTERNAL_DOMAIN}' + dnsNames: + - 'unifi.${SECRET_EXTERNAL_DOMAIN}' + keystores: + jks: + create: true + alias: unifi + password: aircontrolenterprise diff --git a/kubernetes/apps/default/unifi/app/helmrelease.yaml b/kubernetes/apps/default/unifi/app/helmrelease.yaml index 699fffb54..3376a48f7 100644 --- a/kubernetes/apps/default/unifi/app/helmrelease.yaml +++ b/kubernetes/apps/default/unifi/app/helmrelease.yaml @@ -46,7 +46,7 @@ spec: externalTrafficPolicy: Local loadBalancerIP: 192.168.169.103 ports: - http: + https: port: &port 8443 protocol: HTTPS controller: @@ -88,9 +88,27 @@ spec: - backendRefs: - name: *app port: *port + timeouts: + request: 0s # websocket, never time out + backendRequest: 0s # websocket, never time out persistence: config: enabled: true existingClaim: *app globalMounts: - path: /unifi + cert: + type: secret + name: '${SECRET_EXTERNAL_DOMAIN/./-}-unifi' + advancedMounts: + unifi: + app: + - path: /unifi/cert/cert.pem + subPath: tls.crt + readOnly: true + - path: /unifi/cert/privkey.pem + subPath: tls.key + readOnly: true + - path: /unifi/data/keystore + subPath: keystore.jks + readOnly: false diff --git a/kubernetes/apps/default/unifi/app/kustomization.yaml b/kubernetes/apps/default/unifi/app/kustomization.yaml index 09bc749a9..57cea416b 100644 --- a/kubernetes/apps/default/unifi/app/kustomization.yaml +++ b/kubernetes/apps/default/unifi/app/kustomization.yaml @@ -3,4 +3,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: + - ./backendtlspolicy.yaml + - ./certificate.yaml - ./helmrelease.yaml + - ./pushsecret.yaml diff --git a/kubernetes/apps/default/unifi/app/pushsecret.yaml b/kubernetes/apps/default/unifi/app/pushsecret.yaml new file mode 100644 index 000000000..66e2513f6 --- /dev/null +++ b/kubernetes/apps/default/unifi/app/pushsecret.yaml @@ -0,0 +1,35 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/pushsecret_v1alpha1.json +apiVersion: external-secrets.io/v1alpha1 +kind: PushSecret +metadata: + name: lets-encrypt-unifi +spec: + secretStoreRefs: + - name: onepassword-connect + kind: ClusterSecretStore + selector: + secret: + name: ${SECRET_EXTERNAL_DOMAIN/./-}-unifi + template: + engineVersion: v2 + data: + tls.crt: '{{ index . "tls.crt" | b64enc }}' + tls.key: '{{ index . "tls.key" | b64enc }}' + keystore.jks: '{{ index . "keystore.jks" | b64enc }}' + data: + - match: + secretKey: &key tls.crt + remoteRef: + remoteKey: lets-encrypt-unifi + property: *key + - match: + secretKey: &key tls.key + remoteRef: + remoteKey: lets-encrypt-unifi + property: *key + - match: + secretKey: &key keystore.jks + remoteRef: + remoteKey: lets-encrypt-unifi + property: *key diff --git a/kubernetes/apps/default/zigbee2mqtt/ks.yaml b/kubernetes/apps/default/zigbee2mqtt/ks.yaml index 1bb0c5792..603766137 100644 --- a/kubernetes/apps/default/zigbee2mqtt/ks.yaml +++ b/kubernetes/apps/default/zigbee2mqtt/ks.yaml @@ -28,6 +28,7 @@ spec: substitute: APP: *app VOLSYNC_CAPACITY: 2Gi + GATUS_STATUS: "401" GATUS_SUBDOMAIN: zigbee prune: true retryInterval: 2m diff --git a/kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml b/kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml index b02dacf25..c47b268b9 100644 --- a/kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml +++ b/kubernetes/apps/external-secrets/external-secrets/app/kustomization.yaml @@ -5,6 +5,7 @@ kind: Kustomization namespace: kube-system resources: - ./helmrelease.yaml + - ./prometheusrule.yaml configMapGenerator: - name: external-secrets-values files: diff --git a/kubernetes/apps/external-secrets/external-secrets/app/prometheusrule.yaml b/kubernetes/apps/external-secrets/external-secrets/app/prometheusrule.yaml new file mode 100644 index 000000000..fd0afb277 --- /dev/null +++ b/kubernetes/apps/external-secrets/external-secrets/app/prometheusrule.yaml @@ -0,0 +1,26 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/monitoring.coreos.com/prometheusrule_v1.json +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: external-secret-sync-alert + namespace: external-secrets +spec: + groups: + - name: external-secrets + rules: + - alert: ExternalSecretNotSynced + expr: | + ( + max_over_time( + external_secret_status_condition{condition="Ready", status="True"}[15m] + ) == 0 + ) or on(name, namespace) ( + external_secret_status_condition{condition="Ready", status="False"} == 1 + ) + for: 0m + labels: + severity: warning + annotations: + summary: ExternalSecret not synchronized + description: "ExternalSecret {{ $labels.namespace }}/{{ $labels.name }} has not synced for >5 min." diff --git a/kubernetes/apps/flux-system/flux-instance/app/httproute.yaml b/kubernetes/apps/flux-system/flux-instance/app/httproute.yaml new file mode 100644 index 000000000..509b77972 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-instance/app/httproute.yaml @@ -0,0 +1,21 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: github-webhook +spec: + hostnames: ["flux-webhook.${SECRET_EXTERNAL_DOMAIN}"] + parentRefs: + - name: external + namespace: network + sectionName: https + rules: + - backendRefs: + - name: webhook-receiver + namespace: flux-system + port: 80 + matches: + - path: + type: PathPrefix + value: /hook/ diff --git a/kubernetes/apps/flux-system/flux-instance/app/ingress.yaml b/kubernetes/apps/flux-system/flux-instance/app/ingress.yaml deleted file mode 100644 index c3432ee2c..000000000 --- a/kubernetes/apps/flux-system/flux-instance/app/ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: webhook-receiver -spec: - ingressClassName: external - rules: - - host: "flux-webhook.${SECRET_EXTERNAL_DOMAIN}" - http: - paths: - - path: /hook/ - pathType: Prefix - backend: - service: - name: webhook-receiver - port: - number: 80 - tls: - - hosts: - - "flux-webhook.${SECRET_EXTERNAL_DOMAIN}" diff --git a/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml b/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml index 9570b71f6..7c715baf4 100644 --- a/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml +++ b/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml @@ -5,7 +5,7 @@ kind: Kustomization resources: - ./externalsecret.yaml - ./helmrelease.yaml - - ./ingress.yaml + - ./httproute.yaml - ./prometheusrule.yaml - ./receiver.yaml configMapGenerator: diff --git a/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml b/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml index 18d59722a..ca90dbdfd 100644 --- a/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml +++ b/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml @@ -35,32 +35,6 @@ spec: name: cilium-values values: hubble: - enabled: true - metrics: - enabled: - - dns:query - - drop - - tcp - - flow - - port-distribution - - icmp - - http - serviceMonitor: - enabled: true - dashboards: - enabled: true - relay: - enabled: true - rollOutPods: true - prometheus: - serviceMonitor: - enabled: true - ui: - enabled: true - rollOutPods: true - ingress: - enabled: true - className: internal - hosts: ["hubble.${SECRET_EXTERNAL_DOMAIN}"] + enabled: false operator: tolerations: [] diff --git a/kubernetes/apps/default/freshrss/app/externalsecret.yaml b/kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml similarity index 50% rename from kubernetes/apps/default/freshrss/app/externalsecret.yaml rename to kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml index 92f315c6e..feec4854f 100644 --- a/kubernetes/apps/default/freshrss/app/externalsecret.yaml +++ b/kubernetes/apps/network/cloudflare-dns/app/externalsecret.yaml @@ -3,22 +3,16 @@ apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: - name: freshrss + name: cloudflare-dns spec: secretStoreRef: kind: ClusterSecretStore name: onepassword-connect target: - name: freshrss-secret + name: cloudflare-dns-secret template: - engineVersion: v2 data: - OIDC_CLIENT_SECRET: "{{ .FRESHRSS_OAUTH_CLIENT_SECRET }}" - FRESHRSS_OIDC_CLIENT_CRYPTO_KEY: "{{ .FRESHRSS_OIDC_CLIENT_CRYPTO_KEY}}" + CF_API_TOKEN: "{{ .CLOUDFLARE_TOKEN }}" dataFrom: - extract: - key: authelia - - extract: - key: cloudnative-pg - - extract: - key: freshrss + key: cloudflare diff --git a/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml b/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml new file mode 100644 index 000000000..9f005dd89 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/helmrelease.yaml @@ -0,0 +1,58 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/source.toolkit.fluxcd.io/ocirepository_v1.json +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cloudflare-dns +spec: + interval: 5m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 1.18.0 + url: oci://ghcr.io/home-operations/charts-mirror/external-dns +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: &app cloudflare-dns +spec: + interval: 1h + chartRef: + kind: OCIRepository + name: cloudflare-dns + install: + remediation: + retries: -1 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + values: + fullnameOverride: *app + provider: + name: cloudflare + env: + - name: &name CF_API_TOKEN + valueFrom: + secretKeyRef: + name: &secret cloudflare-dns-secret + key: *name + extraArgs: + - --cloudflare-dns-records-per-page=1000 + - --cloudflare-proxied + - --crd-source-apiversion=externaldns.k8s.io/v1alpha1 + - --crd-source-kind=DNSEndpoint + - --gateway-name=external + triggerLoopOnEvent: true + policy: sync + sources: ["crd", "gateway-httproute"] + txtOwnerId: default + txtPrefix: k8s. + domainFilters: ["${SECRET_EXTERNAL_DOMAIN}"] + serviceMonitor: + enabled: true + podAnnotations: + secret.reloader.stakater.com/reload: *secret diff --git a/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml b/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml new file mode 100644 index 000000000..d6adbe135 --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/kustomization.json +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./externalsecret.yaml + - ./helmrelease.yaml diff --git a/kubernetes/apps/network/cloudflare-dns/ks.yaml b/kubernetes/apps/network/cloudflare-dns/ks.yaml new file mode 100644 index 000000000..b2502384a --- /dev/null +++ b/kubernetes/apps/network/cloudflare-dns/ks.yaml @@ -0,0 +1,32 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/kustomize.toolkit.fluxcd.io/kustomization_v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: &app cloudflare-dns + namespace: &namespace network +spec: + commonMetadata: + labels: + app.kubernetes.io/name: *app + dependsOn: + - name: external-secrets-stores + namespace: external-secrets + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + name: *app + namespace: *namespace + - apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + name: dnsendpoints.externaldns.k8s.io + interval: 1h + path: ./kubernetes/apps/network/cloudflare-dns/app + prune: true + retryInterval: 2m + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: *namespace + timeout: 5m diff --git a/kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml similarity index 93% rename from kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml rename to kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml index 72088bfe7..91a3c4bd7 100644 --- a/kubernetes/apps/network/cloudflared/app/dnsendpoint.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/app/dnsendpoint.yaml @@ -3,7 +3,7 @@ apiVersion: externaldns.k8s.io/v1alpha1 kind: DNSEndpoint metadata: - name: cloudflared + name: cloudflare-tunnel spec: endpoints: - dnsName: "external.${SECRET_EXTERNAL_DOMAIN}" diff --git a/kubernetes/apps/network/cloudflared/app/externalsecret.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml similarity index 90% rename from kubernetes/apps/network/cloudflared/app/externalsecret.yaml rename to kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml index 487bbcddc..5261c9514 100644 --- a/kubernetes/apps/network/cloudflared/app/externalsecret.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/app/externalsecret.yaml @@ -3,13 +3,13 @@ apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: - name: cloudflared-tunnel + name: cloudflare-tunnel spec: secretStoreRef: kind: ClusterSecretStore name: onepassword-connect target: - name: cloudflared-tunnel-secret + name: cloudflare-tunnel-secret template: engineVersion: v2 data: diff --git a/kubernetes/apps/network/cloudflared/app/helmrelease.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml similarity index 91% rename from kubernetes/apps/network/cloudflared/app/helmrelease.yaml rename to kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml index 807a49bfc..d86f79cc5 100644 --- a/kubernetes/apps/network/cloudflared/app/helmrelease.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/app/helmrelease.yaml @@ -3,7 +3,7 @@ apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: - name: cloudflared + name: &app cloudflare-tunnel spec: interval: 1h chartRef: @@ -17,12 +17,9 @@ spec: remediation: strategy: rollback retries: 3 - dependsOn: - - name: nginx-external - namespace: network values: controllers: - cloudflared: + cloudflare-tunnel: replicas: 2 strategy: RollingUpdate annotations: @@ -75,13 +72,13 @@ spec: seccompProfile: { type: RuntimeDefault } service: app: - controller: cloudflared + controller: *app ports: http: port: *port serviceMonitor: app: - serviceName: cloudflared + serviceName: *app endpoints: - port: http scheme: http @@ -91,14 +88,14 @@ spec: persistence: config: type: configMap - name: cloudflared-configmap + name: cloudflare-tunnel-configmap globalMounts: - path: /etc/cloudflared/config/config.yaml subPath: config.yaml readOnly: true creds: type: secret - name: cloudflared-tunnel-secret + name: cloudflare-tunnel-secret globalMounts: - path: /etc/cloudflared/creds/credentials.json subPath: credentials.json diff --git a/kubernetes/apps/network/cloudflared/app/kustomization.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml similarity index 90% rename from kubernetes/apps/network/cloudflared/app/kustomization.yaml rename to kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml index 86de1bda9..a484521a9 100644 --- a/kubernetes/apps/network/cloudflared/app/kustomization.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/app/kustomization.yaml @@ -7,7 +7,7 @@ resources: - ./dnsendpoint.yaml - ./helmrelease.yaml configMapGenerator: - - name: cloudflared-configmap + - name: cloudflare-tunnel-configmap files: - config.yaml=./resources/config.yaml generatorOptions: diff --git a/kubernetes/apps/network/cloudflared/app/resources/config.yaml b/kubernetes/apps/network/cloudflare-tunnel/app/resources/config.yaml similarity index 56% rename from kubernetes/apps/network/cloudflared/app/resources/config.yaml rename to kubernetes/apps/network/cloudflare-tunnel/app/resources/config.yaml index 5aaa8586e..78b3c1263 100644 --- a/kubernetes/apps/network/cloudflared/app/resources/config.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/app/resources/config.yaml @@ -4,7 +4,7 @@ originRequest: ingress: - hostname: "${SECRET_EXTERNAL_DOMAIN}" - service: https://nginx-external-controller.network.svc.cluster.local:443 + service: &svc https://envoy-network-external-b1d9befd.network.svc.cluster.local:443 - hostname: "*.${SECRET_EXTERNAL_DOMAIN}" - service: https://nginx-external-controller.network.svc.cluster.local:443 + service: *svc - service: http_status:404 diff --git a/kubernetes/apps/network/cloudflared/ks.yaml b/kubernetes/apps/network/cloudflare-tunnel/ks.yaml similarity index 84% rename from kubernetes/apps/network/cloudflared/ks.yaml rename to kubernetes/apps/network/cloudflare-tunnel/ks.yaml index 0b7eb76e7..9bd1683f2 100644 --- a/kubernetes/apps/network/cloudflared/ks.yaml +++ b/kubernetes/apps/network/cloudflare-tunnel/ks.yaml @@ -3,18 +3,17 @@ apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: - name: &app cloudflared + name: &app cloudflare-tunnel namespace: &namespace network spec: commonMetadata: labels: app.kubernetes.io/name: *app dependsOn: - - name: external-dns-cloudflare - name: external-secrets-stores namespace: external-secrets interval: 1h - path: ./kubernetes/apps/network/cloudflared/app + path: ./kubernetes/apps/network/cloudflare-tunnel/app postBuild: substitute: APP: *app diff --git a/kubernetes/apps/network/envoy-gateway/config/certificate.yaml b/kubernetes/apps/network/envoy-gateway/config/certificate.yaml index 38d396322..2b5171423 100644 --- a/kubernetes/apps/network/envoy-gateway/config/certificate.yaml +++ b/kubernetes/apps/network/envoy-gateway/config/certificate.yaml @@ -1,4 +1,5 @@ --- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/cert-manager.io/certificate_v1.json apiVersion: cert-manager.io/v1 kind: Certificate metadata: diff --git a/kubernetes/apps/network/envoy-gateway/config/envoyproxy.yaml b/kubernetes/apps/network/envoy-gateway/config/envoyproxy.yaml index 1f8cbfa3f..69e76da0b 100644 --- a/kubernetes/apps/network/envoy-gateway/config/envoyproxy.yaml +++ b/kubernetes/apps/network/envoy-gateway/config/envoyproxy.yaml @@ -18,7 +18,7 @@ spec: type: Kubernetes kubernetes: envoyDeployment: - replicas: 1 + replicas: 2 container: resources: requests: diff --git a/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml index 96f2b5cec..ea07ea892 100644 --- a/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml +++ b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml @@ -11,7 +11,7 @@ spec: mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip operation: copy ref: - tag: 3.2.3 + tag: 3.2.6 url: oci://ghcr.io/k8s-gateway/charts/k8s-gateway --- # yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json diff --git a/kubernetes/apps/network/kustomization.yaml b/kubernetes/apps/network/kustomization.yaml index 1b1043214..373857e76 100644 --- a/kubernetes/apps/network/kustomization.yaml +++ b/kubernetes/apps/network/kustomization.yaml @@ -6,8 +6,8 @@ namespace: network components: - ../../components/common resources: - - ./cloudflared/ks.yaml + - ./cloudflare-dns/ks.yaml + - ./cloudflare-tunnel/ks.yaml - ./envoy-gateway/ks.yaml - - ./external-dns/ks.yaml - ./gateway-api-crds/ks.yaml - ./k8s-gateway/ks.yaml diff --git a/kubernetes/apps/observability/gatus/app/config/config.yaml b/kubernetes/apps/observability/gatus/app/config/config.yaml index 1a6567209..1c315c2fc 100644 --- a/kubernetes/apps/observability/gatus/app/config/config.yaml +++ b/kubernetes/apps/observability/gatus/app/config/config.yaml @@ -1,6 +1,10 @@ --- web: port: 8080 +storage: + type: sqlite + path: /config/sqlite.db + caching: true metrics: true ui: title: Status | Gatus @@ -30,7 +34,7 @@ connectivity: endpoints: - name: flux-webhook group: external - url: https://flux-webhook.${CUSTOM_SECRET_EXTERNAL_DOMAIN} + url: https://flux-webhook.${SECRET_EXTERNAL_DOMAIN} interval: 1m client: dns-resolver: tcp://1.1.1.1:53 diff --git a/kubernetes/apps/observability/gatus/app/externalsecret.yaml b/kubernetes/apps/observability/gatus/app/externalsecret.yaml index d5b518412..0a54c49ef 100644 --- a/kubernetes/apps/observability/gatus/app/externalsecret.yaml +++ b/kubernetes/apps/observability/gatus/app/externalsecret.yaml @@ -14,8 +14,11 @@ spec: data: CUSTOM_PUSHOVER_APP_TOKEN: '{{ .PUSHOVER_API_TOKEN }}' CUSTOM_PUSHOVER_USER_KEY: '{{ .PUSHOVER_USER_KEY }}' + SECRET_EXTERNAL_DOMAIN: '{{ .SECRET_EXTERNAL_DOMAIN }}' dataFrom: - extract: key: gatus + - extract: + key: generic - extract: key: pushover diff --git a/kubernetes/apps/observability/gatus/app/helmrelease.yaml b/kubernetes/apps/observability/gatus/app/helmrelease.yaml index 27e201a3e..64dc87f62 100644 --- a/kubernetes/apps/observability/gatus/app/helmrelease.yaml +++ b/kubernetes/apps/observability/gatus/app/helmrelease.yaml @@ -48,7 +48,10 @@ spec: TZ: ${TIMEZONE} GATUS_CONFIG_PATH: /config GATUS_DELAY_START_SECONDS: 5 - GATUS_WEB_PORT: &port 80 + GATUS_WEB_PORT: &port 8080 + envFrom: + - secretRef: + name: gatus-secret probes: liveness: &probes enabled: true @@ -76,20 +79,28 @@ spec: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: { type: RuntimeDefault } service: app: + controller: *app ports: http: port: *port + serviceAccount: + gatus: {} serviceMonitor: app: + serviceName: *app + enabled: true endpoints: - port: http route: app: - hostnames: ["{{ .Release.Name }}.${SECRET_EXTERNAL_DOMAIN}"] + hostnames: ["status.${SECRET_EXTERNAL_DOMAIN}"] parentRefs: - - name: internal + - name: external namespace: network sectionName: https rules: @@ -108,14 +119,12 @@ spec: gatus: type: ClusterRoleBinding roleRef: - identifier: gatus + identifier: *app subjects: - identifier: gatus - serviceAccount: - gatus: {} persistence: config: - type: emptyDir + existingClaim: *app config-file: type: configMap name: "{{ .Release.Name }}-configmap" diff --git a/kubernetes/apps/observability/gatus/app/kustomization.yaml b/kubernetes/apps/observability/gatus/app/kustomization.yaml index a4878692b..7e76d127c 100644 --- a/kubernetes/apps/observability/gatus/app/kustomization.yaml +++ b/kubernetes/apps/observability/gatus/app/kustomization.yaml @@ -5,8 +5,6 @@ kind: Kustomization resources: - ./externalsecret.yaml - ./helmrelease.yaml - - ./pvc.yaml - - ./rbac.yaml configMapGenerator: - name: gatus-configmap files: diff --git a/kubernetes/apps/observability/gatus/app/pvc.yaml b/kubernetes/apps/observability/gatus/app/pvc.yaml deleted file mode 100644 index 1d660c4b9..000000000 --- a/kubernetes/apps/observability/gatus/app/pvc.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: gatus -spec: - accessModes: [ReadWriteOnce] - resources: - requests: - storage: 2Gi - storageClassName: rook-ceph-block diff --git a/kubernetes/apps/observability/gatus/app/rbac.yaml b/kubernetes/apps/observability/gatus/app/rbac.yaml deleted file mode 100644 index 15b8f601e..000000000 --- a/kubernetes/apps/observability/gatus/app/rbac.yaml +++ /dev/null @@ -1,34 +0,0 @@ ---- -# trunk-ignore(checkov/CKV_K8S_21) -apiVersion: v1 -kind: ServiceAccount -metadata: - name: gatus - labels: - app.kubernetes.io/managed-by: Helm - annotations: - meta.helm.sh/release-name: gatus - meta.helm.sh/release-namespace: observability ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: gatus -rules: - # trunk-ignore(trivy/KSV041) - - apiGroups: [""] - resources: [configmaps, secrets] - verbs: [get, watch, list] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: gatus -roleRef: - kind: ClusterRole - name: gatus - apiGroup: rbac.authorization.k8s.io -subjects: - - kind: ServiceAccount - name: gatus - namespace: observability diff --git a/kubernetes/apps/observability/gatus/ks.yaml b/kubernetes/apps/observability/gatus/ks.yaml index a5733a572..976ca2587 100644 --- a/kubernetes/apps/observability/gatus/ks.yaml +++ b/kubernetes/apps/observability/gatus/ks.yaml @@ -9,6 +9,8 @@ spec: commonMetadata: labels: app.kubernetes.io/name: *app + components: + - ../../../../components/volsync dependsOn: - name: external-secrets-stores namespace: external-secrets @@ -17,6 +19,7 @@ spec: postBuild: substitute: APP: *app + VOLSYNC_CAPACITY: 2Gi prune: true retryInterval: 2m sourceRef: diff --git a/kubernetes/apps/observability/pushgateway/app/httproute.yaml b/kubernetes/apps/observability/pushgateway/app/httproute.yaml index 7238e72d5..9c0159269 100644 --- a/kubernetes/apps/observability/pushgateway/app/httproute.yaml +++ b/kubernetes/apps/observability/pushgateway/app/httproute.yaml @@ -3,7 +3,7 @@ apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: - name: https-redirect + name: pushgateway spec: hostnames: - pushgateway.${SECRET_EXTERNAL_DOMAIN} @@ -17,8 +17,8 @@ spec: - backendRefs: - group: '' kind: Service - name: pushgateway - namespace: default + name: pushgateway-prometheus-pushgateway + namespace: observability port: 9091 weight: 1 matches: diff --git a/kubernetes/apps/rook-ceph/rook-ceph/app/externalsecret.yaml b/kubernetes/apps/rook-ceph/rook-ceph/app/externalsecret.yaml new file mode 100644 index 000000000..9490938d4 --- /dev/null +++ b/kubernetes/apps/rook-ceph/rook-ceph/app/externalsecret.yaml @@ -0,0 +1,18 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1.json +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: rook-ceph-dashboard +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-connect + target: + name: rook-ceph-dashboard-password # rook-ceph expects this name + template: + data: + password: "{{ .password }}" + dataFrom: + - extract: + key: rook diff --git a/kubernetes/apps/rook-ceph/rook-ceph/app/helmrelease.yaml b/kubernetes/apps/rook-ceph/rook-ceph/app/helmrelease.yaml index 39b172d82..758ea107b 100644 --- a/kubernetes/apps/rook-ceph/rook-ceph/app/helmrelease.yaml +++ b/kubernetes/apps/rook-ceph/rook-ceph/app/helmrelease.yaml @@ -46,6 +46,9 @@ spec: crds: enabled: true pspEnable: false + enableDiscoveryDaemon: true + image: + repository: ghcr.io/rook/ceph monitoring: enabled: true resources: diff --git a/kubernetes/apps/rook-ceph/rook-ceph/app/kustomization.yaml b/kubernetes/apps/rook-ceph/rook-ceph/app/kustomization.yaml index 09bc749a9..d6adbe135 100644 --- a/kubernetes/apps/rook-ceph/rook-ceph/app/kustomization.yaml +++ b/kubernetes/apps/rook-ceph/rook-ceph/app/kustomization.yaml @@ -3,4 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: + - ./externalsecret.yaml - ./helmrelease.yaml diff --git a/kubernetes/apps/rook-ceph/rook-ceph/cluster/helmrelease.yaml b/kubernetes/apps/rook-ceph/rook-ceph/cluster/helmrelease.yaml index ca05f15bf..ef994a0c7 100644 --- a/kubernetes/apps/rook-ceph/rook-ceph/cluster/helmrelease.yaml +++ b/kubernetes/apps/rook-ceph/rook-ceph/cluster/helmrelease.yaml @@ -33,25 +33,6 @@ spec: monitoring: enabled: true createPrometheusRules: true - ingress: - dashboard: - ingressClassName: internal - annotations: - gethomepage.dev/enabled: "true" - gethomepage.dev/name: Rook - gethomepage.dev/description: Cloud-Native Storage for Kubernetes. - gethomepage.dev/group: Infrastructure - gethomepage.dev/icon: rook.png - gethomepage.dev/pod-selector: >- - app in ( - rook - ) - host: - name: "rook.${SECRET_EXTERNAL_DOMAIN}" - path: / - tls: - - hosts: - - "rook.${SECRET_EXTERNAL_DOMAIN}" configOverride: | [global] bdev_enable_discard = true @@ -63,6 +44,7 @@ spec: enabled: true urlPrefix: / ssl: false + prometheusEndpoint: http://prometheus-operated.observability.svc.cluster.local:9090 storage: useAllNodes: false useAllDevices: false diff --git a/kubernetes/apps/rook-ceph/rook-ceph/cluster/httproute.yaml b/kubernetes/apps/rook-ceph/rook-ceph/cluster/httproute.yaml new file mode 100644 index 000000000..866b4d91b --- /dev/null +++ b/kubernetes/apps/rook-ceph/rook-ceph/cluster/httproute.yaml @@ -0,0 +1,17 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/gateway.networking.k8s.io/httproute_v1.json +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: rook-ceph-dashboard +spec: + hostnames: ["rook.${SECRET_EXTERNAL_DOMAIN}"] + parentRefs: + - name: internal + namespace: network + sectionName: https + rules: + - backendRefs: + - name: rook-ceph-mgr-dashboard + namespace: rook-ceph + port: 7000 diff --git a/kubernetes/apps/rook-ceph/rook-ceph/cluster/kustomization.yaml b/kubernetes/apps/rook-ceph/rook-ceph/cluster/kustomization.yaml index 09bc749a9..d4b286802 100644 --- a/kubernetes/apps/rook-ceph/rook-ceph/cluster/kustomization.yaml +++ b/kubernetes/apps/rook-ceph/rook-ceph/cluster/kustomization.yaml @@ -4,3 +4,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ./helmrelease.yaml + - ./httproute.yaml diff --git a/kubernetes/components/common/repos/app-template/ocirepository.yaml b/kubernetes/components/common/repos/app-template/ocirepository.yaml index 492e7f22c..eea23c586 100644 --- a/kubernetes/components/common/repos/app-template/ocirepository.yaml +++ b/kubernetes/components/common/repos/app-template/ocirepository.yaml @@ -10,5 +10,5 @@ spec: mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip operation: copy ref: - tag: 3.7.3 - url: oci://ghcr.io/bjw-s/helm/app-template + tag: 4.2.0 + url: oci://ghcr.io/bjw-s-labs/helm/app-template diff --git a/kubernetes/components/common/vars/cluster-secrets.sops.yaml b/kubernetes/components/common/vars/cluster-secrets.sops.yaml index 6b2a4a1bf..496c5dd11 100644 --- a/kubernetes/components/common/vars/cluster-secrets.sops.yaml +++ b/kubernetes/components/common/vars/cluster-secrets.sops.yaml @@ -10,11 +10,9 @@ stringData: SECRET_DOMAIN: ENC[AES256_GCM,data:UtdBDs6+azVHO7Y=,iv:ZnWrBW+vW6HiMs1PbgY2LjcwUwuUh1HxYjqvOXvCrDk=,tag:r6uDIJhVoTIcizIfRW+lHw==,type:str] SECRET_EXTERNAL_DOMAIN: ENC[AES256_GCM,data:Brd9H7gizPxew+4=,iv:YaIxv9TFF0mAks9gJXwXA1N7b8k5mcSJ6hs9lpaUV/M=,tag:8xdRoWun3IUVywagpsrsBw==,type:str] SECRET_INTERNAL_DOMAIN: ENC[AES256_GCM,data:WLuQAi9JsUsD5Q==,iv:Zc+5/rQONxepZFVC/ia01aBdlVyG99thOeIipeAVS3E=,tag:FwwjDKoUMfZ/taFPRRThOQ==,type:str] - SECRET_CROWDSEC_NGINX_BOUNCER_API_KEY: ENC[AES256_GCM,data:ecukkFOK40WWIxJ48sXrxJUBaHx2BnzqxkIT+cXYZg4=,iv:y6AfslVPufBfrIL3GQqTw0cDAan64mB9J7RY9OzKQqw=,tag:+V4Rgz26wey2UtA32S0PJQ==,type:str] SECRET_KOMF_MAL_CLIENT_ID: ENC[AES256_GCM,data:HuKHFrICgCj6nbcbix8u7qGeggFmmKht7Elk9dINZtE=,iv:c3mqFdFkIO9dctZ3ooPh4ajOZaY0ZudEeNWbG+lryPI=,tag:jWG2+pgkAf/XUgJyUvdrNg==,type:str] - SECRET_KUBE_PROMETHEUS_STACK_ALERTMANAGER_PUSHOVER_USER_KEY: ENC[AES256_GCM,data:X1J9WLT26soYzlDb8+YtPotGw8p0lJKMuNkn69WX,iv:mW2cJOq5gfzSE+U24IuvPVL+dL2nZcTFpPAkG77Ohus=,tag:kxokidtuE5RAGJlj4Q4P2A==,type:str] + SECRET_KUBE_PROMETHEUS_STACK_ALERTMANAGER_PUSHOVER_USER_KEY: ENC[AES256_GCM,data:6r6jegE5tnW8l9flwQy48jI6biCNXMLonuHt94Zu,iv:iWej1fv28zXlVTHZ+khhF5FuN5RZY5EV/0Slz24no7U=,tag:KH65ZHwl+1Mf7ScuGiAhgw==,type:str] SECRET_KUBE_PROMETHEUS_STACK_ALERTMANAGER_PUSHOVER_TOKEN: ENC[AES256_GCM,data:Bwvuy/jHIRduy/r1A8dOs0OE8ewdjCgs8g/br1oW,iv:PdnPH9I509MT6UJkUG1zLAGn9aV4AVrROgAVCD4a3Y0=,tag:59kBGx9qx3jeauokyoolQQ==,type:str] - SECRET_KUBE_PROMETHEUS_STACK_GRAFANA_ADMIN_PASSWORD: ENC[AES256_GCM,data:L7LS6+tuwPCyb5HN4zg=,iv:JM2KTtDN/VrKicjp5qwqusWiJKHRZnfTtsZE2hkLq6Q=,tag:XGF3L5P6JxVBrlGuKosdZA==,type:str] type: Opaque sops: age: @@ -27,7 +25,7 @@ sops: WG82VkdBMlNnRzBySFQzMk41cEtXSlEKBqOmq9UpO61C85+pj0ibdT31y4pmFsbm pTi4N0vv81kcf4ilqBU5h1gudNCb42Q2iL0eGNR4e3JzH4iaNsvnEg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-04-15T20:57:26Z" - mac: ENC[AES256_GCM,data:/qQpLkJIhVBnkDVNsls1xfw1Iyy6ijyrmU9LQqhO+Qa6lQ4CKejX6wiLuPJNtQ+rTtmp3KUG4uCF3JvWNnyNOLGtSjM3X7bDS11NY2sfWkBebBQy/s59B7Jb30937lqFP39hP5GhvegN6kP5+iLIltgKKjH0cXXyf+FT/Q+6kOs=,iv:r6HfAGPr09e4xuaDQBE3zXt3n7k88dHZfQXKa2LMiYY=,tag:nxzFsjI9QhhsnTO7Oed8QQ==,type:str] + lastmodified: "2025-08-19T20:12:58Z" + mac: ENC[AES256_GCM,data:uVZFsWvrk0T1q446uNnVdNai7C7mTrZNXkPxwZdmLi1Do6nzCYccmnefz5Fukr9DzWCmofdlqEcDneugHxPbKiOKnqQ1Wbuf7smqRSeHaRycDgmFtYVBTnm2Bc7ePU2a7zcnbR5w6q1HXC+iyxP0aKAMI5Z7NvOJ/CZi3PIPUUY=,iv:ZJLOh9+SxX0WzvIue6/WxG1d2SesdTCBnBr0EaX53ls=,tag:0rL7B/J4b6PNEsKsmdT2NA==,type:str] encrypted_regex: ^(data|stringData)$ version: 3.10.2 diff --git a/kubernetes/components/gatus/external/config.yaml b/kubernetes/components/gatus/external/config.yaml index bd6cd766f..21f3b83de 100644 --- a/kubernetes/components/gatus/external/config.yaml +++ b/kubernetes/components/gatus/external/config.yaml @@ -4,7 +4,7 @@ endpoints: url: "https://${GATUS_SUBDOMAIN:-${APP}}.${SECRET_EXTERNAL_DOMAIN}${GATUS_PATH:-/}" interval: 1m client: - dns-resolver: tcp://192.168.8.1:53 + dns-resolver: tcp://1.1.1.1:53 conditions: - "[STATUS] == ${GATUS_STATUS:-200}" alerts: diff --git a/kubernetes/components/gatus/guarded/config.yaml b/kubernetes/components/gatus/guarded/config.yaml index f4f307a9e..7eb6bcf4b 100644 --- a/kubernetes/components/gatus/guarded/config.yaml +++ b/kubernetes/components/gatus/guarded/config.yaml @@ -3,6 +3,8 @@ endpoints: group: guarded url: "https://${GATUS_SUBDOMAIN:-${APP}}.${GATUS_DOMAIN:-${SECRET_EXTERNAL_DOMAIN}}${GATUS_PATH:-/}" interval: 1m + client: + dns-resolver: tcp://192.168.8.1:53 ui: hide-hostname: true hide-url: true