292 lines
7.5 KiB
Markdown
292 lines
7.5 KiB
Markdown
|
# OCI Bundle
|
||
|
|
||
|
Since containerd consumes the OCI bundle format containers and configuration will have to be created
|
||
|
on the machine that containerd is running on. The easiest way to do this is to download an image
|
||
|
with docker and export it.
|
||
|
|
||
|
|
||
|
## Setup
|
||
|
|
||
|
First thing we need to do to create a bundle is setup the initial directory structure.
|
||
|
Create a directory with a unique name. In this example we will create a redis container.
|
||
|
We will create this container in a `/containers` directory.
|
||
|
|
||
|
|
||
|
```bash
|
||
|
mkdir redis
|
||
|
```
|
||
|
|
||
|
Inside the `redis` directory create another directory named `rootfs`
|
||
|
|
||
|
```bash
|
||
|
mkdir redis/rootfs
|
||
|
```
|
||
|
|
||
|
## Root Filesystem
|
||
|
|
||
|
Now we need to populate the `rootfs` directory with the filesystem of a redis container. To do this we
|
||
|
need to pull the redis image with docker and export its contents to the `rootfs` directory.
|
||
|
|
||
|
```bash
|
||
|
docker pull redis
|
||
|
|
||
|
# create the container with a temp name so that we can export it
|
||
|
docker create --name tempredis redis
|
||
|
|
||
|
# export it into the rootfs directory
|
||
|
docker export tempredis | tar -C redis/rootfs -xf -
|
||
|
|
||
|
# remove the container now that we have exported
|
||
|
docker rm tempredis
|
||
|
```
|
||
|
|
||
|
Now that we have the root filesystem populated we need to create the configs for the container.
|
||
|
|
||
|
## Configs
|
||
|
|
||
|
An easy way to get temp configs for the container bundle is to use the `runc`
|
||
|
cli tool from the [runc](https://github.com/opencontainers/runc) repository.
|
||
|
|
||
|
|
||
|
You need to `cd` into the `redis` directory and run the `runc spec` command. After doing this you
|
||
|
should have two files created, `configs.json` and `runtime.json`. The directory structure should
|
||
|
look like this:
|
||
|
|
||
|
```
|
||
|
/containers/redis
|
||
|
├── config.json
|
||
|
├── rootfs/
|
||
|
└── runtime.json
|
||
|
```
|
||
|
|
||
|
## Edits
|
||
|
|
||
|
We need to exit the config to add `redis-server` as the application to launch inside the container along with
|
||
|
a few other settings. The resulting `config.json` should look like this:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"version": "0.2.0",
|
||
|
"platform": {
|
||
|
"os": "linux",
|
||
|
"arch": "amd64"
|
||
|
},
|
||
|
"process": {
|
||
|
"terminal": false,
|
||
|
"user": {
|
||
|
"uid": 1000,
|
||
|
"gid": 1000
|
||
|
},
|
||
|
"args": [
|
||
|
"redis-server", "--bind", "0.0.0.0"
|
||
|
],
|
||
|
"env": [
|
||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||
|
"TERM=xterm"
|
||
|
],
|
||
|
"cwd": ""
|
||
|
},
|
||
|
"root": {
|
||
|
"path": "rootfs",
|
||
|
"readonly": false
|
||
|
},
|
||
|
"hostname": "shell",
|
||
|
"mounts": [
|
||
|
{"name": "proc", "path": "/proc"},
|
||
|
{"name": "dev", "path": "/dev"},
|
||
|
{"name": "devpts", "path": "/dev/pts"},
|
||
|
{"name": "shm", "path": "/dev/shm"},
|
||
|
{"name": "mqueue", "path": "/dev/mqueue"},
|
||
|
{"name": "sysfs", "path": "/sys"}
|
||
|
],
|
||
|
"linux": {
|
||
|
"capabilities": [
|
||
|
"CAP_AUDIT_WRITE",
|
||
|
"CAP_KILL",
|
||
|
"CAP_NET_BIND_SERVICE"
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
You will also want to edit the `runtime.json` file to remove the network namespace so that
|
||
|
you can connect to the redis server on your system. The final result for the `runtime.json`
|
||
|
file should look like this:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"mounts": {
|
||
|
"dev": {
|
||
|
"type": "tmpfs",
|
||
|
"source": "tmpfs",
|
||
|
"options": [
|
||
|
"nosuid",
|
||
|
"strictatime",
|
||
|
"mode=755",
|
||
|
"size=65536k"
|
||
|
]
|
||
|
},
|
||
|
"devpts": {
|
||
|
"type": "devpts",
|
||
|
"source": "devpts",
|
||
|
"options": [
|
||
|
"nosuid",
|
||
|
"noexec",
|
||
|
"newinstance",
|
||
|
"ptmxmode=0666",
|
||
|
"mode=0620",
|
||
|
"gid=5"
|
||
|
]
|
||
|
},
|
||
|
"mqueue": {
|
||
|
"type": "mqueue",
|
||
|
"source": "mqueue",
|
||
|
"options": [
|
||
|
"nosuid",
|
||
|
"noexec",
|
||
|
"nodev"
|
||
|
]
|
||
|
},
|
||
|
"proc": {
|
||
|
"type": "proc",
|
||
|
"source": "proc",
|
||
|
"options": null
|
||
|
},
|
||
|
"shm": {
|
||
|
"type": "tmpfs",
|
||
|
"source": "shm",
|
||
|
"options": [
|
||
|
"nosuid",
|
||
|
"noexec",
|
||
|
"nodev",
|
||
|
"mode=1777",
|
||
|
"size=65536k"
|
||
|
]
|
||
|
},
|
||
|
"sysfs": {
|
||
|
"type": "sysfs",
|
||
|
"source": "sysfs",
|
||
|
"options": [
|
||
|
"nosuid",
|
||
|
"noexec",
|
||
|
"nodev"
|
||
|
]
|
||
|
}
|
||
|
},
|
||
|
"linux": {
|
||
|
"rlimits": [
|
||
|
{
|
||
|
"type": "RLIMIT_NOFILE",
|
||
|
"hard": 1024,
|
||
|
"soft": 1024
|
||
|
}
|
||
|
],
|
||
|
"resources": {
|
||
|
"disableOOMKiller": false,
|
||
|
"memory": {
|
||
|
"limit": 0,
|
||
|
"reservation": 0,
|
||
|
"swap": 0,
|
||
|
"kernel": 0
|
||
|
},
|
||
|
"cpu": {
|
||
|
"shares": 0,
|
||
|
"quota": 0,
|
||
|
"period": 0,
|
||
|
"realtimeRuntime": 0,
|
||
|
"realtimePeriod": 0,
|
||
|
"cpus": "",
|
||
|
"mems": ""
|
||
|
},
|
||
|
"pids": {
|
||
|
"limit": 0
|
||
|
},
|
||
|
"blockIO": {
|
||
|
"blkioWeight": 0,
|
||
|
"blkioLeafWeight": 0,
|
||
|
"blkioWeightDevice": null,
|
||
|
"blkioThrottleReadBpsDevice": null,
|
||
|
"blkioThrottleWriteBpsDevice": null,
|
||
|
"blkioThrottleReadIOPSDevice": null,
|
||
|
"blkioThrottleWriteIOPSDevice": null
|
||
|
},
|
||
|
"hugepageLimits": null,
|
||
|
"network": {
|
||
|
"classId": "",
|
||
|
"priorities": null
|
||
|
}
|
||
|
},
|
||
|
"namespaces": [
|
||
|
{"type": "pid", "path": ""},
|
||
|
{"type": "ipc", "path": ""},
|
||
|
{"type": "uts", "path": ""},
|
||
|
{"type": "mount", "path": ""}
|
||
|
],
|
||
|
"devices": [
|
||
|
{
|
||
|
"path": "/dev/null",
|
||
|
"type": 99,
|
||
|
"major": 1,
|
||
|
"minor": 3,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
},
|
||
|
{
|
||
|
"path": "/dev/random",
|
||
|
"type": 99,
|
||
|
"major": 1,
|
||
|
"minor": 8,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
},
|
||
|
{
|
||
|
"path": "/dev/full",
|
||
|
"type": 99,
|
||
|
"major": 1,
|
||
|
"minor": 7,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
},
|
||
|
{
|
||
|
"path": "/dev/tty",
|
||
|
"type": 99,
|
||
|
"major": 5,
|
||
|
"minor": 0,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
},
|
||
|
{
|
||
|
"path": "/dev/zero",
|
||
|
"type": 99,
|
||
|
"major": 1,
|
||
|
"minor": 5,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
},
|
||
|
{
|
||
|
"path": "/dev/urandom",
|
||
|
"type": 99,
|
||
|
"major": 1,
|
||
|
"minor": 9,
|
||
|
"permissions": "rwm",
|
||
|
"fileMode": 438,
|
||
|
"uid": 0,
|
||
|
"gid": 0
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
This is what you need to do to make a OCI compliant bundle for containerd to start.
|