| |
| # Features |
| |
| The sections below cover core features of `containerd`. |
| |
| ## Client |
| |
| containerd offers a full client package to help you integrate containerd into your platform. |
| |
| ```go |
| |
| import ( |
| "context" |
| |
| containerd "github.com/containerd/containerd/v2/client" |
| "github.com/containerd/containerd/v2/pkg/cio" |
| "github.com/containerd/containerd/v2/pkg/namespaces" |
| ) |
| |
| |
| func main() { |
| client, err := containerd.New("/run/containerd/containerd.sock") |
| defer client.Close() |
| } |
| |
| ``` |
| |
| ## Namespaces |
| |
| Namespaces allow multiple consumers to use the same containerd without conflicting with each other. It has the benefit of sharing content while maintaining separation with containers and images. |
| |
| To set a namespace for requests to the API: |
| |
| ```go |
| context = context.Background() |
| // create a context for docker |
| docker = namespaces.WithNamespace(context, "docker") |
| |
| containerd, err := client.NewContainer(docker, "id") |
| ``` |
| |
| To set a default namespace on the client: |
| |
| ```go |
| client, err := containerd.New(address, containerd.WithDefaultNamespace("docker")) |
| ``` |
| |
| ## Distribution |
| |
| ```go |
| // pull an image |
| image, err := client.Pull(context, "docker.io/library/redis:latest") |
| |
| // push an image |
| err := client.Push(context, "docker.io/library/redis:latest", image.Target()) |
| ``` |
| |
| ## Containers |
| |
| In containerd, a container is a metadata object. Resources such as an OCI runtime specification, image, root filesystem, and other metadata can be attached to a container. |
| |
| ```go |
| redis, err := client.NewContainer(context, "redis-master") |
| defer redis.Delete(context) |
| ``` |
| |
| ## OCI Runtime Specification |
| |
| containerd fully supports the OCI runtime specification for running containers. We have built-in functions to help you generate runtime specifications based on images as well as custom parameters. |
| |
| You can specify options when creating a container about how to modify the specification. |
| |
| ```go |
| redis, err := client.NewContainer(context, "redis-master", containerd.WithNewSpec(oci.WithImageConfig(image))) |
| ``` |
| |
| ## Root Filesystems |
| |
| containerd allows you to use overlay or snapshot filesystems with your containers. It comes with built-in support for overlayfs and btrfs. |
| |
| ```go |
| // pull an image and unpack it into the configured snapshotter |
| image, err := client.Pull(context, "docker.io/library/redis:latest", containerd.WithPullUnpack) |
| |
| // allocate a new RW root filesystem for a container based on the image |
| redis, err := client.NewContainer(context, "redis-master", |
| containerd.WithNewSnapshot("redis-rootfs", image), |
| containerd.WithNewSpec(oci.WithImageConfig(image)), |
| ) |
| |
| // use a readonly filesystem with multiple containers |
| for i := 0; i < 10; i++ { |
| id := fmt.Sprintf("id-%s", i) |
| container, err := client.NewContainer(ctx, id, |
| containerd.WithNewSnapshotView(id, image), |
| containerd.WithNewSpec(oci.WithImageConfig(image)), |
| ) |
| } |
| ``` |
| |
| ## Tasks |
| |
| Taking a container object and turning it into a runnable process on a system is done by creating a new `Task` from the container. A task represents the runnable object within containerd. |
| |
| ```go |
| // create a new task |
| task, err := redis.NewTask(context, cio.NewCreator(cio.WithStdio)) |
| defer task.Delete(context) |
| |
| // the task is now running and has a pid that can be used to setup networking |
| // or other runtime settings outside of containerd |
| pid := task.Pid() |
| |
| // start the redis-server process inside the container |
| err := task.Start(context) |
| |
| // wait for the task to exit and get the exit status |
| status, err := task.Wait(context) |
| ``` |
| |
| ## Checkpoint and Restore |
| |
| If you have [criu](https://criu.org/Main_Page) installed on your machine you can checkpoint and restore containers and their tasks. This allows you to clone and/or live migrate containers to other machines. |
| |
| ```go |
| // checkpoint the task then push it to a registry |
| checkpoint, err := task.Checkpoint(context) |
| |
| err := client.Push(context, "myregistry/checkpoints/redis:master", checkpoint) |
| |
| // on a new machine pull the checkpoint and restore the redis container |
| checkpoint, err := client.Pull(context, "myregistry/checkpoints/redis:master") |
| |
| redis, err = client.NewContainer(context, "redis-master", containerd.WithNewSnapshot("redis-rootfs", checkpoint)) |
| defer container.Delete(context) |
| |
| task, err = redis.NewTask(context, cio.NewCreator(cio.WithStdio), containerd.WithTaskCheckpoint(checkpoint)) |
| defer task.Delete(context) |
| |
| err := task.Start(context) |
| ``` |
| |
| ## Snapshot Plugins |
| |
| In addition to the built-in Snapshot plugins in containerd, additional external |
| plugins can be configured using GRPC. An external plugin is made available using |
| the configured name and appears as a plugin alongside the built-in ones. |
| |
| To add an external snapshot plugin, add the plugin to containerd's config file |
| (by default at `/etc/containerd/config.toml`). The string following |
| `proxy_plugin.` will be used as the name of the snapshotter and the address |
| should refer to a socket with a GRPC listener serving containerd's Snapshot |
| GRPC API. Remember to restart containerd for any configuration changes to take |
| effect. |
| |
| ``` |
| [proxy_plugins] |
| [proxy_plugins.customsnapshot] |
| type = "snapshot" |
| address = "/var/run/mysnapshotter.sock" |
| ``` |
| |
| See [PLUGINS.md](PLUGINS.md) for how to create plugins |