- Move Keycloak off Helm to plain Crossplane Object manifests (PostgreSQL + Keycloak deployment) - Add Vaultwarden SSO/OIDC config with Keycloak, fix Recreate deployment strategy for RWO volumes - Switch routing from Helm-based Pomerium to pomerium-allinone with all service routes - Deploy Argo Workflows (controller, server, CRDs, RBAC) with KEDA queue-depth autoscaling - Add Civo cluster autoscaler with pool-scaler for zero-to-one scale-up via Civo API - Add node-labeler to auto-tag nodes by pool membership for nodeSelector scheduling - Set up mTLS container registry at registry.nge6.com (Forgejo built-in, client cert required) - Add internal registry route (registry-internal.nge6.com) for in-cluster image pulls - Fix DNS records for new Emissary LB IP (212.2.241.28) - Fix CoreDNS crash from invalid custom config - Fix Emissary apiext expired webhook CA certificate Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
127 lines
3.7 KiB
YAML
127 lines
3.7 KiB
YAML
# Node labeler - automatically labels nodes by pool based on name pattern
|
|
# fc94 in node name -> main pool (1b886eac...)
|
|
# cc28 in node name -> high-compute pool
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: node-labeler-sa
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: node-labeler
|
|
namespace: kube-system
|
|
---
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: node-labeler-clusterrole
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: node-labeler
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: [nodes]
|
|
verbs: [get, list, patch]
|
|
- apiGroups: [""]
|
|
resources: [pods]
|
|
verbs: [get, list, watch]
|
|
---
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: node-labeler-clusterrolebinding
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: node-labeler
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: node-labeler
|
|
namespace: kube-system
|
|
roleRef:
|
|
kind: ClusterRole
|
|
name: node-labeler
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: node-labeler-deployment
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: node-labeler
|
|
namespace: kube-system
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: node-labeler
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: node-labeler
|
|
spec:
|
|
serviceAccountName: node-labeler
|
|
containers:
|
|
- name: labeler
|
|
image: bitnami/kubectl:latest
|
|
command:
|
|
- /bin/bash
|
|
- -c
|
|
- |
|
|
while true; do
|
|
for NODE in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
|
|
# Skip if already labeled
|
|
POOL=$(kubectl get node "$NODE" -o jsonpath='{.metadata.labels.kubernetes\.civo\.com/node-pool}' 2>/dev/null)
|
|
if [ -n "$POOL" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Label based on name pattern
|
|
if echo "$NODE" | grep -q "fc94"; then
|
|
echo "Labeling $NODE as main pool"
|
|
kubectl label node "$NODE" \
|
|
kubernetes.civo.com/node-pool=1b886eac-942e-40bf-8f70-7a5496f2fd3b \
|
|
kubernetes.civo.com/node-size=g4s.kube.medium --overwrite
|
|
elif echo "$NODE" | grep -q "cc28"; then
|
|
echo "Labeling $NODE as high-compute pool"
|
|
kubectl label node "$NODE" \
|
|
kubernetes.civo.com/node-pool=high-compute \
|
|
kubernetes.civo.com/node-size=g4c.kube.small --overwrite
|
|
fi
|
|
done
|
|
sleep 30
|
|
done
|
|
resources:
|
|
requests:
|
|
cpu: 10m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 50m
|
|
memory: 64Mi
|