github.com/containerd/Containerd@v1.4.13/PLUGINS.md (about) 1 # containerd Plugins 2 3 containerd supports extending its functionality using most of its defined 4 interfaces. This includes using a customized runtime, snapshotter, content 5 store, and even adding gRPC interfaces. 6 7 ## Smart Client Model 8 9 containerd has a smart client architecture, meaning any functionality which is 10 not required by the daemon is done by the client. This includes most high 11 level interactions such as creating a container's specification, interacting 12 with an image registry, or loading an image from tar. containerd's Go client 13 gives a user access to many points of extensions from creating their own 14 options on container creation to resolving image registry names. 15 16 See [containerd's Go documentation](https://godoc.org/github.com/containerd/containerd) 17 18 ## External Plugins 19 20 External plugins allow extending containerd's functionality using an officially 21 released version of containerd without needing to recompile the daemon to add a 22 plugin. 23 24 containerd allows extensions through two method: 25 - via a binary available in containerd's PATH 26 - by configuring containerd to proxy to another gRPC service 27 28 ### V2 Runtimes 29 30 The runtime v2 interface allows resolving runtimes to binaries on the system. 31 These binaries are used to start the shim process for containerd and allows 32 containerd to manage those containers using the runtime shim api returned by 33 the binary. 34 35 See [runtime v2 documentation](runtime/v2/README.md) 36 37 ### Proxy Plugins 38 39 A proxy plugin is configured using containerd's config file and will be loaded 40 alongside the internal plugins when containerd is started. These plugins are 41 connected to containerd using a local socket serving one of containerd's gRPC 42 API services. Each plugin is configured with a type and name just as internal 43 plugins are. 44 45 #### Configuration 46 47 Update the containerd config file, which by default is at 48 `/etc/containerd/config.toml`. Add a `[proxy_plugins]` section along with a 49 section for your given plugin `[proxy_plugins.myplugin]`. The `address` must 50 refer to a local socket file which the containerd process has access to. The 51 currently supported types are `snapshot` and `content`. 52 53 ``` 54 [proxy_plugins] 55 [proxy_plugins.customsnapshot] 56 type = "snapshot" 57 address = "/var/run/mysnapshotter.sock" 58 ``` 59 60 #### Implementation 61 62 Implementing a proxy plugin is as easy as implementing the gRPC API for a 63 service. For implementing a proxy plugin in Go, look at the go doc for 64 [content store service](https://godoc.org/github.com/containerd/containerd/api/services/content/v1#ContentServer) 65 and [snapshotter service](https://godoc.org/github.com/containerd/containerd/api/services/snapshots/v1#SnapshotsServer). 66 67 The following example creates a snapshot plugin binary which can be used 68 with any implementation of 69 [containerd's Snapshotter interface](https://godoc.org/github.com/containerd/containerd/snapshots#Snapshotter) 70 ```go 71 package main 72 73 import ( 74 "fmt" 75 "net" 76 "os" 77 78 "google.golang.org/grpc" 79 80 snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" 81 "github.com/containerd/containerd/contrib/snapshotservice" 82 "github.com/containerd/containerd/snapshots/native" 83 ) 84 85 func main() { 86 // Provide a unix address to listen to, this will be the `address` 87 // in the `proxy_plugin` configuration. 88 // The root will be used to store the snapshots. 89 if len(os.Args) < 3 { 90 fmt.Printf("invalid args: usage: %s <unix addr> <root>\n", os.Args[0]) 91 os.Exit(1) 92 } 93 94 // Create a gRPC server 95 rpc := grpc.NewServer() 96 97 // Configure your custom snapshotter, this example uses the native 98 // snapshotter and a root directory. Your custom snapshotter will be 99 // much more useful than using a snapshotter which is already included. 100 // https://godoc.org/github.com/containerd/containerd/snapshots#Snapshotter 101 sn, err := native.NewSnapshotter(os.Args[2]) 102 if err != nil { 103 fmt.Printf("error: %v\n", err) 104 os.Exit(1) 105 } 106 107 // Convert the snapshotter to a gRPC service, 108 // example in github.com/containerd/containerd/contrib/snapshotservice 109 service := snapshotservice.FromSnapshotter(sn) 110 111 // Register the service with the gRPC server 112 snapshotsapi.RegisterSnapshotsServer(rpc, service) 113 114 // Listen and serve 115 l, err := net.Listen("unix", os.Args[1]) 116 if err != nil { 117 fmt.Printf("error: %v\n", err) 118 os.Exit(1) 119 } 120 if err := rpc.Serve(l); err != nil { 121 fmt.Printf("error: %v\n", err) 122 os.Exit(1) 123 } 124 } 125 ``` 126 127 Using the previous configuration and example, you could run a snapshot plugin 128 with 129 ``` 130 # Start plugin in one terminal 131 $ go run ./main.go /var/run/mysnapshotter.sock /tmp/snapshots 132 133 # Use ctr in another 134 $ CONTAINERD_SNAPSHOTTER=customsnapshot ctr images pull docker.io/library/alpine:latest 135 $ tree -L 3 /tmp/snapshots 136 /tmp/snapshots 137 |-- metadata.db 138 `-- snapshots 139 `-- 1 140 |-- bin 141 |-- dev 142 |-- etc 143 |-- home 144 |-- lib 145 |-- media 146 |-- mnt 147 |-- proc 148 |-- root 149 |-- run 150 |-- sbin 151 |-- srv 152 |-- sys 153 |-- tmp 154 |-- usr 155 `-- var 156 157 18 directories, 1 file 158 ``` 159 160 ## Built-in Plugins 161 162 containerd uses plugins internally to ensure that internal implementations are 163 decoupled, stable, and treated equally with external plugins. To see all the 164 plugins containerd has, use `ctr plugins ls` 165 166 ``` 167 $ ctr plugins ls 168 TYPE ID PLATFORMS STATUS 169 io.containerd.content.v1 content - ok 170 io.containerd.snapshotter.v1 btrfs linux/amd64 ok 171 io.containerd.snapshotter.v1 aufs linux/amd64 error 172 io.containerd.snapshotter.v1 native linux/amd64 ok 173 io.containerd.snapshotter.v1 overlayfs linux/amd64 ok 174 io.containerd.snapshotter.v1 zfs linux/amd64 error 175 io.containerd.metadata.v1 bolt - ok 176 io.containerd.differ.v1 walking linux/amd64 ok 177 io.containerd.gc.v1 scheduler - ok 178 io.containerd.service.v1 containers-service - ok 179 io.containerd.service.v1 content-service - ok 180 io.containerd.service.v1 diff-service - ok 181 io.containerd.service.v1 images-service - ok 182 io.containerd.service.v1 leases-service - ok 183 io.containerd.service.v1 namespaces-service - ok 184 io.containerd.service.v1 snapshots-service - ok 185 io.containerd.runtime.v1 linux linux/amd64 ok 186 io.containerd.runtime.v2 task linux/amd64 ok 187 io.containerd.monitor.v1 cgroups linux/amd64 ok 188 io.containerd.service.v1 tasks-service - ok 189 io.containerd.internal.v1 restart - ok 190 io.containerd.grpc.v1 containers - ok 191 io.containerd.grpc.v1 content - ok 192 io.containerd.grpc.v1 diff - ok 193 io.containerd.grpc.v1 events - ok 194 io.containerd.grpc.v1 healthcheck - ok 195 io.containerd.grpc.v1 images - ok 196 io.containerd.grpc.v1 leases - ok 197 io.containerd.grpc.v1 namespaces - ok 198 io.containerd.grpc.v1 snapshots - ok 199 io.containerd.grpc.v1 tasks - ok 200 io.containerd.grpc.v1 version - ok 201 io.containerd.grpc.v1 cri linux/amd64 ok 202 ``` 203 204 From the output all the plugins can be seen as well those which did not 205 successfully load. In this case `aufs` and `zfs` are expected not to load 206 since they are not support on the machine. The logs will show why it failed, 207 but you can also get more details using the `-d` option. 208 209 ``` 210 $ ctr plugins ls -d id==aufs id==zfs 211 Type: io.containerd.snapshotter.v1 212 ID: aufs 213 Platforms: linux/amd64 214 Exports: 215 root /var/lib/containerd/io.containerd.snapshotter.v1.aufs 216 Error: 217 Code: Unknown 218 Message: modprobe aufs failed: "modprobe: FATAL: Module aufs not found in directory /lib/modules/4.17.2-1-ARCH\n": exit status 1 219 220 Type: io.containerd.snapshotter.v1 221 ID: zfs 222 Platforms: linux/amd64 223 Exports: 224 root /var/lib/containerd/io.containerd.snapshotter.v1.zfs 225 Error: 226 Code: Unknown 227 Message: path /var/lib/containerd/io.containerd.snapshotter.v1.zfs must be a zfs filesystem to be used with the zfs snapshotter 228 ``` 229 230 The error message which the plugin returned explains why the plugin was unable 231 to load. 232 233 #### Configuration 234 235 Plugins are configured using the `[plugins]` section of containerd's config. 236 Every plugin can have its own section using the pattern `[plugins.<plugin id>]`. 237 238 example configuration 239 ``` 240 [plugins] 241 [plugins.cgroups] 242 no_prometheus = false 243 [plugins.cri] 244 stream_server_address = "" 245 stream_server_port = "10010" 246 enable_selinux = false 247 sandbox_image = "k8s.gcr.io/pause:3.1" 248 stats_collect_period = 10 249 systemd_cgroup = false 250 [plugins.cri.containerd] 251 snapshotter = "overlayfs" 252 [plugins.cri.containerd.default_runtime] 253 runtime_type = "io.containerd.runtime.v1.linux" 254 runtime_engine = "" 255 runtime_root = "" 256 [plugins.cri.containerd.untrusted_workload_runtime] 257 runtime_type = "" 258 runtime_engine = "" 259 runtime_root = "" 260 [plugins.cri.cni] 261 bin_dir = "/opt/cni/bin" 262 conf_dir = "/etc/cni/net.d" 263 [plugins.cri.registry] 264 [plugins.cri.registry.mirrors] 265 [plugins.cri.registry.mirrors."docker.io"] 266 endpoint = ["https://registry-1.docker.io"] 267 ```