refactor(k8s): Reorganize into 5-layer structure with production kustomizations

This commit is contained in:
Story Crater Bot
2026-07-16 14:28:19 -07:00
parent a81b9b6169
commit 2d7330798b
214 changed files with 405 additions and 885 deletions
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: dev-tools
resources: []
# Helm chart deployed via ArgoCD Helm source
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: duckdns
resources: []
# DuckDNS deployed via Helm chart or CronJob
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: forge
resources:
- pki/
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: []
# PKI configuration, not K8s manifests
+18
View File
@@ -0,0 +1,18 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: applications
# Layer 5: Applications — user services, workloads
# Dependencies: all previous layers (bootstrap, platform, security)
# Order: Applied fifth
resources:
- temporal/
- sqs/
- llm/
- portainer/
- forge/
- shadowsocks/
- dev-tools/
- duckdns/
+6
View File
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: llm
resources:
- scripts/
# Helm charts deployed via ArgoCD Helm source
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: []
# Shell scripts, not K8s manifests
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: portainer
resources: []
# Portainer deployed via Helm chart or existing manifests
@@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: shadowsocks
resources: []
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: sqs
resources:
- 02-redis.yaml
- 03-queue-crd.yaml
- 04-management-service.yaml
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: sqs
resources:
- project.yaml
- root.yaml
- apps/
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: sqs
resources: []
# homelab.yaml is configuration, not a K8s manifest
+8
View File
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: sqs
resources:
- argocd/
- environments/
- queues/
# Helm charts deployed via ArgoCD Helm source
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- orders-fifo.yaml
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: temporal
resources:
- elasticsearch.yaml
- queues/
# SOPS secrets (*.enc.yaml) handled by ArgoCD SOPS plugin at sync time
# temporal deployed via ArgoCD Helm source
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- example-queue.yaml
+22
View File
@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: homelab-root
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/argocd/root
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-1-infrastructure
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/infrastructure
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21
View File
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-2-bootstrap
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/bootstrap
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21
View File
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-3-platform
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "3"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/platform
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21
View File
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-4-security
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "4"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/security
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21
View File
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-5-applications
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "5"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/applications
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21
View File
@@ -0,0 +1,21 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: layer-6-data
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "6"
spec:
project: homelab
source:
repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
targetRevision: main
path: k8s/data
destination:
server: https://kubernetes.default.svc
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+15
View File
@@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: homelab-root
# Root Application orchestration
# Includes all layer Applications in order (sync-wave)
resources:
- ../apps/layer-1-infrastructure.yaml
- ../apps/layer-2-bootstrap.yaml
- ../apps/layer-3-platform.yaml
- ../apps/layer-4-security.yaml
- ../apps/layer-5-applications.yaml
- ../apps/layer-6-data.yaml
-19
View File
@@ -1,19 +0,0 @@
#!/bin/bash
# Reusable namespace setup script
# Creates namespace and applies pod-security policy labels
# Usage: bash k8s/base/namespace-setup.sh <namespace> [<namespace2> ...]
set -euo pipefail
if [ $# -eq 0 ]; then
echo "Usage: $0 <namespace> [<namespace2> ...]" >&2
exit 1
fi
for namespace in "$@"; do
kubectl create namespace "$namespace" --dry-run=client -o yaml | kubectl apply -f -
kubectl label namespace "$namespace" \
pod-security.kubernetes.io/enforce=privileged \
pod-security.kubernetes.io/enforce-version=latest \
--overwrite
echo "✓ Namespace '$namespace' ready"
done
-322
View File
@@ -1,322 +0,0 @@
# k8s/base/poddisruptionbudgets.yaml
# PodDisruptionBudgets ensure zero-downtime cluster maintenance.
# Allows Kubernetes to gracefully drain nodes during updates/maintenance
# without violating availability guarantees.
---
# Observability stack
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: grafana
namespace: logging
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: grafana
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: loki
namespace: logging
spec:
minAvailable: 1
selector:
matchLabels:
app: loki
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: prometheus
namespace: monitoring
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: prometheus
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: prometheus-operator
namespace: monitoring
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: kube-prometheus-stack-operator
---
# IAM stack
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: authentik
namespace: iam
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: authentik
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: vault
namespace: iam
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: vault
---
# CI/CD stack
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: argocd-server
namespace: cicd
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: argocd-server
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: argocd-repo-server
namespace: cicd
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: forgejo
namespace: forge
spec:
minAvailable: 1
selector:
matchLabels:
app: forgejo
---
# Ingress & network
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
---
# Certificate management
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cert-manager
namespace: cert-manager
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: cert-manager
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cert-manager-webhook
namespace: cert-manager
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: cert-manager-webhook
---
# Storage & replication
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: minio-az-a
namespace: storage
spec:
minAvailable: 2
selector:
matchLabels:
app: minio
instance: az-a
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: minio-az-b
namespace: storage
spec:
minAvailable: 2
selector:
matchLabels:
app: minio
instance: az-b
---
# Database
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cnpg-cluster
namespace: ddb
spec:
minAvailable: 2
selector:
matchLabels:
cnpg.io/cluster: ddb-cluster
---
# Messaging
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: kafka-broker
namespace: sqs
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: kafka
app.kubernetes.io/component: kafka-broker
---
# Workflow orchestration
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: temporal-cassandra
namespace: temporal
spec:
minAvailable: 2
selector:
matchLabels:
app: cassandra
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: temporal-server
namespace: temporal
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: temporal
app.kubernetes.io/component: server
---
# LLM inference
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ollama
namespace: llm
spec:
minAvailable: 1
selector:
matchLabels:
app: ollama
---
# Cluster DNS
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: coredns
namespace: kube-system
spec:
minAvailable: 1
selector:
matchLabels:
k8s-app: kube-dns
---
# Cilium networking
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cilium-agent
namespace: kube-system
spec:
minAvailable: 1
selector:
matchLabels:
k8s-app: cilium
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: cilium-operator
namespace: kube-system
spec:
minAvailable: 1
selector:
matchLabels:
io.cilium/app: operator
---
# Longhorn storage
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: longhorn-manager
namespace: longhorn-system
spec:
minAvailable: 2
selector:
matchLabels:
app: longhorn-manager
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: longhorn-csi-plugin
namespace: longhorn-system
spec:
minAvailable: 1
selector:
matchLabels:
app: csi-provisioner
---
# System components
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: kube-state-metrics
namespace: monitoring
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: kube-state-metrics
-38
View File
@@ -1,38 +0,0 @@
authentik:
secret_key: ENC[AES256_GCM,data:4u/VJKGJL6J+ILh2+HY=,iv:mZus6YQX7TK6BK8JbHvS113ph4jZpUqKiKLK69nLc8k=,tag:xj/FhXl/GpA7zfYBkyEpGA==,type:str]
bootstrap_password: ENC[AES256_GCM,data:z5qyj124j90pimo07QQ=,iv:oJj54T0WEoy4zq8gTPsCBEZ5BqJubbyuLBdb9in98oU=,tag:SaVmxgIqxhzBjOnMi1PT6g==,type:str]
bootstrap_token: ENC[AES256_GCM,data:zbs67SwmNqXUj1inerg=,iv:TL3hu2NR9eCvZQHM9L2WJHlhi1lqNJDU+tKHJHy8OZM=,tag:2fzVZDXazzNrExBq/12dfQ==,type:str]
postgresql_password: ENC[AES256_GCM,data:lnisFWkVkv9LmRiB+cA=,iv:nFcecdugM8GB+ty4Ac5HhN84ekWk+VpDRh2QuW7cZhk=,tag:8Nu9aodwPqQ+1OP4xRVr2g==,type:str]
minio:
root_user: ENC[AES256_GCM,data:MQQHIaoc1tuG8A==,iv:92bGTYwyqc7tasjO0F8j2cBH28/ZOBHMkawsix6Z0UE=,tag:gkug3OeiZ5tpPrtXApFfsg==,type:str]
root_password: ENC[AES256_GCM,data:Neb1t95cJqxnnXKCIAYqLl6N0zdtD843RrnHyXhnEulZhvqPeMC2Y1DIZr8=,iv:NSveFwxhONWq8MfcVCvjLisbHJgZfkLBBp9Z0tmxQ+Y=,tag:zM0hpg97GcMJ9YFtDj7vjQ==,type:str]
oidc_client_secret: ENC[AES256_GCM,data:I+JJuokOMYX/52sSxos=,iv:wxZQ1NaeYCF3EMkZKyrzTXP35fbiA8VnMZV3cX+NYuA=,tag:O/7kuLTws7cz45GbACHsYQ==,type:str]
forgejo:
admin_password: ENC[AES256_GCM,data:WbjwEpB6vkRjZEwXg1QVPVl0pj5/QOfuo0SJndBr5OE=,iv:jvZ7+IH++qaUJL9Ts2+6X5ip1QvLOeGfzoBsKsFjbwo=,tag:zQXfRuXUdqwTcA7EDzRwJA==,type:str]
oidc_client_secret: ENC[AES256_GCM,data:2ikhULuCiUx98G9FubTKolZrDLuctA6F7m7xSTK/K+qHAmN4Zuqi+BzU56dfC0W2g7ZUqQ8flPQ8Jw2HlR/mww==,iv:zVZeAdxraSEQNMSX1r08L8j5g7pCKP86OTOBAHg3AIU=,tag:vke5Pj7QnEPIbI6LswLXnQ==,type:str]
grafana:
admin_password: ENC[AES256_GCM,data:cFfbO8f/A2yQVnXUa2Trpnp9g6M=,iv:LEnAOBFwr4YtmlXdE+GnorFPR1zJ406sxch0pgnnTCs=,tag:LDkt62m8zIw6sBTIiJBLTA==,type:str]
oidc_client_secret: ENC[AES256_GCM,data:YQV8mM6ogq57bXb1oFCocO+JPhFztAhqosex54s4ZcvJDSnQbAy/ILfcTVqQ26qoD4M7Bf2p+P/lSAO9RXPKtA==,iv:X2X/k2MqdEXN0SO53RadvS3JKzkXlTfgSf5bZCaWFRI=,tag:UK+BvSBa2ZXLmZHoh/V18A==,type:str]
argocd:
oidc_client_secret: ENC[AES256_GCM,data:BxTd8J/hnMDRBwND1ho=,iv:hP8OwLWTiaB3tT5kQarDWpfPYe/wWP/7DP+TyM7OJZY=,tag:K05rRDyk6dJYAtjJmgtbNQ==,type:str]
temporal:
oidc_client_id: ENC[AES256_GCM,data:zKj5POhCGcfoXy+d+zg=,iv:1NmLIy0xQ9V9AZipU/r6HQOPkvsTFV29cESVFsRZaZw=,tag:U+SkYLAXj5OSNJImINO5sw==,type:str]
oidc_client_secret: ENC[AES256_GCM,data:hWgK6dhh7onHmTwq3UU=,iv:iahP7vl3RPQaOJDvlTVqjn1+w8H8y0AZ/CToiIpZtB4=,tag:qqRhHShIc36aEmtUHHUnig==,type:str]
ollama:
oidc_client_id: ENC[AES256_GCM,data:b9+dTdLSL4mbodLBcI8=,iv:gnborzVMME6Baw4LuvucjdqjNnyygXhRZ1K4yQyr26c=,tag:2DfC9uRbVKzf5zcPspa+vA==,type:str]
oidc_client_secret: ENC[AES256_GCM,data:Ow8JrhgCJlHfYfQ1GBc=,iv:QBXdVyowDKPsN4Fjbe9Eh0O4cTgrPAx6EfN5kpRRsek=,tag:zw4mN/SJQMh25vm/yoCNBQ==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxVWZkRDRBc09BakYvaUZD
em1CcFhwOVpjRnJsYjhxM3J3WldnMjE3MkJvClJrT1BXaGFkOU80V3krbVRNYXVo
RE5Jb0dISEJiU1lVc1U4blI0b2d6SVUKLS0tIDM2dk95M08rQkNuYStYbks1ZVBG
L2pIS3ZMYUVxTndwcW1zNCtPbWJ0Y2sKW6SkSLf+y37WR0hVy5bVegnsjBRCsmqq
VYNVFf/xzrCU6Bjv0KV/1laHHmQoea1xQPC2l6KrptUEZoVjDYkKpQ==
-----END AGE ENCRYPTED FILE-----
recipient: age1smu533f803gmd0jq60s2zaj9zlznajy0ca6rtewd4r37mr2hs3uqsrldfh
lastmodified: "2026-07-15T22:03:57Z"
mac: ENC[AES256_GCM,data:wds9Tc4t3V5uTxdsXtJuuOXLfRNt+uPso6Ge3TTgv8BDDxN/jPQmBPljvdKp8U7kXhtq7ifgtEbJUwunZvBAhJN8T2gQs6+SaNgNS+H7RqWXWsTnMy0u1PAz6WX8FEYNeZMqePrkAtV6kLjx3B/b6bL+mRxVXut8+kBmfpKgoEI=,iv:Su6uHqqn5qdoIdxxOGRmapyv8OsYNbPwRVD/QHgJZa0=,tag:hh9KcYDXPaq+aGUDzJDPKQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.2
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cert-manager
resources: []
# cert-manager deployed via ArgoCD Helm source (see layer-2-bootstrap app)
+5
View File
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-system
resources: []
# Cilium deployed via Helm chart
+5
View File
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-system
resources: []
# CoreDNS deployed via Helm chart
+5
View File
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: ingress-nginx
resources: []
# Ingress controller deployed via Helm chart

Some files were not shown because too many files have changed in this diff Show More