When migrating Kubernetes workloads to ACK, moving large numbers of container images is often the bottleneck. Scripts built on docker pull and docker push require disk space proportional to image size, depend on the Docker daemon, and become unwieldy when you need tag filtering or multi-destination sync. image-syncer removes these constraints: it copies images directly between registries using only memory and network bandwidth, with no Docker daemon and no disk storage on the host. The server running image-syncer makes full use of server bandwidth, and there is no disk capacity requirement on the server. The maximum image repository capacity supported is greater than 3 TB.
How it works
image-syncer reads a JSON configuration file that defines authentication credentials and sync rules, then transfers images directly between registries. A single configuration file can define rules that synchronize images from multiple source image repositories to multiple destination image repositories simultaneously. Each run checks which images already exist at the destination and skips them, so re-running the tool is safe. It handles concurrent transfers with configurable parallelism and retries failed tasks automatically to survive network jitter.
image-syncer supports any Docker Registry V2-compatible service, including Alibaba Cloud Container Registry (ACR), Docker Hub, Quay.io, and Harbor. It is used for TB-scale image migration in production environments.
Limitations
Before configuring sync rules, note these constraints:
One sync rule maps one source repository to one destination repository. A single rule cannot sync an entire namespace or registry.
The source repository URL cannot be empty.
When the source URL specifies multiple tags (comma-separated), the destination URL must not include a tag.
Prerequisites
Before you begin, make sure you have:
Network connectivity from the host machine to all source and destination registries
Pull access and tag-listing permissions on all source repositories
Push access and repository-creation permissions on all destination registries
Configure image-syncer
image-syncer uses a JSON configuration file with two top-level fields: auth and images.
Authentication (auth)
The auth field maps each registry URL to its credentials. If a registry requires no authentication, omit it from auth — image-syncer accesses it anonymously.
The registry URL in auth must exactly match the registry hostname used in image URLs.| Field | Required | Type | Default | Description |
|---|---|---|---|---|
username | No | String | — | Username for the registry |
password | No | String | — | Password for the registry |
insecure | No | Boolean | false | Set to true to connect via HTTP instead of HTTPS. Supported in V1.0.1 and later. |
Sync rules (images)
The images field defines sync rules as key-value pairs. The key is the source image URL; the value is the destination image URL. Both follow the format registry/namespace/repository:tag.
Tag behavior depends on how you specify the source URL:
| Source URL | Destination URL | Behavior |
|---|---|---|
| No tag | No tag | All tags in the source repository are synced, keeping original tag names |
Single tag, e.g., :v1 | No tag | Only the image with that tag is synced, keeping the original tag name |
Single tag, e.g., :v1 | With tag, e.g., :stable | Only that image is synced, renamed to the destination tag |
Multiple tags, e.g., :v1,v2,v3 | No tag (required) | Only those tags are synced, keeping original tag names |
| No tag | Empty string "" | All tags are synced to the same-named repository in the default namespace of the default registry |
Configuration file example
{
"auth": {
"quay.io": {
"username": "xxx",
"password": "xxxxxxxxx",
"insecure": true
},
"registry.cn-beijing.aliyuncs.com": {
"username": "xxx",
"password": "xxxxxxxxx"
},
"registry.hub.docker.com": {
"username": "xxx",
"password": "xxxxxxxxxx"
}
},
"images": {
"quay.io/coreos/kube-rbac-proxy": "quay.io/ruohe/kube-rbac-proxy",
"xxxx": "xxxxx",
"xxx/xxx/xx:tag1,tag2,tag3": "xxx/xxx/xx"
}
}Replace the placeholder values with your actual registry URLs, credentials, and image paths.
Run image-syncer
After preparing your configuration file, run image-syncer against it. The tool logs the number of images that fail to sync and provides detailed error output to help you diagnose issues.
For a complete working example, see Synchronize images from a self-managed Harbor project to Container Registry Enterprise Edition.