- 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>
440 lines
11 KiB
YAML
440 lines
11 KiB
YAML
# Argo Workflows namespace
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-namespace
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: argo
|
|
---
|
|
# Argo Workflows ServiceAccount
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-sa
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: argo
|
|
namespace: argo
|
|
---
|
|
# Argo Server ServiceAccount
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-server-sa
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: argo-server
|
|
namespace: argo
|
|
---
|
|
# Argo Workflows ClusterRole
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-cluster-role
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: argo-cluster-role
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: [pods, pods/exec, pods/log]
|
|
verbs: [create, get, list, watch, update, patch, delete]
|
|
- apiGroups: [""]
|
|
resources: [configmaps, secrets, services, serviceaccounts, persistentvolumeclaims, events]
|
|
verbs: [create, get, list, watch, update, patch, delete]
|
|
- apiGroups: [argoproj.io]
|
|
resources: [workflows, workflows/finalizers, workflowtemplates, workflowtemplates/finalizers, clusterworkflowtemplates, clusterworkflowtemplates/finalizers, cronworkflows, cronworkflows/finalizers, workfloweventbindings, workfloweventbindings/finalizers, workflowtaskresults, workflowartifactgctasks]
|
|
verbs: [create, get, list, watch, update, patch, delete]
|
|
- apiGroups: [argoproj.io]
|
|
resources: [workflowtasksets, workflowtasksets/status]
|
|
verbs: [create, get, list, watch, update, patch, delete]
|
|
- apiGroups: [""]
|
|
resources: [events]
|
|
verbs: [create, patch]
|
|
- apiGroups: [coordination.k8s.io]
|
|
resources: [leases]
|
|
verbs: [create, get, update]
|
|
---
|
|
# Argo Server ClusterRole
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-server-cluster-role
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: argo-server-cluster-role
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: [configmaps, events]
|
|
verbs: [get, watch, list]
|
|
- apiGroups: [""]
|
|
resources: [pods, pods/exec, pods/log]
|
|
verbs: [get, list, watch]
|
|
- apiGroups: [""]
|
|
resources: [secrets]
|
|
verbs: [get, list, watch, create]
|
|
- apiGroups: [""]
|
|
resources: [events]
|
|
verbs: [watch, create, patch]
|
|
- apiGroups: [argoproj.io]
|
|
resources: [workflows, workflowtemplates, clusterworkflowtemplates, cronworkflows, workfloweventbindings]
|
|
verbs: [create, get, list, watch, update, patch, delete]
|
|
- apiGroups: [argoproj.io]
|
|
resources: [workflowtasksets]
|
|
verbs: [list, watch]
|
|
---
|
|
# Argo ClusterRoleBinding
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-cluster-role-binding
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: argo-binding
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: argo
|
|
namespace: argo
|
|
roleRef:
|
|
kind: ClusterRole
|
|
name: argo-cluster-role
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
# Argo Server ClusterRoleBinding
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-server-cluster-role-binding
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: argo-server-binding
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: argo-server
|
|
namespace: argo
|
|
roleRef:
|
|
kind: ClusterRole
|
|
name: argo-server-cluster-role
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
# Default workflow ServiceAccount (used by workflows themselves)
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-sa
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: argo-workflow
|
|
namespace: argo
|
|
---
|
|
# Workflow role - what workflows can do
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-role
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata:
|
|
name: argo-workflow-role
|
|
namespace: argo
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: [pods]
|
|
verbs: [get, watch, patch]
|
|
- apiGroups: [""]
|
|
resources: [pods/log]
|
|
verbs: [get, watch]
|
|
- apiGroups: [argoproj.io]
|
|
resources: [workflowtaskresults]
|
|
verbs: [create, patch]
|
|
---
|
|
# Workflow RoleBinding
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-role-binding
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: argo-workflow-binding
|
|
namespace: argo
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: argo-workflow
|
|
namespace: argo
|
|
roleRef:
|
|
kind: Role
|
|
name: argo-workflow-role
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
# Workflow Controller ConfigMap
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-controller-configmap
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: workflow-controller-configmap
|
|
namespace: argo
|
|
data:
|
|
config: |
|
|
workflowDefaults:
|
|
spec:
|
|
serviceAccountName: argo-workflow
|
|
imagePullSecrets:
|
|
- name: forgejo-registry
|
|
nodeSelector:
|
|
kubernetes.civo.com/node-pool: high-compute
|
|
tolerations:
|
|
- key: "kubernetes.civo.com/node-pool"
|
|
operator: "Equal"
|
|
value: "high-compute"
|
|
effect: "NoSchedule"
|
|
metricsConfig:
|
|
enabled: true
|
|
path: /metrics
|
|
port: 9090
|
|
---
|
|
# Workflow Controller Deployment
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-controller
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: workflow-controller
|
|
namespace: argo
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: workflow-controller
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: workflow-controller
|
|
spec:
|
|
serviceAccountName: argo
|
|
containers:
|
|
- name: workflow-controller
|
|
image: quay.io/argoproj/workflow-controller:v3.6.7
|
|
args:
|
|
- --configmap
|
|
- workflow-controller-configmap
|
|
- --executor-image
|
|
- quay.io/argoproj/argoexec:v3.6.7
|
|
- --loglevel
|
|
- info
|
|
env:
|
|
- name: LEADER_ELECTION_IDENTITY
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.name
|
|
ports:
|
|
- containerPort: 9090
|
|
name: metrics
|
|
- containerPort: 6060
|
|
name: pprof
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 128Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 6060
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 6060
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
---
|
|
# Workflow Controller Metrics Service
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-workflow-controller-metrics
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: workflow-controller-metrics
|
|
namespace: argo
|
|
spec:
|
|
selector:
|
|
app: workflow-controller
|
|
ports:
|
|
- name: metrics
|
|
port: 9090
|
|
targetPort: 9090
|
|
type: ClusterIP
|
|
---
|
|
# Argo Server Deployment
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-server-deployment
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: argo-server
|
|
namespace: argo
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: argo-server
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: argo-server
|
|
spec:
|
|
serviceAccountName: argo-server
|
|
containers:
|
|
- name: argo-server
|
|
image: quay.io/argoproj/argocli:v3.6.7
|
|
args:
|
|
- server
|
|
- --auth-mode=server
|
|
- --secure=false
|
|
ports:
|
|
- containerPort: 2746
|
|
name: web
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 128Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 256Mi
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 2746
|
|
scheme: HTTP
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
---
|
|
# Argo Server Service
|
|
apiVersion: kubernetes.crossplane.io/v1alpha2
|
|
kind: Object
|
|
metadata:
|
|
name: argo-server-service
|
|
namespace: crossplane-system
|
|
spec:
|
|
providerConfigRef:
|
|
name: kubernetes-provider
|
|
forProvider:
|
|
manifest:
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: argo-server
|
|
namespace: argo
|
|
spec:
|
|
selector:
|
|
app: argo-server
|
|
ports:
|
|
- name: web
|
|
port: 2746
|
|
targetPort: 2746
|
|
type: ClusterIP
|