refactor(k8s): consolidate to infra/+apps/ single-source tree, dedicated per-app CNPG (authentik-db/temporal-db), wire monitoring-config, forgejo→cicd ns, drop orphan/stale (data-schemas, ollama, story-crater, sqs/argocd, key-rotation)

This commit is contained in:
Story Crater Bot
2026-08-18 15:08:03 -07:00
parent 54fa540b33
commit 41f5b05395
241 changed files with 467 additions and 10416 deletions
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v2
name: forgejo-runner
description: Forgejo Actions runner with Docker-in-Docker sidecar for homelab CI/CD
type: application
version: 0.1.0
appVersion: "6"
@@ -0,0 +1,108 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name }}
spec:
replicas: 1
strategy:
type: Recreate # RWO PVCs — old pod must terminate before new one mounts them
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
# runner image runs as UID 1000; fsGroup makes the Longhorn /data PVC
# group-writable so `register` can write /data/.runner (else permission denied).
securityContext:
fsGroup: 1000
tolerations:
{{- toYaml .Values.tolerations | nindent 8 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
initContainers:
- name: register
image: {{ .Values.runner.image.repository }}:{{ .Values.runner.image.tag }}
command: ["sh", "-c"]
args:
- |
test -f /data/.runner || forgejo-runner register --no-interactive \
--instance {{ .Values.runner.forgejoUrl }} \
--token $(RUNNER_TOKEN) \
--name {{ .Values.runner.name }} \
--labels "{{ .Values.runner.labels }}"
env:
- name: RUNNER_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.runner.tokenSecret }}
key: token
volumeMounts:
- name: runner-data
mountPath: /data
- name: homelab-ca
mountPath: /etc/ssl/certs/homelab-ca.pem
subPath: ca.crt
workingDir: /data
containers:
- name: runner
image: {{ .Values.runner.image.repository }}:{{ .Values.runner.image.tag }}
command: ["sh", "-c", "forgejo-runner daemon"]
workingDir: /data
env:
- name: DOCKER_HOST
value: tcp://localhost:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /docker-certs/client
volumeMounts:
- name: runner-data
mountPath: /data
- name: docker-certs
mountPath: /docker-certs
- name: homelab-ca
mountPath: /etc/ssl/certs/homelab-ca.pem
subPath: ca.crt
resources:
{{- toYaml .Values.runner.resources | nindent 12 }}
- name: dind
image: {{ .Values.dind.image.repository }}:{{ .Values.dind.image.tag }}
securityContext:
privileged: true # required for DinD; cicd namespace is labelled privileged
env:
- name: DOCKER_TLS_CERTDIR
value: /docker-certs
volumeMounts:
- name: docker-certs
mountPath: /docker-certs
- name: dind-storage
mountPath: /var/lib/docker
- name: homelab-ca
mountPath: /etc/ssl/certs/homelab-ca.pem
subPath: ca.crt
resources:
{{- toYaml .Values.dind.resources | nindent 12 }}
volumes:
- name: runner-data
persistentVolumeClaim:
claimName: runner-reg
- name: dind-storage
persistentVolumeClaim:
claimName: runner-dind
- name: docker-certs
emptyDir: {} # DinD regenerates mTLS certs on each start
- name: homelab-ca
secret:
secretName: homelab-ca
@@ -0,0 +1,31 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Release.Name }}-egress
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: {{ .Release.Name }}
policyTypes: [Egress]
egress:
# Forgejo — same cicd namespace (git push, registry push/pull)
- to:
- podSelector: {}
# CoreDNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Internet (action deps, base images) — never LAN or pod network
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 192.168.1.0/24
- 10.244.0.0/16
@@ -0,0 +1,27 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: runner-reg
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name }}
spec:
accessModes: [ReadWriteOnce]
storageClassName: {{ .Values.persistence.reg.storageClass }}
resources:
requests:
storage: {{ .Values.persistence.reg.size }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: runner-dind
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name }}
spec:
accessModes: [ReadWriteOnce]
storageClassName: {{ .Values.persistence.dind.storageClass }}
resources:
requests:
storage: {{ .Values.persistence.dind.size }}
+49
View File
@@ -0,0 +1,49 @@
runner:
image:
repository: code.forgejo.org/forgejo/runner
tag: "6" # pin exact release before apply
name: talos-runner
labels: "docker:docker://node:22-bookworm"
# In-cluster Service (:3000) — direct, avoids the ingress/public-hostname hop
# (the public URL is :443 which forgejo doesn't serve; runner got i/o timeout).
forgejoUrl: http://forgejo-gitea-http.cicd.svc.cluster.local:3000
# tokenSecret: name of the K8s Secret that holds the runner registration token
# created automatically by the helmfile presync hook (see helmfile.yaml.gotmpl)
tokenSecret: runner-token
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "2"
memory: 4Gi
dind:
image:
repository: docker
tag: "27-dind" # pin exact release before apply
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "2"
memory: 4Gi
persistence:
reg:
storageClass: longhorn # Unified StorageClass (3 replicas)
size: 1Gi # .runner registration file + config — survives pod restarts
dind:
storageClass: longhorn # Unified StorageClass (3 replicas)
size: 30Gi # docker layer cache — keeps rebuilds fast across restarts
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
# Pin to az-a (talos-cp-1) — sole Longhorn node; RWO PVCs (reg/dind cache) only
# attach there.
nodeSelector:
topology.kubernetes.io/zone: az-a