provisioning/schemas/platform/templates/kubernetes/orchestrator-deployment.yaml.ncl
Jesús Pérez 44648e3206
chore: complete nickel migration and consolidate legacy configs
- Remove KCL ecosystem (~220 files deleted)
- Migrate all infrastructure to Nickel schema system
- Consolidate documentation: legacy docs → provisioning/docs/src/
- Add CI/CD workflows (.github/) and Rust build config (.cargo/)
- Update core system for Nickel schema parsing
- Update README.md and CHANGES.md for v5.0.0 release
- Fix pre-commit hooks: end-of-file, trailing-whitespace
- Breaking changes: KCL workspaces require migration
- Migration bridge available in docs/src/development/
2026-01-08 09:55:37 +00:00

285 lines
7.7 KiB
Plaintext

# Orchestrator Kubernetes Deployment
# Supports 4 deployment modes: solo, multiuser, cicd, enterprise
# Exports to YAML via: nickel export --format json | yq -P
#
# Usage:
# nickel eval --format json orchestrator-deployment.yaml.ncl | yq -P > orchestrator-deployment.yaml
# kubectl apply -f orchestrator-deployment.yaml
{
apiVersion = "apps/v1",
kind = "Deployment",
metadata = {
name = "orchestrator",
labels = {
app = "orchestrator",
component = "provisioning-platform",
},
},
spec = {
# Solo: 1 replica (single developer)
# MultiUser: 1 replica (team development)
# CI/CD: 1 replica (stateless, ephemeral)
# Enterprise: 3 replicas (HA with load balancing)
replicas = 3, # Override per mode
selector = {
matchLabels = {
app = "orchestrator",
},
},
template = {
metadata = {
labels = {
app = "orchestrator",
component = "provisioning-platform",
},
annotations = {
"prometheus.io/scrape" = "true",
"prometheus.io/port" = "9090",
"prometheus.io/path" = "/metrics",
},
},
spec = {
# Service account for orchestrator
serviceAccountName = "orchestrator",
# Init container: wait for dependencies
initContainers = [
{
name = "wait-for-storage",
image = "busybox:1.35",
command = ["sh", "-c", "until wget -q http://storage-service:8000/health || true; do echo waiting; sleep 2; done"],
imagePullPolicy = "IfNotPresent",
},
],
containers = [
{
name = "orchestrator",
image = "provisioning-orchestrator:latest",
imagePullPolicy = "Always",
ports = [
{
name = "http",
containerPort = 9090,
protocol = "TCP",
},
{
name = "metrics",
containerPort = 9091,
protocol = "TCP",
},
],
env = [
{
name = "ORCHESTRATOR_MODE",
value = "kubernetes",
},
{
name = "ORCHESTRATOR_SERVER_HOST",
value = "0.0.0.0",
},
{
name = "ORCHESTRATOR_SERVER_PORT",
value = "9090",
},
{
name = "ORCHESTRATOR_STORAGE_BACKEND",
valueFrom = {
configMapKeyRef = {
name = "orchestrator-config",
key = "storage_backend",
},
},
},
{
name = "ORCHESTRATOR_STORAGE_PATH",
value = "/var/lib/provisioning/orchestrator/data",
},
{
name = "ORCHESTRATOR_QUEUE_MAX_CONCURRENT_TASKS",
valueFrom = {
configMapKeyRef = {
name = "orchestrator-config",
key = "max_concurrent_tasks",
},
},
},
{
name = "ORCHESTRATOR_BATCH_PARALLEL_LIMIT",
valueFrom = {
configMapKeyRef = {
name = "orchestrator-config",
key = "batch_parallel_limit",
},
},
},
{
name = "ORCHESTRATOR_LOG_LEVEL",
valueFrom = {
configMapKeyRef = {
name = "orchestrator-config",
key = "log_level",
},
},
},
{
name = "POD_NAME",
valueFrom = {
fieldRef = {
fieldPath = "metadata.name",
},
},
},
{
name = "POD_NAMESPACE",
valueFrom = {
fieldRef = {
fieldPath = "metadata.namespace",
},
},
},
],
# Health check: HTTP GET /health on port 9090
livenessProbe = {
httpGet = {
path = "/health",
port = 9090,
},
initialDelaySeconds = 30,
periodSeconds = 10,
timeoutSeconds = 5,
failureThreshold = 3,
},
# Startup check: ensure service is ready
readinessProbe = {
httpGet = {
path = "/health",
port = 9090,
},
initialDelaySeconds = 20,
periodSeconds = 5,
timeoutSeconds = 3,
failureThreshold = 3,
},
# Resource management
resources = {
requests = {
cpu = "500m", # Minimum 0.5 CPU
memory = "512Mi", # Minimum 512MB
},
limits = {
cpu = "2", # Maximum 2 CPUs
memory = "2Gi", # Maximum 2GB
},
},
# Volume mounts
volumeMounts = [
{
name = "orchestrator-data",
mountPath = "/var/lib/provisioning/orchestrator/data",
},
{
name = "orchestrator-logs",
mountPath = "/var/log/provisioning/orchestrator",
},
],
# Security context
securityContext = {
allowPrivilegeEscalation = false,
runAsNonRoot = true,
runAsUser = 1000,
capabilities = {
drop = ["ALL"],
},
},
},
],
# Volumes
volumes = [
{
name = "orchestrator-data",
persistentVolumeClaim = {
claimName = "orchestrator-data",
},
},
{
name = "orchestrator-logs",
persistentVolumeClaim = {
claimName = "orchestrator-logs",
},
},
],
# Pod affinity for distributed deployment (enterprise mode)
affinity = {
podAntiAffinity = {
preferredDuringSchedulingIgnoredDuringExecution = [
{
weight = 100,
podAffinityTerm = {
labelSelector = {
matchExpressions = [
{
key = "app",
operator = "In",
values = ["orchestrator"],
},
],
},
topologyKey = "kubernetes.io/hostname",
},
},
],
},
},
# Tolerations for node failures
tolerations = [
{
key = "node.kubernetes.io/not-ready",
operator = "Exists",
effect = "NoExecute",
tolerationSeconds = 300,
},
{
key = "node.kubernetes.io/unreachable",
operator = "Exists",
effect = "NoExecute",
tolerationSeconds = 300,
},
],
# Restart policy
restartPolicy = "Always",
# Termination grace period
terminationGracePeriodSeconds = 30,
},
},
# Deployment strategy
strategy = {
type = "RollingUpdate",
rollingUpdate = {
maxSurge = 1,
maxUnavailable = 0,
},
},
# Rollback configuration
revisionHistoryLimit = 5,
},
}