Merge pull request #10730 from mxpv/features
Move features section to a separate file
This commit is contained in:
		
							
								
								
									
										160
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								README.md
									
									
									
									
									
								
							| @@ -89,164 +89,8 @@ For configuring registries, see [registry host configuration documentation](docs | |||||||
|  |  | ||||||
| ## Features | ## Features | ||||||
|  |  | ||||||
| ### Client | For a detailed overview of containerd's core concepts and the features it supports, | ||||||
|  | please refer to the [FEATURES.MD](./docs/features.md) document. | ||||||
| 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](/docs/PLUGINS.md) for how to create plugins |  | ||||||
|  |  | ||||||
| ### Releases and API Stability | ### Releases and API Stability | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										163
									
								
								docs/features.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								docs/features.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | |||||||
|  |  | ||||||
|  | # 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 | ||||||
		Reference in New Issue
	
	Block a user
	 Maksym Pavlenko
					Maksym Pavlenko