|
| 1 | +# containerd Namespaces and Multi-Tenancy |
| 2 | + |
| 3 | +containerd offers a fully namespaced API so multiple consumers can all use a single containerd instance and not conflict with one another. |
| 4 | +Namespaces allow multi-tenancy with a single daemon, no more running nested containers to achieve this. |
| 5 | +Consumers are able to have containers with the same names but settings that vary drastically. |
| 6 | +System or infrastructure level containers can be hidden in a namespace while user level containers are kept in another. |
| 7 | +Underlying image content is still shared via content addresses but image names and metadata are separate per namespace. |
| 8 | + |
| 9 | +It is important to note that namespaces, as implemented, is an administration level construct that is not meant to be used as a security feature. |
| 10 | +It is trivial for clients to switch namespaces. |
| 11 | + |
| 12 | +## Who specifies the namespace? |
| 13 | + |
| 14 | +The client specifies the namespace via the `context`. |
| 15 | +There is a `github.com/containerd/containerd/namespaces` package that allows a user to get and set the namespace on a context. |
| 16 | + |
| 17 | +```go |
| 18 | +// set a namespace |
| 19 | +ctx := namespaces.WithNamespace(context.Background(), "my-namespace") |
| 20 | + |
| 21 | +// get the namespace |
| 22 | +ns, ok := namespaces.Namespace(ctx) |
| 23 | +``` |
| 24 | + |
| 25 | +Because the client calls containerd's GRPC API to interact with the daemon, all API calls require a context with a namespace set. |
| 26 | + |
| 27 | +## How low level is the implementation? |
| 28 | + |
| 29 | +Namespaces are passed through the containerd API to the underlying plugins providing functionality. |
| 30 | +Plugins must be written to take namespaces into account. |
| 31 | +Filesystem paths, IDs, or other system level resources must be namespaced for a plugin to work properly. |
| 32 | + |
| 33 | +## How does multi-tenancy work? |
| 34 | + |
| 35 | +Simply create a new `context` and set your application's namespace on the `context`. |
| 36 | +Make sure you use a unique namespace for your applications that do not conflict with others. |
| 37 | + |
| 38 | +```go |
| 39 | +ctx := context.Background() |
| 40 | + |
| 41 | +var ( |
| 42 | + docker = namespaces.WithNamespace(ctx, "docker") |
| 43 | + vmware = namespaces.WithNamespace(ctx, "vmware") |
| 44 | + ecs = namespaces.WithNamespace(ctx, "aws-ecs") |
| 45 | + cri = namespaces.WithNamespace(ctx, "cri") |
| 46 | +) |
| 47 | +``` |
| 48 | + |
| 49 | +## Inspecting Namespaces |
| 50 | + |
| 51 | +If we need to inspect containers, images, or other resources in various namespaces the `ctr` tool allows you to do this. |
| 52 | +Simply set the `--namespace,-n` flag on `ctr` to change the namespace. |
| 53 | + |
| 54 | +```bash |
| 55 | +> sudo ctr -n docker tasks |
| 56 | +> sudo ctr -n cri tasks |
| 57 | +``` |
| 58 | + |
| 59 | +You can also use the `CONTAINERD_NAMESPACE` env var when interacting with `ctr` to set or change the default namespace. |
0 commit comments