infrastructure/node-labeler.yaml
Infrastructure Admin 0dee133377 Add Argo Workflows, mTLS container registry, and fix infrastructure
- 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>
2026-04-07 21:23:12 -04:00

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