Skip to content

Cluster Migration

Skipper can migrate entire projects (apps, services, databases with data, volumes, functions, jobs, and secrets) from one cluster to another. No kubectl, no manual exports.

When to use migration

  • Moving from an old server to a new one
  • Upgrading hardware (bigger server, different provider)
  • Splitting a cluster (move some projects to a separate server)
  • Disaster recovery (restore from a running cluster to a new one)

How it works

Migration is a console feature with visual progress. The flow:

  1. Generate token on the new cluster (target)
  2. Paste token on the old cluster (source), select projects
  3. Watch progress as data transfers automatically
  4. Verify apps on temporary URLs before touching DNS
  5. Cutover custom domains and update DNS

What gets migrated

ResourceHow
Project CRsCreated on target, namespaces auto-provisioned
Kubernetes SecretsTransferred directly (credentials, env vars, registry auth)
Service CRsCreated on target, StatefulSets auto-provisioned
Database dataExported via pg_dumpall / mysqldump / mongodump, imported on target
Redis dataRDB snapshot transferred
RabbitMQ definitionsExported and imported via rabbitmqctl
VolumesPVC data tarred, transferred, extracted on target
Container imagesManifests transferred between Zot registries
App CRsCreated on target with temporary routes
Function CRsCreated on target
Job CRsCreated on target
Custom domain routesApplied after user verifies apps work

What is NOT migrated

  • System components (Traefik, cert-manager, Longhorn, Dex), which already exist on the target from kip install
  • TLS certificates, because cert-manager issues new ones on the target
  • Build history (only the current image is migrated)
  • Pod logs (ephemeral by nature)

Step-by-step guide

1. Prepare the target cluster

Install Skipper on the new server:

bash
kip install --host 203.0.113.20

The target cluster should be running with no projects deployed (or projects that don't conflict with what you're migrating).

2. Generate a migration token

On the target cluster's console, go to Migration and click Receive from another cluster. Copy the generated token.

The token is valid for 24 hours and can only be used once.

3. Start the migration

On the source cluster's console, go to Migration and click Migrate to another cluster. Paste the token and select which projects to migrate.

If a project already exists on the target, you'll be asked to confirm the overwrite by typing the project name.

Click Start migration.

4. Monitor progress

The migration view shows:

  • Two cluster icons with animated data flow indicators
  • A step-by-step list with checkmarks, spinners, and progress counters
  • A detail panel showing the current operation

Typical steps:

  1. Creating project on target
  2. Waiting for namespaces
  3. Transferring secrets
  4. Creating services and waiting for databases to start
  5. Exporting and importing database data
  6. Transferring volume data
  7. Transferring container images
  8. Creating apps (with temporary URLs)
  9. Verifying health

5. Verify your apps

After migration completes, apps are live on temporary *.kipper.run subdomains. The verification dashboard shows each app with its temporary URL and status.

Click each URL to verify the app works correctly. Check that pages load, database connections work, and functionality is intact.

6. Apply custom domains

When everything looks good, click Everything looks good, apply custom domains. Skipper applies the original route configuration and shows DNS update instructions.

Update your DNS records to point to the new server's IP address. Skipper checks DNS propagation automatically and shows resolved/pending status for each domain.

Limitations

  • Database size: Databases up to ~500MB transfer in a single request. Larger databases may need manual migration.
  • OpenSearch and MinIO: Data transfer for these services is not yet automated. Migrate data manually after the project structure is created.
  • Build artifacts: Only the latest container image is transferred, not the full build cache.
  • Active connections: Apps on the source cluster continue running during migration. There is no automatic traffic cutover. DNS changes propagate gradually.

Troubleshooting

Migration token expired

Tokens are valid for 24 hours. Generate a new one on the target cluster.

Target cluster unreachable

The source cluster connects to the target's console-api over HTTPS. Ensure the target's console URL is accessible from the source server (no firewall blocking outbound HTTPS).

Database import failed

If the database import fails, the Service CR still exists on the target. You can manually export and import the data:

bash
# On source: export
kubectl exec -n <namespace> <pod> -- pg_dumpall -U skipper > dump.sql

# Copy to target server and import
kubectl exec -i -n <namespace> <pod> -- psql -U skipper -d app < dump.sql

Apps stuck in pending

After migration, apps need time to pull container images and start. Check the target cluster's console for pod status and logs.

Released under the Apache 2.0 License.