|
| 1 | +# Runtime v2 |
| 2 | + |
| 3 | +Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd. |
| 4 | +The shim API is minimal and scoped to the execution lifecycle of a container. |
| 5 | + |
| 6 | +## Binary Naming |
| 7 | + |
| 8 | +Users specify the runtime they wish to use when creating a container. |
| 9 | +The runtime can also be changed via a container update. |
| 10 | + |
| 11 | +```bash |
| 12 | +> ctr run --runtime io.containerd.runc.v1 |
| 13 | +``` |
| 14 | + |
| 15 | +When a user specifies a runtime name, `io.containerd.runc.v1`, they will specify the name and version of the runtime. |
| 16 | +This will be trasnlated by containerd into a binary name for the shim. |
| 17 | + |
| 18 | +`io.containerd.runc.v1` -> `containerd-shim-runc-v1` |
| 19 | + |
| 20 | +containerd keeps the `containerd-shim-*` prefix so that users can `ps aux | grep containerd-shim` to see running shims on their system. |
| 21 | + |
| 22 | +## Shim Authoring |
| 23 | + |
| 24 | +This section is dedicated to runtime authors wishing to build a shim. |
| 25 | +It will detail how the API works and different considerations when building shim. |
| 26 | + |
| 27 | +### Commands |
| 28 | + |
| 29 | +Container information is provided to a shim in two ways. |
| 30 | +The OCI Runtime Bundle and on the `Create` rpc request. |
| 31 | + |
| 32 | +#### `start` |
| 33 | + |
| 34 | +Each shim MUST implement a `start` subcommand. |
| 35 | +This command will launch new shims. |
| 36 | +The start command MUST accept the following flags: |
| 37 | + |
| 38 | +* `-namespace` the namespace for the container |
| 39 | +* `-id` the id of the container |
| 40 | +* `-address` the address of the containerd's main socket |
| 41 | +* `-publish-binary` the binary path to publish events back to containerd |
| 42 | + |
| 43 | +The start command, as well as all binary calls to the shim, has the bundle for the container set as the `cwd`. |
| 44 | + |
| 45 | +The start command MUST return an address to a shim for containerd to issue API requests for container operations. |
| 46 | + |
| 47 | +The start command can either start a new shim or return an address to an existing shim based on the shim's logic. |
| 48 | + |
| 49 | +#### `delete` |
| 50 | + |
| 51 | +Each shim MUST implement a `delete` subcommand. |
| 52 | +This command allows containerd to delete any container resources created, mounted, and/or run by a shim when containerd can no longer communicate over rpc. |
| 53 | +This happens if a shim is SIGKILL'd with a running container. |
| 54 | +These resources will need to be cleaned up when containerd looses the connection to a shim. |
| 55 | +This is also used when containerd boots and reconnects to shims. |
| 56 | +If a bundle is still on disk but containerd cannot connect to a shim, the delete command is invoked. |
| 57 | + |
| 58 | +The delete command MUST accept the following flags: |
| 59 | + |
| 60 | +* `-namespace` the namespace for the container |
| 61 | +* `-id` the id of the container |
| 62 | +* `-address` the address of the containerd's main socket |
| 63 | +* `-publish-binary` the binary path to publish events back to containerd |
| 64 | + |
| 65 | +The delete command will be executed in the container's bundle as its `cwd`. |
| 66 | + |
| 67 | +### Host Level Shim Configuration |
| 68 | + |
| 69 | +containerd does not provide any host level configuration for shims via the API. |
| 70 | +If a shim needs configuration from the user with host level information across all instances, a shim specific configuration file can be setup. |
| 71 | + |
| 72 | +### Container Level Shim Configuration |
| 73 | + |
| 74 | +On the create request, there is a generic `*protobuf.Any` that allows a user to specify container level configuration for the shim. |
| 75 | + |
| 76 | +```proto |
| 77 | +message CreateTaskRequest { |
| 78 | + string id = 1; |
| 79 | + ... |
| 80 | + google.protobuf.Any options = 10; |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +A shim author can create their own protobuf message for configuration and clients can import and provide this information is needed. |
| 85 | + |
| 86 | +### I/O |
| 87 | + |
| 88 | +I/O for a container is provided by the client to the shim via fifo on Linux, named pipes on Windows, or log files on disk. |
| 89 | +The paths to these files are provided on the `Create` rpc for the initial creation and on the `Exec` rpc for additional processes. |
| 90 | + |
| 91 | +```proto |
| 92 | +message CreateTaskRequest { |
| 93 | + string id = 1; |
| 94 | + bool terminal = 4; |
| 95 | + string stdin = 5; |
| 96 | + string stdout = 6; |
| 97 | + string stderr = 7; |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +```proto |
| 102 | +message ExecProcessRequest { |
| 103 | + string id = 1; |
| 104 | + string exec_id = 2; |
| 105 | + bool terminal = 3; |
| 106 | + string stdin = 4; |
| 107 | + string stdout = 5; |
| 108 | + string stderr = 6; |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +Containers that are to be launched with an interactive terminal will have the `terminal` field set to `true`, data is still copied over the files(fifos,pipes) in the same way as non interactive containers. |
| 113 | + |
| 114 | +### Root Filesystems |
| 115 | + |
| 116 | +The root filesytems for the containers is provided by on the `Create` rpc. |
| 117 | +Shims are responsible for managing the lifecycle of the filesystem mount during the lifecycle of a container. |
| 118 | + |
| 119 | +```proto |
| 120 | +message CreateTaskRequest { |
| 121 | + string id = 1; |
| 122 | + string bundle = 2; |
| 123 | + repeated containerd.types.Mount rootfs = 3; |
| 124 | + ... |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +The mount protobuf message is: |
| 129 | + |
| 130 | +```proto |
| 131 | +message Mount { |
| 132 | + // Type defines the nature of the mount. |
| 133 | + string type = 1; |
| 134 | + // Source specifies the name of the mount. Depending on mount type, this |
| 135 | + // may be a volume name or a host path, or even ignored. |
| 136 | + string source = 2; |
| 137 | + // Target path in container |
| 138 | + string target = 3; |
| 139 | + // Options specifies zero or more fstab style mount options. |
| 140 | + repeated string options = 4; |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +Shims are responsible for mounting the filesystem into the `rootfs/` directory of the bundle. |
| 145 | +Shims are also responsible for unmounting of the filesystem. |
| 146 | +During a `delete` binary call, the shim MUST ensure that filesystem is also unmounted. |
| 147 | +Filesystems are provided by the containerd snapshotters. |
| 148 | + |
| 149 | +### Other |
| 150 | + |
| 151 | +#### Unsupported rpcs |
| 152 | + |
| 153 | +If a shim does not or cannot implement an rpc call, it MUST return a `github.com/containerd/containerd/errdefs.ErrNotImplemented` error. |
| 154 | + |
| 155 | +#### ttrpc |
| 156 | + |
| 157 | +[ttrpc](https://github.com/containerd/ttrpc) is the only currently supported protocol for shims. |
| 158 | +It works with standard protobufs and GRPC services as well as generating clients. |
| 159 | +The only difference between grpc and ttrpc is the wire protocol. |
| 160 | +ttrpc removes the http stack in order to save memory and binary size to keep shims small. |
| 161 | +It is recommended to use ttrpc in your shim but grpc support is also in development. |
0 commit comments