mirror of
https://github.com/rubenhensen/k8scd.git
synced 2026-11-15 14:29:09 +01:00
Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f894996e6 | ||
|
|
c380bfc0cf | ||
|
|
c3597ef0a6 | ||
|
|
baa8c70b55 | ||
|
|
1efa6c2b93 | ||
|
|
15a92294a6 | ||
|
|
144b9dda2b | ||
|
|
920e54b43c | ||
|
|
665147a691 | ||
|
|
1ba1d5f1a0 | ||
|
|
285a64f980 | ||
|
|
6cf41b0f14 | ||
|
|
5678adfa82 | ||
|
|
2e2d367f63 | ||
|
|
2a1394763d | ||
|
|
86bbf25145 | ||
|
|
92d5147994 | ||
|
|
9e88a92ff7 | ||
|
|
7b12ee2028 | ||
|
|
039b956764 | ||
|
|
a36fc6f348 | ||
|
|
66207de2dd | ||
|
|
a8ccbef274 | ||
|
|
d0ce5ddbec | ||
|
|
c384ae921f | ||
|
|
13b92fff54 | ||
|
|
3834f7a354 | ||
|
|
8110a235a9 | ||
|
|
fa33bf44ae | ||
|
|
d4e99d28c7 | ||
|
|
c8a81e805d | ||
|
|
6c727346f6 | ||
|
|
ed828b426f | ||
|
|
f6186d5a11 | ||
|
|
2ccaea24a8 | ||
|
|
a2abb66fea | ||
|
|
b721c80599 | ||
|
|
09026a5ff0 | ||
|
|
1fcfd3ad61 |
No files matched your search
@@ -18,7 +18,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
validate:
|
validate:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-26.04
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ spec:
|
|||||||
project: default
|
project: default
|
||||||
source:
|
source:
|
||||||
repoURL: https://community-charts.github.io/helm-charts
|
repoURL: https://community-charts.github.io/helm-charts
|
||||||
targetRevision: 1.8.9
|
targetRevision: 1.9.5
|
||||||
chart: actualbudget
|
chart: actualbudget
|
||||||
helm:
|
helm:
|
||||||
values: |
|
values: |
|
||||||
|
|||||||
@@ -55,3 +55,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -103,6 +103,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 70m
|
cpu: 70m
|
||||||
memory: 560Mi
|
memory: 560Mi
|
||||||
|
limits:
|
||||||
|
memory: 1536Mi
|
||||||
volumes:
|
volumes:
|
||||||
- name: patched-ca-bundle
|
- name: patched-ca-bundle
|
||||||
configMap:
|
configMap:
|
||||||
@@ -192,6 +194,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 336Mi
|
memory: 336Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
volumes:
|
volumes:
|
||||||
- name: patched-ca-bundle
|
- name: patched-ca-bundle
|
||||||
configMap:
|
configMap:
|
||||||
|
|||||||
@@ -38,16 +38,22 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 48Mi
|
memory: 48Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
cainjector:
|
cainjector:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 80Mi
|
memory: 80Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
webhook:
|
webhook:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
syncPolicy:
|
syncPolicy:
|
||||||
syncOptions:
|
syncOptions:
|
||||||
- CreateNamespace=true
|
- CreateNamespace=true
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: cloudnative-pg-folder
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://github.com/rubenhensen/k8scd.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: cloudnative-pg
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: cnpg-system
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
selfHeal: true
|
||||||
@@ -28,6 +28,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 48Mi
|
memory: 48Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
destination:
|
destination:
|
||||||
server: https://kubernetes.default.svc
|
server: https://kubernetes.default.svc
|
||||||
namespace: cnpg-system
|
namespace: cnpg-system
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: default-folder
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://github.com/rubenhensen/k8scd.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: default
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: default
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
selfHeal: true
|
||||||
@@ -12,7 +12,7 @@ spec:
|
|||||||
repoURL: docker.io/envoyproxy
|
repoURL: docker.io/envoyproxy
|
||||||
chart: gateway-helm
|
chart: gateway-helm
|
||||||
# v1.9 supports Kubernetes 1.33 to 1.36
|
# v1.9 supports Kubernetes 1.33 to 1.36
|
||||||
targetRevision: v1.9.2
|
targetRevision: 1.9.3
|
||||||
helm:
|
helm:
|
||||||
values: |
|
values: |
|
||||||
config:
|
config:
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: external-secrets-folder
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://github.com/rubenhensen/k8scd.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: external-secrets
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: external-secrets
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
selfHeal: true
|
||||||
@@ -24,16 +24,22 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 20m
|
cpu: 20m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
certController:
|
certController:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
webhook:
|
webhook:
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
destination:
|
destination:
|
||||||
server: https://kubernetes.default.svc
|
server: https://kubernetes.default.svc
|
||||||
namespace: external-secrets
|
namespace: external-secrets
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: plugin-barman-cloud
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
chart: plugin-barman-cloud
|
||||||
|
repoURL: https://cloudnative-pg.github.io/charts
|
||||||
|
targetRevision: 0.8.1
|
||||||
|
helm:
|
||||||
|
values: |
|
||||||
|
# CNPG's barman cloud plugin, which backs the PostgreSQL clusters
|
||||||
|
# up to Garage on the NAS (authentik/postgresql-backup.yaml,
|
||||||
|
# immich/postgresql-backup.yaml). It has to run in the operator's
|
||||||
|
# namespace; the chart gets its TLS certificates from cert-manager.
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: cnpg-system
|
||||||
|
syncPolicy:
|
||||||
|
syncOptions:
|
||||||
|
- ServerSideApply=true
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Requests from what the components used on 2026-10-25 (kubectl top every
|
# Requests from what the components used on 2026-10-25 (kubectl top every
|
||||||
# 5 minutes; highest value plus 10%). No limits until there are daytime
|
# 5 minutes; highest value plus 10%). Memory limits at about twice the
|
||||||
# numbers, see docs/roadmap.md.
|
# highest value seen then or on 2026-10-27, rounded up; no CPU limits.
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
@@ -14,6 +14,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 150m
|
cpu: 150m
|
||||||
memory: 704Mi
|
memory: 704Mi
|
||||||
|
limits:
|
||||||
|
memory: 2560Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -28,6 +30,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 128Mi
|
memory: 128Mi
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -42,6 +46,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -56,6 +62,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 20m
|
cpu: 20m
|
||||||
memory: 96Mi
|
memory: 96Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -70,6 +78,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 48Mi
|
memory: 48Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -84,6 +94,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 48Mi
|
memory: 48Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -98,3 +110,5 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
@@ -108,7 +108,8 @@ spec:
|
|||||||
---
|
---
|
||||||
# The CNPG operator checks each instance on its status port and connects to
|
# The CNPG operator checks each instance on its status port and connects to
|
||||||
# PostgreSQL; the instance manager inside each pod watches its Cluster
|
# PostgreSQL; the instance manager inside each pod watches its Cluster
|
||||||
# through the API server.
|
# through the API server. The barman cloud sidecar sends the WAL and the
|
||||||
|
# base backups to Garage on the NAS (postgresql-backup.yaml).
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: NetworkPolicy
|
kind: NetworkPolicy
|
||||||
metadata:
|
metadata:
|
||||||
@@ -135,3 +136,34 @@ spec:
|
|||||||
cidr: 192.168.1.204/32
|
cidr: 192.168.1.204/32
|
||||||
ports:
|
ports:
|
||||||
- port: 16443
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.99/32
|
||||||
|
ports:
|
||||||
|
- port: 3900
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# Backups of authentik's database by CNPG itself, through the barman cloud
|
||||||
|
# plugin (apps/templates/plugin-barman-cloud-helm.yaml): a base backup every
|
||||||
|
# night, and every WAL segment as soon as it is full or 5 minutes old
|
||||||
|
# (archive_timeout). Both go to the bucket cnpg-authentik in Garage on the
|
||||||
|
# NAS (nas/garage), so the database can be restored to any moment of the
|
||||||
|
# last 30 days. Velero copies the data directory while PostgreSQL runs,
|
||||||
|
# which is not a consistent copy.
|
||||||
|
# The key is Garage's cnpg-authentik, in Vault as kv/cnpg-authentik-s3; it
|
||||||
|
# can only reach this bucket.
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: authentik-postgres-s3
|
||||||
|
spec:
|
||||||
|
secretStoreRef:
|
||||||
|
name: vault-backend
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
refreshInterval: 15m
|
||||||
|
target:
|
||||||
|
name: authentik-postgres-s3
|
||||||
|
creationPolicy: Owner
|
||||||
|
template:
|
||||||
|
engineVersion: v2
|
||||||
|
data:
|
||||||
|
ACCESS_KEY_ID: "{{ .access_key_id }}"
|
||||||
|
ACCESS_SECRET_KEY: "{{ .secret_access_key }}"
|
||||||
|
# Garage rejects requests signed for another region
|
||||||
|
REGION: garage
|
||||||
|
data:
|
||||||
|
- secretKey: access_key_id
|
||||||
|
remoteRef:
|
||||||
|
key: kv/cnpg-authentik-s3
|
||||||
|
property: access_key_id
|
||||||
|
- secretKey: secret_access_key
|
||||||
|
remoteRef:
|
||||||
|
key: kv/cnpg-authentik-s3
|
||||||
|
property: secret_access_key
|
||||||
|
---
|
||||||
|
apiVersion: barmancloud.cnpg.io/v1
|
||||||
|
kind: ObjectStore
|
||||||
|
metadata:
|
||||||
|
name: authentik-postgres
|
||||||
|
annotations:
|
||||||
|
# The CRD comes with the plugin's own app
|
||||||
|
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
|
||||||
|
spec:
|
||||||
|
retentionPolicy: 30d
|
||||||
|
configuration:
|
||||||
|
destinationPath: s3://cnpg-authentik/
|
||||||
|
endpointURL: http://192.168.1.99:3900
|
||||||
|
s3Credentials:
|
||||||
|
accessKeyId:
|
||||||
|
name: authentik-postgres-s3
|
||||||
|
key: ACCESS_KEY_ID
|
||||||
|
secretAccessKey:
|
||||||
|
name: authentik-postgres-s3
|
||||||
|
key: ACCESS_SECRET_KEY
|
||||||
|
region:
|
||||||
|
name: authentik-postgres-s3
|
||||||
|
key: REGION
|
||||||
|
wal:
|
||||||
|
compression: gzip
|
||||||
|
data:
|
||||||
|
compression: gzip
|
||||||
|
instanceSidecarConfiguration:
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
|
env:
|
||||||
|
# Newer boto3 adds checksums that S3-compatible stores can reject;
|
||||||
|
# the plugin's docs suggest sending them only when required.
|
||||||
|
- name: AWS_REQUEST_CHECKSUM_CALCULATION
|
||||||
|
value: when_required
|
||||||
|
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
|
||||||
|
value: when_required
|
||||||
|
---
|
||||||
|
apiVersion: postgresql.cnpg.io/v1
|
||||||
|
kind: ScheduledBackup
|
||||||
|
metadata:
|
||||||
|
name: authentik-postgres-daily
|
||||||
|
spec:
|
||||||
|
cluster:
|
||||||
|
name: authentik-postgres
|
||||||
|
# 03:00 UTC, after Longhorn's and Velero's backups; immediate: one right
|
||||||
|
# away, so WAL archiving has a base backup to start from.
|
||||||
|
schedule: "0 0 3 * * *"
|
||||||
|
immediate: true
|
||||||
|
backupOwnerReference: self
|
||||||
|
method: plugin
|
||||||
|
pluginConfiguration:
|
||||||
|
name: barman-cloud.cloudnative-pg.io
|
||||||
@@ -6,12 +6,20 @@ spec:
|
|||||||
instances: 1
|
instances: 1
|
||||||
# Pinned so a new operator default (PostgreSQL 18 since CNPG 1.26.3) can't
|
# Pinned so a new operator default (PostgreSQL 18 since CNPG 1.26.3) can't
|
||||||
# start an in-place major upgrade. CNPG filled this in at creation.
|
# start an in-place major upgrade. CNPG filled this in at creation.
|
||||||
imageName: ghcr.io/cloudnative-pg/postgresql:17.4
|
imageName: ghcr.io/cloudnative-pg/postgresql:17.11
|
||||||
primaryUpdateStrategy: unsupervised
|
primaryUpdateStrategy: unsupervised
|
||||||
|
# WAL archiving and base backups to Garage, see postgresql-backup.yaml
|
||||||
|
plugins:
|
||||||
|
- name: barman-cloud.cloudnative-pg.io
|
||||||
|
isWALArchiver: true
|
||||||
|
parameters:
|
||||||
|
barmanObjectName: authentik-postgres
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
memory: 256Mi
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
bootstrap:
|
bootstrap:
|
||||||
initdb:
|
initdb:
|
||||||
database: authentik
|
database: authentik
|
||||||
|
|||||||
@@ -54,3 +54,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# cert-manager's three pods reach each other, DNS and the API server (the
|
||||||
|
# node, port 16443), and take connections only from each other and the
|
||||||
|
# node: the API server calls the webhook from there and the kubelet probes
|
||||||
|
# come from there too (10.1.7.64 is the node's Calico VXLAN address,
|
||||||
|
# projectcalico.org/IPv4VXLANTunnelAddr). Nothing scrapes the metrics on
|
||||||
|
# 9402. The HTTP-01 solver pods run in each Certificate's own namespace
|
||||||
|
# (acme-http01-solver in <namespace>/networkpolicy.yaml), not here.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
---
|
||||||
|
# The controller talks to Let's Encrypt (443), and before it lets Let's
|
||||||
|
# Encrypt check a challenge it fetches http://<host>/.well-known/... itself
|
||||||
|
# (80). Every certificate's host has a public address, node001's or the
|
||||||
|
# home router's (checked 2026-10-26), so the LAN stays out.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: controller-to-internet
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: cert-manager
|
||||||
|
app.kubernetes.io/component: controller
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
except:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 100.64.0.0/10
|
||||||
|
- 169.254.0.0/16
|
||||||
|
- 172.16.0.0/12
|
||||||
|
- 192.168.0.0/16
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
- port: 443
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# The CloudNativePG operator reaches DNS, the API server (the node, port
|
||||||
|
# 16443) and the PostgreSQL instances it runs in other namespaces: the
|
||||||
|
# instance manager's status port (8000) and PostgreSQL (5432), which the
|
||||||
|
# instances' own policies let in (postgres-cnpg in authentik and immich).
|
||||||
|
# Besides its own namespace it takes connections only from the node: the
|
||||||
|
# API server calls its webhook (9443) from there and the kubelet probes
|
||||||
|
# come from there too (10.1.7.64 is the node's Calico VXLAN address,
|
||||||
|
# projectcalico.org/IPv4VXLANTunnelAddr). The chart's Application
|
||||||
|
# (apps/templates/cloudnativepg-helm.yaml) only installs the chart, so
|
||||||
|
# this folder gets an Application of its own, cloudnative-pg-folder.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- namespaceSelector: {}
|
||||||
|
podSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: cnpg.io/cluster
|
||||||
|
operator: Exists
|
||||||
|
ports:
|
||||||
|
- port: 8000
|
||||||
|
- port: 5432
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Nothing runs in default (2026-10-26: only the kubernetes Service, whose
|
||||||
|
# endpoint is the API server on the node, which this doesn't touch). A pod
|
||||||
|
# started here, by `kubectl run` or a manifest without a namespace, gets
|
||||||
|
# no network at all, instead of reaching the LAN, Vault and every app.
|
||||||
|
# Anything that needs a network gets a namespace and a policy of its own.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
+1
-1
@@ -13,7 +13,7 @@ spec:
|
|||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
containers:
|
containers:
|
||||||
- name: sync
|
- name: sync
|
||||||
image: python:3.12-alpine
|
image: python:3.15-alpine
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ resources:
|
|||||||
- external-secret.yaml
|
- external-secret.yaml
|
||||||
- rbac.yaml
|
- rbac.yaml
|
||||||
- cronjob.yaml
|
- cronjob.yaml
|
||||||
|
- networkpolicy.yaml
|
||||||
|
|
||||||
configMapGenerator:
|
configMapGenerator:
|
||||||
- name: dns-sync-script
|
- name: dns-sync-script
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# The only pod here is the dns-sync Job (a PostSync hook): it installs its
|
||||||
|
# Python packages from PyPI and pushes domains/ to TransIP's API, so it
|
||||||
|
# reaches DNS and the internet (not the LAN, the API server or other
|
||||||
|
# namespaces). Nothing connects to it.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
except:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 100.64.0.0/10
|
||||||
|
- 169.254.0.0/16
|
||||||
|
- 172.16.0.0/12
|
||||||
|
- 192.168.0.0/16
|
||||||
|
ports:
|
||||||
|
- port: 443
|
||||||
+30
-11
@@ -207,7 +207,20 @@ Findings from 2026-10-25:
|
|||||||
|
|
||||||
- [x] Whether the immich library stays in Velero: it stays, since
|
- [x] Whether the immich library stays in Velero: it stays, since
|
||||||
Velero's bucket is what goes off-site (2; decided 2026-10-26)
|
Velero's bucket is what goes off-site (2; decided 2026-10-26)
|
||||||
- [ ] CNPG backups through the barman cloud plugin
|
- [x] CNPG backups through the barman cloud plugin (PR #56, merged
|
||||||
|
2026-10-26 22:43 UTC): authentik's and immich's PostgreSQL 17 back up
|
||||||
|
to their own bucket in Garage (`cnpg-authentik`, `cnpg-immich`), a base
|
||||||
|
backup at 03:00 UTC and the WAL every 5 minutes, kept 30 days. Adding
|
||||||
|
the sidecar restarted both instances; authentik was down from 22:44 to
|
||||||
|
22:48, since the old pod waited for its connections to close. The first
|
||||||
|
base backups: 46 MB in 29 s and 776 MB in 3.5 minutes. immich's
|
||||||
|
`immediate` backup ran before the plugin was up and failed; a manual one
|
||||||
|
(`immich-postgres-17-first`) went through
|
||||||
|
- [ ] Restore one of them into a new Cluster (`bootstrap.recovery` from
|
||||||
|
the ObjectStore, to a point in time) to see that it works. After that,
|
||||||
|
decide whether Velero still needs to copy the CNPG data directories
|
||||||
|
- [ ] Take `cnpg-authentik` and `cnpg-immich` along in the off-site copy
|
||||||
|
(2)
|
||||||
- [x] Velero's target, MinIO on the NAS, is no longer maintained: no
|
- [x] Velero's target, MinIO on the NAS, is no longer maintained: no
|
||||||
community images since October 2025, maintenance mode since December
|
community images since October 2025, maintenance mode since December
|
||||||
2025, and the repository is archived. Since 2026-10-26 Velero backs up
|
2025, and the repository is archived. Since 2026-10-26 Velero backs up
|
||||||
@@ -308,15 +321,16 @@ Counted 2026-10-25 over the 73 running containers:
|
|||||||
through within 20 seconds (now valid until 2027-01-24). PR #51 adds it
|
through within 20 seconds (now valid until 2027-01-24). PR #51 adds it
|
||||||
to all 11. Without it the next renewals hang too: gitea on 11-15,
|
to all 11. Without it the next renewals hang too: gitea on 11-15,
|
||||||
bolletjestrui on 11-18, the rest from 12-03
|
bolletjestrui on 11-18, the rest from 12-03
|
||||||
- [ ] The infrastructure namespaces (cert-manager, cnpg-system,
|
- [x] The infrastructure namespaces (cert-manager, cnpg-system,
|
||||||
external-secrets, envoy-gateway-system, velero, mariadb-system, dns,
|
external-secrets, envoy-gateway-system, velero, mariadb-system, dns,
|
||||||
default) still have none; `default` can reach the LAN and everything
|
default), merged 2026-10-26: PR #54 for envoy-gateway-system (22:31
|
||||||
without a policy. Prepared on 2026-10-26, not yet merged: PR #53 for
|
UTC), PR #53 for the rest (22:42 UTC; one commit per namespace, and
|
||||||
all but Envoy (one commit per namespace; `default` denies everything),
|
`default` denies everything). Checked afterwards: all 16 public hosts
|
||||||
PR #54 for envoy-gateway-system on its own, since a mistake there takes
|
answer as before; server-side dry runs reach the CNPG, ESO,
|
||||||
every public host down. Merge them when someone is home to check: the
|
cert-manager and MariaDB webhooks (all fail closed); Velero's location
|
||||||
cert-manager, CNPG, ESO and MariaDB webhooks fail closed. Velero's
|
Available, every ExternalSecret synced, the dns-sync job ran, no errors
|
||||||
policy only lets it reach Garage, not MinIO's port 9000
|
from the operators after the barman plugin had started. Velero's policy
|
||||||
|
only lets it reach Garage, not MinIO's port 9000
|
||||||
- [x] Requests: PR #33, merged 2026-10-25 11:23 UTC, for everything that
|
- [x] Requests: PR #33, merged 2026-10-25 11:23 UTC, for everything that
|
||||||
had none except the Vault server, from `kubectl top` every 5 minutes
|
had none except the Vault server, from `kubectl top` every 5 minutes
|
||||||
from 03:13 to 08:40 UTC (highest memory plus 10%, CPU at p95, 10m
|
from 03:13 to 08:40 UTC (highest memory plus 10%, CPU at p95, 10m
|
||||||
@@ -327,8 +341,13 @@ Counted 2026-10-25 over the 73 running containers:
|
|||||||
requested. Still without requests: Longhorn (22 containers, its chart),
|
requested. Still without requests: Longhorn (22 containers, its chart),
|
||||||
the Vault servers, the LDAP outpost, immich's PG14 cluster and three in
|
the Vault servers, the LDAP outpost, immich's PG14 cluster and three in
|
||||||
kube-system
|
kube-system
|
||||||
- [ ] Memory limits, once there are daytime numbers: the night ones miss
|
- [x] Memory limits: PR #58, for everything that got requests in #33.
|
||||||
immich's machine learning at work (it idles at 234Mi)
|
About twice the highest memory from `kubectl top` every 5 minutes from
|
||||||
|
2026-10-26 22:29 to 2026-10-27 21:55 UTC or the night of #33, rounded
|
||||||
|
up; no CPU limits. No OOM kills that day. immich's machine learning
|
||||||
|
sat idle all day (240Mi), so on 2026-10-28 a test image went through
|
||||||
|
CLIP, face recognition and OCR inside the container: 884Mi with all
|
||||||
|
three loaded, limit 2Gi
|
||||||
- [x] WordPress (scoutingmbg.nl) was OOMKilled at 08:27:59 UTC on
|
- [x] WordPress (scoutingmbg.nl) was OOMKilled at 08:27:59 UTC on
|
||||||
2026-10-25, its third restart: a crawler asked for 88 pages and assets
|
2026-10-25, its third restart: a crawler asked for 88 pages and assets
|
||||||
within a few seconds (normally ~6 a minute), Apache started a PHP worker
|
within a few seconds (normally ~6 a minute), Apache started a PHP worker
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# External Secrets' three pods reach each other, DNS and the API server
|
||||||
|
# (the node, port 16443); the controller also reads Vault
|
||||||
|
# (vault-active.vault.svc:8200, which vault/networkpolicy.yaml lets it
|
||||||
|
# into). Besides their own namespace they take connections only from the
|
||||||
|
# node: the API server calls the webhook from there and the kubelet probes
|
||||||
|
# come from there too (10.1.7.64 is the node's Calico VXLAN address,
|
||||||
|
# projectcalico.org/IPv4VXLANTunnelAddr). The Password generator behind
|
||||||
|
# gatus/backup-check-token needs no network. The chart's Application
|
||||||
|
# (apps/templates/external-secrets-helm.yaml) only installs the chart, so
|
||||||
|
# this folder gets an Application of its own, external-secrets-folder.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: controller-to-vault
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: external-secrets
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: vault
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: vault
|
||||||
|
ports:
|
||||||
|
- port: 8200
|
||||||
@@ -23,7 +23,7 @@ spec:
|
|||||||
io.kompose.service: freshrss
|
io.kompose.service: freshrss
|
||||||
spec:
|
spec:
|
||||||
initContainers:
|
initContainers:
|
||||||
- image: alpine/git:v2.52.0
|
- image: alpine/git:v2.54.0
|
||||||
name: git
|
name: git
|
||||||
command:
|
command:
|
||||||
- git
|
- git
|
||||||
@@ -74,7 +74,7 @@ spec:
|
|||||||
value: Europe/Amsterdam
|
value: Europe/Amsterdam
|
||||||
# 1.30.3 ships PHP 8.4.27, which fixes CVE-2026-109618 and
|
# 1.30.3 ships PHP 8.4.27, which fixes CVE-2026-109618 and
|
||||||
# CVE-2026-109619.
|
# CVE-2026-109619.
|
||||||
image: freshrss/freshrss:1.30.3
|
image: freshrss/freshrss:1.30.4
|
||||||
name: freshrss
|
name: freshrss
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
@@ -83,6 +83,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
memory: 176Mi
|
memory: 176Mi
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
# TCP, because mod_auth_openidc answers 401 to anything that isn't a
|
# TCP, because mod_auth_openidc answers 401 to anything that isn't a
|
||||||
# browser.
|
# browser.
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
|||||||
@@ -56,3 +56,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
# Envoy Gateway: the controller and the proxy it runs (envoyproxy.yaml).
|
||||||
|
# Both reach each other (the proxy gets its config from the controller on
|
||||||
|
# 18000) and DNS, and take connections from each other and the node: the
|
||||||
|
# API server calls the controller's topology webhook (9443) from there and
|
||||||
|
# the kubelet probes come from there too (10.1.7.64 is the node's Calico
|
||||||
|
# VXLAN address, projectcalico.org/IPv4VXLANTunnelAddr). Nothing scrapes
|
||||||
|
# the metrics on 19001.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: envoy-gateway-system
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
---
|
||||||
|
# The proxy holds the node's ports 80 and 443 (10080 and 10443 inside) and
|
||||||
|
# takes connections there from anywhere: the internet through node001 and
|
||||||
|
# the router, the LAN, and pods that call a public hostname. It reaches
|
||||||
|
# every app it routes to (pods in any namespace; their own policies decide
|
||||||
|
# which port), Home Assistant on 192.168.1.202:8123 (outside the cluster,
|
||||||
|
# home-assistant/), and the internet on 443 for Longhorn's OIDC login
|
||||||
|
# (authentik's token endpoint, at its public address).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: proxy
|
||||||
|
namespace: envoy-gateway-system
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
app.kubernetes.io/component: proxy
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- ports:
|
||||||
|
- port: 10080
|
||||||
|
- port: 10443
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector: {}
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.202/32
|
||||||
|
ports:
|
||||||
|
- port: 8123
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
except:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 100.64.0.0/10
|
||||||
|
- 169.254.0.0/16
|
||||||
|
- 172.16.0.0/12
|
||||||
|
- 192.168.0.0/16
|
||||||
|
ports:
|
||||||
|
- port: 443
|
||||||
|
---
|
||||||
|
# Everything but the proxy (the controller, and the chart's certgen job on
|
||||||
|
# upgrades) reaches the API server (the node, port 16443). The controller
|
||||||
|
# also fetches the OIDC discovery document of Longhorn's SecurityPolicy
|
||||||
|
# from authentik's public address.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: control-plane
|
||||||
|
namespace: envoy-gateway-system
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app.kubernetes.io/name
|
||||||
|
operator: NotIn
|
||||||
|
values:
|
||||||
|
- envoy
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
except:
|
||||||
|
- 10.0.0.0/8
|
||||||
|
- 100.64.0.0/10
|
||||||
|
- 169.254.0.0/16
|
||||||
|
- 172.16.0.0/12
|
||||||
|
- 192.168.0.0/16
|
||||||
|
ports:
|
||||||
|
- port: 443
|
||||||
@@ -83,3 +83,29 @@ spec:
|
|||||||
cidr: 192.168.1.204/32
|
cidr: 192.168.1.204/32
|
||||||
ports:
|
ports:
|
||||||
- port: 16443
|
- port: 16443
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -54,6 +54,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 20m
|
cpu: 20m
|
||||||
memory: 336Mi
|
memory: 336Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
# /api/healthz checks the database and the cache.
|
# /api/healthz checks the database and the cache.
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
|
|||||||
@@ -55,3 +55,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -67,6 +67,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
image:
|
image:
|
||||||
repository: docker.io/valkey/valkey
|
repository: docker.io/valkey/valkey
|
||||||
tag: 9.1.2-alpine@sha256:48332870af354a799964c0012ae1194a0bf2bf894eb508f945810596dc2d8d11
|
tag: 9.1.2-alpine@sha256:48332870af354a799964c0012ae1194a0bf2bf894eb508f945810596dc2d8d11
|
||||||
@@ -93,6 +95,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 1280Mi
|
memory: 1280Mi
|
||||||
|
limits:
|
||||||
|
memory: 3Gi
|
||||||
# Node trusts its built-in roots, which still include the
|
# Node trusts its built-in roots, which still include the
|
||||||
# ones above the compromised eMudhra intermediates. Use
|
# ones above the compromised eMudhra intermediates. Use
|
||||||
# patched-ca-bundle through OpenSSL until Node ships a fix.
|
# patched-ca-bundle through OpenSSL until Node ships a fix.
|
||||||
@@ -117,12 +121,14 @@ spec:
|
|||||||
image:
|
image:
|
||||||
repository: ghcr.io/immich-app/immich-machine-learning
|
repository: ghcr.io/immich-app/immich-machine-learning
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
# Idle at night (234Mi); the models take over a GiB when
|
# Idle at 240Mi; 884Mi with CLIP, face recognition and
|
||||||
# it works.
|
# OCR loaded (2026-10-28, a test image through each).
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
memory: 1Gi
|
memory: 1Gi
|
||||||
|
limits:
|
||||||
|
memory: 2Gi
|
||||||
env:
|
env:
|
||||||
TRANSFORMERS_CACHE: /cache
|
TRANSFORMERS_CACHE: /cache
|
||||||
HF_XET_CACHE: /cache/huggingface-xet
|
HF_XET_CACHE: /cache/huggingface-xet
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ spec:
|
|||||||
---
|
---
|
||||||
# The CNPG operator checks each instance on its status port and connects to
|
# The CNPG operator checks each instance on its status port and connects to
|
||||||
# PostgreSQL; the instance manager inside each pod watches its Cluster
|
# PostgreSQL; the instance manager inside each pod watches its Cluster
|
||||||
# through the API server (the node, port 16443).
|
# through the API server (the node, port 16443). The barman cloud sidecar
|
||||||
|
# sends the WAL and the base backups to Garage on the NAS
|
||||||
|
# (postgresql-backup.yaml).
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: NetworkPolicy
|
kind: NetworkPolicy
|
||||||
metadata:
|
metadata:
|
||||||
@@ -100,3 +102,34 @@ spec:
|
|||||||
cidr: 192.168.1.204/32
|
cidr: 192.168.1.204/32
|
||||||
ports:
|
ports:
|
||||||
- port: 16443
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.99/32
|
||||||
|
ports:
|
||||||
|
- port: 3900
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# Backups of immich's database (albums, faces, the photos' metadata; the
|
||||||
|
# photos themselves are files on immich-claim) by CNPG itself, through the
|
||||||
|
# barman cloud plugin (apps/templates/plugin-barman-cloud-helm.yaml): a base
|
||||||
|
# backup every night, and every WAL segment as soon as it is full or 5
|
||||||
|
# minutes old (archive_timeout). Both go to the bucket cnpg-immich in Garage
|
||||||
|
# on the NAS (nas/garage), so the database can be restored to any moment of
|
||||||
|
# the last 30 days. Velero copies the data directory while PostgreSQL runs,
|
||||||
|
# which is not a consistent copy. Only the PostgreSQL 17 cluster; the 14
|
||||||
|
# one is about to go.
|
||||||
|
# The key is Garage's cnpg-immich, in Vault as kv/cnpg-immich-s3; it can
|
||||||
|
# only reach this bucket.
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: immich-postgres-17-s3
|
||||||
|
namespace: immich
|
||||||
|
spec:
|
||||||
|
secretStoreRef:
|
||||||
|
name: vault-backend
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
refreshInterval: 15m
|
||||||
|
target:
|
||||||
|
name: immich-postgres-17-s3
|
||||||
|
creationPolicy: Owner
|
||||||
|
template:
|
||||||
|
engineVersion: v2
|
||||||
|
data:
|
||||||
|
ACCESS_KEY_ID: "{{ .access_key_id }}"
|
||||||
|
ACCESS_SECRET_KEY: "{{ .secret_access_key }}"
|
||||||
|
# Garage rejects requests signed for another region
|
||||||
|
REGION: garage
|
||||||
|
data:
|
||||||
|
- secretKey: access_key_id
|
||||||
|
remoteRef:
|
||||||
|
key: kv/cnpg-immich-s3
|
||||||
|
property: access_key_id
|
||||||
|
- secretKey: secret_access_key
|
||||||
|
remoteRef:
|
||||||
|
key: kv/cnpg-immich-s3
|
||||||
|
property: secret_access_key
|
||||||
|
---
|
||||||
|
apiVersion: barmancloud.cnpg.io/v1
|
||||||
|
kind: ObjectStore
|
||||||
|
metadata:
|
||||||
|
name: immich-postgres-17
|
||||||
|
namespace: immich
|
||||||
|
annotations:
|
||||||
|
# The CRD comes with the plugin's own app
|
||||||
|
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
|
||||||
|
spec:
|
||||||
|
retentionPolicy: 30d
|
||||||
|
configuration:
|
||||||
|
destinationPath: s3://cnpg-immich/
|
||||||
|
endpointURL: http://192.168.1.99:3900
|
||||||
|
s3Credentials:
|
||||||
|
accessKeyId:
|
||||||
|
name: immich-postgres-17-s3
|
||||||
|
key: ACCESS_KEY_ID
|
||||||
|
secretAccessKey:
|
||||||
|
name: immich-postgres-17-s3
|
||||||
|
key: ACCESS_SECRET_KEY
|
||||||
|
region:
|
||||||
|
name: immich-postgres-17-s3
|
||||||
|
key: REGION
|
||||||
|
wal:
|
||||||
|
compression: gzip
|
||||||
|
data:
|
||||||
|
compression: gzip
|
||||||
|
instanceSidecarConfiguration:
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
|
env:
|
||||||
|
# Newer boto3 adds checksums that S3-compatible stores can reject;
|
||||||
|
# the plugin's docs suggest sending them only when required.
|
||||||
|
- name: AWS_REQUEST_CHECKSUM_CALCULATION
|
||||||
|
value: when_required
|
||||||
|
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
|
||||||
|
value: when_required
|
||||||
|
---
|
||||||
|
apiVersion: postgresql.cnpg.io/v1
|
||||||
|
kind: ScheduledBackup
|
||||||
|
metadata:
|
||||||
|
name: immich-postgres-17-daily
|
||||||
|
namespace: immich
|
||||||
|
spec:
|
||||||
|
cluster:
|
||||||
|
name: immich-postgres-17
|
||||||
|
# 03:00 UTC, after Longhorn's and Velero's backups; immediate: one right
|
||||||
|
# away, so WAL archiving has a base backup to start from.
|
||||||
|
schedule: "0 0 3 * * *"
|
||||||
|
immediate: true
|
||||||
|
backupOwnerReference: self
|
||||||
|
method: plugin
|
||||||
|
pluginConfiguration:
|
||||||
|
name: barman-cloud.cloudnative-pg.io
|
||||||
@@ -13,11 +13,20 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 20m
|
cpu: 20m
|
||||||
memory: 320Mi
|
memory: 320Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
|
|
||||||
postgresql:
|
postgresql:
|
||||||
shared_preload_libraries:
|
shared_preload_libraries:
|
||||||
- "vchord.so"
|
- "vchord.so"
|
||||||
|
|
||||||
|
# WAL archiving and base backups to Garage, see postgresql-backup.yaml
|
||||||
|
plugins:
|
||||||
|
- name: barman-cloud.cloudnative-pg.io
|
||||||
|
isWALArchiver: true
|
||||||
|
parameters:
|
||||||
|
barmanObjectName: immich-postgres-17
|
||||||
|
|
||||||
# Filled once from the PostgreSQL 14 cluster (immich-postgres) after its
|
# Filled once from the PostgreSQL 14 cluster (immich-postgres) after its
|
||||||
# embedding columns were turned into real[] and pgvecto.rs was dropped,
|
# embedding columns were turned into real[] and pgvecto.rs was dropped,
|
||||||
# see docs/upgrade-k8s-1.33.md.
|
# see docs/upgrade-k8s-1.33.md.
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ kind: Kustomization
|
|||||||
resources:
|
resources:
|
||||||
- operator-crds-helm.yaml
|
- operator-crds-helm.yaml
|
||||||
- operator-helm.yaml
|
- operator-helm.yaml
|
||||||
|
- networkpolicy.yaml
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# The mariadb-operator's three pods reach each other, DNS and the API
|
||||||
|
# server (the node, port 16443); the operator also connects to MariaDB on
|
||||||
|
# 3306 for the databases, users and grants it manages (mbgwp's
|
||||||
|
# mariadb-from-operator lets it in). Besides their own namespace they take
|
||||||
|
# connections only from the node: the API server calls the webhook from
|
||||||
|
# there and the kubelet probes come from there too (10.1.7.64 is the node's
|
||||||
|
# Calico VXLAN address, projectcalico.org/IPv4VXLANTunnelAddr). This
|
||||||
|
# folder's Application deploys into argocd (the operator's own
|
||||||
|
# Applications), hence the namespace here.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: mariadb-system
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- namespaceSelector: {}
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: mariadb
|
||||||
|
ports:
|
||||||
|
- port: 3306
|
||||||
@@ -13,7 +13,7 @@ spec:
|
|||||||
source:
|
source:
|
||||||
chart: mariadb-operator-crds
|
chart: mariadb-operator-crds
|
||||||
repoURL: https://mariadb-operator.github.io/mariadb-operator
|
repoURL: https://mariadb-operator.github.io/mariadb-operator
|
||||||
targetRevision: 25.10.4
|
targetRevision: 26.10.2
|
||||||
syncPolicy:
|
syncPolicy:
|
||||||
automated:
|
automated:
|
||||||
prune: true
|
prune: true
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ spec:
|
|||||||
source:
|
source:
|
||||||
chart: mariadb-operator
|
chart: mariadb-operator
|
||||||
repoURL: https://mariadb-operator.github.io/mariadb-operator
|
repoURL: https://mariadb-operator.github.io/mariadb-operator
|
||||||
targetRevision: 25.10.4
|
targetRevision: 26.10.2
|
||||||
helm:
|
helm:
|
||||||
values: |
|
values: |
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 48Mi
|
memory: 48Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
metrics:
|
metrics:
|
||||||
enabled: true
|
enabled: true
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
@@ -29,6 +31,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
enabled: false
|
enabled: false
|
||||||
certController:
|
certController:
|
||||||
@@ -36,6 +40,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
enabled: false
|
enabled: false
|
||||||
syncPolicy:
|
syncPolicy:
|
||||||
|
|||||||
@@ -85,3 +85,29 @@ spec:
|
|||||||
kubernetes.io/metadata.name: mariadb-system
|
kubernetes.io/metadata.name: mariadb-system
|
||||||
ports:
|
ports:
|
||||||
- port: 3306
|
- port: 3306
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -31,5 +31,12 @@ Velero's key is in Vault as `kv/velero-s3` (`access_key_id`,
|
|||||||
`velero/external-secret.yaml`. Without the cluster, `$g key info velero
|
`velero/external-secret.yaml`. Without the cluster, `$g key info velero
|
||||||
--show-secret` on the NAS shows it again.
|
--show-secret` on the NAS shows it again.
|
||||||
|
|
||||||
|
CNPG's backups (`authentik/postgresql-backup.yaml`,
|
||||||
|
`immich/postgresql-backup.yaml`) have a bucket and a key per cluster, so
|
||||||
|
neither database can touch the other's backups. Made on 2026-10-26 the
|
||||||
|
same way as Velero's, with `cnpg-authentik` and `cnpg-immich` as both
|
||||||
|
bucket and key name; the keys are in Vault as `kv/cnpg-authentik-s3` and
|
||||||
|
`kv/cnpg-immich-s3`.
|
||||||
|
|
||||||
Renovate updates the image tag in `compose.yaml`, but nothing deploys it:
|
Renovate updates the image tag in `compose.yaml`, but nothing deploys it:
|
||||||
after merging, `docker compose pull && docker compose up -d` on the NAS.
|
after merging, `docker compose pull && docker compose up -d` on the NAS.
|
||||||
@@ -65,3 +65,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
"config:recommended",
|
"config:recommended",
|
||||||
"customManagers:githubActionsVersions"
|
"customManagers:githubActionsVersions"
|
||||||
],
|
],
|
||||||
|
"timezone": "Europe/Amsterdam",
|
||||||
"argocd": {
|
"argocd": {
|
||||||
"description": "Every app folder; Renovate's regexes are RE2, which has no lookahead, so the other folders are skipped through ignorePaths",
|
"description": "Every app folder; Renovate's regexes are RE2, which has no lookahead, so the other folders are skipped through ignorePaths",
|
||||||
"managerFilePatterns": [
|
"managerFilePatterns": [
|
||||||
@@ -88,6 +89,27 @@
|
|||||||
"major"
|
"major"
|
||||||
],
|
],
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Patch updates of apps that hold little state and are easy to roll back, and of CI's tools, merge themselves once CI passes: three days after the release, in the evening or at the weekend, when the cluster can be reached. Not the databases, operators, Vault, authentik, Longhorn, Velero, immich, Gitea or WordPress. Renovate merges itself; the repo has no branch protection for GitHub's auto-merge to wait on",
|
||||||
|
"matchFileNames": [
|
||||||
|
"ntfy/**",
|
||||||
|
"gatus/**",
|
||||||
|
"freshrss/**",
|
||||||
|
"serpbear/**",
|
||||||
|
"actual-budget/**",
|
||||||
|
".github/workflows/**"
|
||||||
|
],
|
||||||
|
"matchUpdateTypes": [
|
||||||
|
"patch"
|
||||||
|
],
|
||||||
|
"minimumReleaseAge": "3 days",
|
||||||
|
"automerge": true,
|
||||||
|
"platformAutomerge": false,
|
||||||
|
"automergeSchedule": [
|
||||||
|
"* 17-21 * * 1-5",
|
||||||
|
"* 10-21 * * 0,6"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -54,3 +54,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -60,6 +60,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 160Mi
|
memory: 160Mi
|
||||||
|
limits:
|
||||||
|
memory: 512Mi
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /login
|
path: /login
|
||||||
|
|||||||
@@ -66,3 +66,29 @@ spec:
|
|||||||
- 169.254.0.0/16
|
- 169.254.0.0/16
|
||||||
- 172.16.0.0/12
|
- 172.16.0.0/12
|
||||||
- 192.168.0.0/16
|
- 192.168.0.0/16
|
||||||
|
---
|
||||||
|
# cert-manager's HTTP-01 solver, which runs only while a certificate
|
||||||
|
# renews: Let's Encrypt and cert-manager's own self check reach it on 8089
|
||||||
|
# through Envoy. The policies above let Envoy reach the app's port only,
|
||||||
|
# which left the solver unreachable (found 2026-10-26, when ynab's renewal
|
||||||
|
# hung).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: acme-http01-solver
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: envoy-gateway-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: envoy
|
||||||
|
ports:
|
||||||
|
- port: 8089
|
||||||
@@ -7,6 +7,8 @@ injector:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
# The chart's default anti-affinity forbids two injector pods on one
|
# The chart's default anti-affinity forbids two injector pods on one
|
||||||
# node, so on this single node a rolling update can never start the new
|
# node, so on this single node a rolling update can never start the new
|
||||||
# pod while the old one runs. Recreate removes the old pod first, which
|
# pod while the old one runs. Recreate removes the old pod first, which
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Velero, its node agent, and the pods it starts here (the data movers of
|
||||||
|
# each pod volume backup or restore, kopia's maintenance jobs, the chart's
|
||||||
|
# CRD upgrade job) reach each other, DNS, the API server (the node, port
|
||||||
|
# 16443) and Garage on the NAS (192.168.1.99:3900, nas/garage). The node
|
||||||
|
# agent reads volumes through its hostPath mount, not the network. Besides
|
||||||
|
# their own namespace they take connections only from the node (kubelet
|
||||||
|
# probes; 10.1.7.64 is the node's Calico VXLAN address,
|
||||||
|
# projectcalico.org/IPv4VXLANTunnelAddr); nothing scrapes the metrics on
|
||||||
|
# 8085. MinIO (the NAS, port 9000) is not allowed: going back to it means
|
||||||
|
# adding its port here as well.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector: {}
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 10.1.7.64/32
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- podSelector: {}
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
k8s-app: kube-dns
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.204/32
|
||||||
|
ports:
|
||||||
|
- port: 16443
|
||||||
|
- to:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 192.168.1.99/32
|
||||||
|
ports:
|
||||||
|
- port: 3900
|
||||||
@@ -71,6 +71,8 @@ spec:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
# 512Mi got the server OOMKilled 314 times, including halfway
|
# 512Mi got the server OOMKilled 314 times, including halfway
|
||||||
# through a backup of ~14.7k items.
|
# through a backup of ~14.7k items.
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
Reference in new issue
Block a user