Skip to content

Add docs and tests for Transfer Service #2084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:
builtin: ["true", "false"]
metadata-store: ["memory", "db"]
fuse-passthrough: ["true", "false"]
transfer-service: ["true", "false"]
exclude:
- buildargs: ""
builtin: "true"
Expand All @@ -69,6 +70,14 @@ jobs:
buildargs: "--build-arg=CONTAINERD_VERSION=main"
- fuse-passthrough: "true"
metadata-store: "db"
- transfer-service: "true"
buildargs: "--build-arg=CONTAINERD_VERSION=main"
- transfer-service: "true"
builtin: "true"
- transfer-service: "true"
metadata-store: "db"
- transfer-service: "true"
fuse-passthrough: "true"
steps:
- name: Install htpasswd for setting up private registry
run: sudo apt-get update -y && sudo apt-get --no-install-recommends install -y apache2-utils
Expand All @@ -79,6 +88,7 @@ jobs:
BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }}
METADATA_STORE: ${{ matrix.metadata-store }}
FUSE_PASSTHROUGH: ${{ matrix.fuse-passthrough }}
TRANSFER_SERVICE: ${{ matrix.transfer-service }}
run: make integration

test-optimize:
Expand Down Expand Up @@ -149,6 +159,7 @@ jobs:
builtin: ["true", "false"]
metadata-store: ["memory", "db"]
fuse-passthrough: ["true", "false"]
transfer-service: ["true", "false"]
exclude:
- buildargs: ""
builtin: "true"
Expand All @@ -162,6 +173,14 @@ jobs:
buildargs: "--build-arg=CONTAINERD_VERSION=main"
- fuse-passthrough: "true"
metadata-store: "db"
- transfer-service: "true"
buildargs: "--build-arg=CONTAINERD_VERSION=main"
- transfer-service: "true"
builtin: "true"
- transfer-service: "true"
metadata-store: "db"
- transfer-service: "true"
fuse-passthrough: "true"
steps:
- uses: actions/checkout@v4
- name: Validate containerd through CRI
Expand All @@ -170,6 +189,7 @@ jobs:
BUILTIN_SNAPSHOTTER: ${{ matrix.builtin }}
METADATA_STORE: ${{ matrix.metadata-store }}
FUSE_PASSTHROUGH: ${{ matrix.fuse-passthrough }}
TRANSFER_SERVICE: ${{ matrix.transfer-service }}
run: make test-cri-containerd

test-cri-cri-o:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ARG NETAVARK_VERSION=v1.13.0

ARG CONTAINERIZED_SYSTEMD_VERSION=v0.1.1
ARG SLIRP4NETNS_VERSION=v1.3.1
ARG PAUSE_IMAGE_NAME_TEST=registry.k8s.io/pause:3.10
ARG PAUSE_IMAGE_NAME_TEST=registry.k8s.io/pause:3.10.1

# Used in CI
ARG CRI_TOOLS_VERSION=v1.30.1
Expand Down
99 changes: 99 additions & 0 deletions docs/transfer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Enabling Stargz Snapshotter With Transfer Service

Transfer Service is a containerd component which is used for image management in contianerd (e.g. pulling and pushing images).
For details about Transfer Service, refer to [the official document in the containerd repo](https://github.com/containerd/containerd/blob/6af7c07905a317d4c343a49255e2392f4c8569f9/docs/transfer.md).

To use Stargz Snapshotter on containerd with enabling Transfer Service, additional configurations is needed.

## Availability of Transfer Service

Transfer Service is available since v1.7.
And this is enabled in different settings depending on the containerd version.

|containerd version|`ctr`|CRI|
---|---|---
|containerd >= v1.7 and < v2.0|Disabled by default. Enabled by `--local=false`|Disabled|
|containerd >= v2.0 and < v2.1|Enabled by default. Disabled by `--local`|Disabled|
|containerd >= v2.1|Enabled by default. Disabled by `--local`|Enabled by default. Disabled when conditions described in [containerd's CRI document](https://github.com/containerd/containerd/blob/v2.1.0/docs/cri/config.md#image-pull-configuration-since-containerd-v21) are met|

### Note about containerd v2.1

Before containerd v2.1, `disable_snapshot_annotations = false` in containerd's config TOML was a mandatory field to enable Stargz Snapshotter in CRI.
In containerd v2.1, `disable_snapshot_annotations = false` field can still be used to enable Stargz Snapshotter and containerd disables Transfer Service when this field is detected.
If you want to enable Transfer Service, you need to remove `disable_snapshot_annotations = false` field and apply the configuration explaind in this document.

## How to enable Stargz Snapshotter when Transfer Service is enabled?

In containerd v2.1, Transfer Service added support for remote snapshotters like Stargz Snapshotter.

### For ctr and other non-CRI clients

To enable Stargz Snapshotter with Transfer Service, you need to start containerd-stargz-grpc on the node and add the following configuration to contianerd's config TOML file.
Note that you need to add a field `enable_remote_snapshot_annotations = "true"` in `proxy_plugins.stargz.exports` so that containerd can correctly pass image-related information to Stargz Snapshotter.

```toml
version = 2

# Enable Stargz Snapshotter in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "stargz"

# Plugin Stargz Snapshotter
[proxy_plugins]
[proxy_plugins.stargz]
type = "snapshot"
address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock"
[proxy_plugins.stargz.exports]
root = "/var/lib/containerd-stargz-grpc/"
enable_remote_snapshot_annotations = "true"
```

#### Example client command

When you enable Transfer Service with Stargz Snapshotter, you can perform lazy pulling using the normal `ctr` command. (of course, `ctr-remote` can still be used)

```
# ctr image pull --snapshotter=stargz ghcr.io/stargz-containers/ubuntu:24.04-esgz
```

Then `mount | grep stargz` prints stargz mounts on the node.

### For CRI

To enable Stargz Snapshotter with Transfer Service, you need to start containerd-stargz-grpc on the node and add the following configuration to contianerd's config TOML file.

```toml
version = 2

# Basic CRI configuration with enabling Stargz Snapshotter
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
snapshotter = "stargz"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"

# Enable Stargz Snapshotter in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "stargz"

# Plugin Stargz Snapshotter
[proxy_plugins]
[proxy_plugins.stargz]
type = "snapshot"
address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock"
[proxy_plugins.stargz.exports]
root = "/var/lib/containerd-stargz-grpc/"
enable_remote_snapshot_annotations = "true"
```

#### Example client command

You can quickly check the behaviour using `crictl` command.

```
# crictl image pull ghcr.io/stargz-containers/ubuntu:24.04-esgz
```

Then `mount | grep stargz` prints stargz mounts on the node.
26 changes: 26 additions & 0 deletions script/cri-containerd/config.containerd.transfer.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version = 2

# Basic CRI configuration with enabling Stargz Snapshotter
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
snapshotter = "stargz"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"

# Enable Stargz Snapshotter in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "stargz"
# Enable overlayfs in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "overlayfs"

# Plugin Stargz Snapshotter
[proxy_plugins]
[proxy_plugins.stargz]
type = "snapshot"
address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock"
[proxy_plugins.stargz.exports]
root = "/var/lib/containerd-stargz-grpc/"
enable_remote_snapshot_annotations = "true"
11 changes: 8 additions & 3 deletions script/cri-containerd/test-stargz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,16 @@ docker exec "${PREPARE_NODE_NAME}" /bin/bash /tools/mirror.sh
# Configure mirror registries for containerd and snapshotter
docker exec "${TEST_NODE_NAME}" cat /etc/containerd/config.toml > "${CONTAINERD_CONFIG}"
docker exec "${TEST_NODE_NAME}" cat /etc/containerd-stargz-grpc/config.toml > "${SNAPSHOTTER_CONFIG}"
docker exec "${TEST_NODE_NAME}" mkdir -p "/etc/containerd/certs.d"
cat <<EOF >> "${CONTAINERD_CONFIG}"
[plugins."io.containerd.cri.v1.images".registry]
config_path = "/etc/containerd/certs.d"
EOF
cat "${IMAGE_LIST}" | sed -E 's/^([^/]*).*/\1/g' | sort | uniq | while read DOMAIN ; do
echo "Adding mirror config: ${DOMAIN}"
cat <<EOF >> "${CONTAINERD_CONFIG}"
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."${DOMAIN}"]
endpoint = ["http://${REGISTRY_HOST}:5000"]
docker exec "${TEST_NODE_NAME}" mkdir -p "/etc/containerd/certs.d/${DOMAIN}/"
cat <<EOF | docker exec -i "${TEST_NODE_NAME}" tee -a "/etc/containerd/certs.d/${DOMAIN}/hosts.toml"
server = "http://${REGISTRY_HOST}:5000"
EOF
if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then
cat <<EOF >> "${CONTAINERD_CONFIG}"
Expand Down
12 changes: 9 additions & 3 deletions script/cri-containerd/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function cleanup {
}
trap 'cleanup "$?"' EXIT SIGHUP SIGINT SIGQUIT SIGTERM

BUILTIN_HACK_INST=
ADDITIONAL_INST=
if [ "${BUILTIN_SNAPSHOTTER:-}" == "true" ] ; then
# Special configuration for CRI containerd + builtin stargz snapshotter
cat <<EOF > "${TMP_CONTEXT}/containerd.hack.toml"
Expand All @@ -75,7 +75,7 @@ metadata_store = "memory"
[plugins."io.containerd.snapshotter.v1.stargz".cri_keychain]
enable_keychain = true
EOF
BUILTIN_HACK_INST="COPY containerd.hack.toml /etc/containerd/config.toml"
ADDITIONAL_INST="COPY containerd.hack.toml /etc/containerd/config.toml"
fi

cat <<EOF > "${TMP_CONTEXT}/test.conflist"
Expand Down Expand Up @@ -128,6 +128,12 @@ if [ "${FUSE_PASSTHROUGH:-}" != "" ] ; then
fi
fi

if [ "${TRANSFER_SERVICE:-}" == "true" ] ; then
cp "${CONTEXT}/config.containerd.transfer.toml" "${TMP_CONTEXT}/"
ADDITIONAL_INST="${ADDITIONAL_INST}
COPY config.containerd.transfer.toml /etc/containerd/config.toml"
fi

# Prepare the testing node
cat <<EOF > "${TMP_CONTEXT}/Dockerfile"
# Legacy builder that doesn't support TARGETARCH should set this explicitly using --build-arg.
Expand All @@ -152,7 +158,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends make && \

COPY ./test.conflist /etc/cni/net.d/test.conflist

${BUILTIN_HACK_INST}
${ADDITIONAL_INST}

RUN if [ "${BUILTIN_SNAPSHOTTER:-}" != "true" ] ; then \
sed -i '1imetadata_store = "${USE_METADATA_STORE}"' "${SNAPSHOTTER_CONFIG_FILE}" && \
Expand Down
10 changes: 10 additions & 0 deletions script/integration/containerd/config.containerd.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ check_always = true

[plugins."io.containerd.snapshotter.v1.stargz".registry.mirrors."registry-integration.test"]
endpoint = ["http://registry-alt.test:5000"]

# Enable Stargz Snapshotter in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "stargz"

# Enable overlayfs in Transfer Service
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
platform = "linux"
snapshotter = "overlayfs"
Loading
Loading