Pool Provisioning¶
Overview¶
The NextcloudPool CRD enables fast tenant onboarding by maintaining a pool of pre-provisioned, unassigned NextcloudInstances. When a tenant creates a Nextcloud resource, the operator assigns an existing instance from the pool (~30s) instead of creating one from scratch (~2min).
Architecture¶
┌────────────────────────────────────────────────────────────┐
│ Cluster-Scoped │
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ NextcloudPool │ │ NextcloudPool │ │
│ │ production │ │ development │ │
│ │ │ │ │ │
│ │ spec: │ │ spec: │ │
│ │ replicas: 5 │ │ replicas: 2 │ │
│ │ profile: prod │ │ profile: dev │ │
│ │ │ │ │ │
│ │ status: │ │ status: │ │
│ │ ready: 5 │ │ ready: 2 │ │
│ │ assigned: 0 │ │ assigned: 0 │ │
│ └──────────────────────┘ └──────────────────────┘ │
└────────────────────────────────────────────────────────────┘
│ │
│ manages │ manages
▼ ▼
┌────────────────────────────────────────────────────────────┐
│ Instance Namespaces │
│ │
│ Pool instances (unassigned): │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ NextcloudInstance │ │ NextcloudInstance │ │
│ │ nc-brave-lake-g7h8i9 │ │ nc-quiet-hill-j0k1l2│ │
│ │ labels: │ │ labels: │ │
│ │ assigned: "false" │ │ assigned: "false" │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ Assigned instances: │
│ ┌──────────────────────┐ │
│ │ NextcloudInstance │ │
│ │ nc-happy-sun-a1b2c3 │ │
│ │ labels: │ │
│ │ assigned: "true" │ │
│ │ tenant: acme-corp │ │
│ └──────────────────────┘ │
└────────────────────────────────────────────────────────────┘
How It Works¶
Pool-Based Assignment Flow¶
1. Tenant creates Nextcloud CR
└─> kubectl apply -f nextcloud.yaml
2. Operator checks poolSelector
└─> spec.poolSelector.matchLabels: {pool: "production"}
3. Operator finds matching unassigned instance
└─> Labels: {assigned: "false", pool: "production"}
└─> Found: nc-brave-lake-g7h8i9
4. Operator assigns instance
├─> Updates NextcloudInstance labels (assigned: "true")
├─> Copies Nextcloud.spec to NextcloudInstance.spec
└─> Updates Nextcloud.status.instanceRef
5. NextcloudInstance reconciles with new spec
└─> Updates HelmRelease, Secrets, etc.
6. Pool operator detects assignment
└─> Creates new unassigned instance to maintain pool size
Fresh Instance Creation (No Pool)¶
If no poolSelector is specified or no matching instances are available:
1. Operator creates fresh NextcloudInstance
2. Copies entire spec from Nextcloud
3. NextcloudInstance creates all resources (~2min)
Creating a Pool¶
apiVersion: k8s.bnerd.com/v1alpha1
kind: NextcloudPool
metadata:
name: production
spec:
replicas: 5
instanceNamespacePattern: "*"
template:
metadata:
labels:
pool: production
spec:
profile: production
database:
managed: true
type: postgresql
lifecycle:
recreateOnProfileChange: true
maxUnassignedAge: "168h" # 7 days
reclaimPolicy: Delete
Using a Pool¶
Create a Nextcloud resource with a poolSelector:
apiVersion: k8s.bnerd.com/v1alpha1
kind: Nextcloud
metadata:
name: tenant-cloud
namespace: tenant-acme
spec:
poolSelector:
matchLabels:
pool: production
ingress:
host: cloud.acme-corp.example.com
tls:
enabled: true
# Additional spec fields are applied to the assigned instance
Pool Status¶
The pool status shows instance counts:
status:
phase: Ready
replicas: 5
ready: 5
unassigned: 4
assigned: 1
instances:
- name: nc-brave-lake-g7h8i9
phase: Ready
assigned: false
- name: nc-happy-sun-a1b2c3
phase: Ready
assigned: true
Status Phases¶
NextcloudPool: Pending -> Scaling -> Ready | Failed
Nextcloud (logical): Pending -> Assigning -> Configuring -> Ready | Failed
Instance Naming¶
Pool instances use a human-readable naming convention:
Format: nc-{adjective}-{noun}-{random}
Examples: nc-happy-sun-a1b2c3, nc-calm-moon-d4e5f6, nc-brave-lake-g7h8i9
This provides memorable names for support conversations while avoiding collisions.
Lifecycle Policies¶
| Policy | Description |
|---|---|
recreateOnProfileChange |
Recreate unassigned instances when the pool profile changes |
maxUnassignedAge |
Maximum time an instance can stay unassigned before cleanup (e.g., 168h) |
reclaimPolicy |
What happens to the instance when the Nextcloud is deleted: Delete or Retain |
Status Synchronization¶
The operator keeps the Nextcloud and NextcloudInstance status in sync:
Nextcloud.spec ──────────────► NextcloudInstance.spec
(propagation)
Nextcloud.status ◄──────────── NextcloudInstance.status
(sync back)
Fields synced back: phase, helmRelease, url, version, conditions
Drift Reconciliation¶
If a NextcloudInstance is modified directly, the operator detects drift during the 30-second timer reconciliation and overwrites the instance spec with the Nextcloud spec. Manual changes to assigned instances are not preserved.