📦
runC: 分かり易く解説 (第3回) - 実際に動かしてみる
Dockerの中核コンテナ技術であるrunCについて、以下の通りいくつかの記事に分けて分かり易く解説します。
- 第1回:概要と実現技術
- 第2回:インストールと環境構築
- 第3回:runCを実際に動かしてみる
はじめに
今回は実際にrunCでUbuntu18.04を動かし、雰囲気が分かるようになることを目的として解説していきます。
Ubuntu 18.04のrootfs準備
まず、コンテナ化対象のrootfs (/) となるディレクトリを作成します。
mkdir sample-container-rootfs
cd sample-container-rootfs
次に、x64用(PC環境に合わせた適切なアーキテクチャを選択が必要)のDockerイメージのUbuntu18.04イメージを取得します。
$ wget https://partner-images.canonical.com/core/bionic/current/ubuntu-bionic-core-cloudimg-amd64-root.tar.gz
$ tar xzvf ubuntu-bionic-core-cloudimg-amd64-root.tar.gz
$ rm ubuntu-bionic-core-cloudimg-amd64-root.tar.gz
$ ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
この展開したデータを見ると分かりますが、Linuxのルートファイルシステムのデータ群をtarで固めたデータであることが分かると思います。これがDockerイメージの実態なのです。
config.jsonファイルの作成
config.jsonファイルは必ずrootfs直下に配置する必要があります。
runc spec
config.jsonファイルの修正
今回は細かい設定やカスタマイズはさておき、とりあえず動かす方法のconfigファイルは以下です。基本的にrunc specで作成したそのままで動かすことが可能です。
{
"ociVersion": "1.0.1-dev",
"process": {
"terminal": true,
"user": {
"uid": 0,
"gid": 0
},
"args": [
"sh"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": "/",
"capabilities": {
"bounding": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"effective": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"inheritable": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"permitted": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"ambient": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
]
},
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"noNewPrivileges": true
},
"root": {
"path": "", ← ここを修正。runcコマンド実行ディレクトリからの相体位置を意識して下さい。
"readonly": true
},
"hostname": "runc",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/sys/fs/cgroup",
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
}
],
"linux": {
"resources": {
"devices": [
{
"allow": false,
"access": "rwm"
}
]
},
"namespaces": [
{
"type": "pid"
},
{
"type": "network"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
}
],
"maskedPaths": [
"/proc/kcore",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/sys/firmware",
"/proc/scsi"
],
"readonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
}
}
Ubuntu18をコンテナを動かす - 方法その①
$ sudo runc run ubuntu18
# ls
bin config.json dev home lib64 mnt proc run srv tmp var
boot config.json~ etc lib media opt root sbin sys usr
# uname -a
Linux runc 5.0.0-27-generic #28~18.04.1-Ubuntu SMP Thu Aug 22 03:00:32 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# hostname
runc
終了方法
runc runで開始した場合、exitで終了した時点でコンテナは破棄されます。
# exit
Ubuntu18をコンテナを動かす - 方法その②
コンテナに実際に入らずに、コンテナはバックグラウンドで動かしながらバッチ処理などをそのコンテナ内で実行したい場合に利用する方法です。
$ sudo runc create ubuntu18
$ sudo runc list
ID PID STATUS BUNDLE CREATED OWNER
ubuntu18 3927 created /home/xxxxx/sample-container-rootfs 2019-11-20T11:03:43.234637306Z root
config.jsonファイルの修正
上記方法①に対して、process -> terminalの部分をfalseに修正します。また、argsの部分も修正し、コンテナがずっと生き続けるようにダミーのsleepを入れておきます。
config.json
{
"ociVersion": "1.0.1-dev",
"process": {
"terminal": false, ← 修正
"user": {
"uid": 0,
"gid": 0
},
"args": [
"sleep","infinity" ← 修正
],
コンテナを作成し、そのコンテナの中でコマンドを実行します。
$ sudo runc create ubuntu18
$ sudo runc start ubuntu18
$ sudo runc exec ubuntu18 ls
bin
boot
config.json
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ sudo runc exec ubuntu18 pwd
/
$ sudo runc exec ubuntu18 hostname
runc
終了方法
無限sleepでコンテナを動かしているため、通常のrunc killでコンテナが停止してくれないため、強制終了で対応します。
$ sudo runc list
ID PID STATUS BUNDLE CREATED OWNER
ubuntu18 4398 running /home/xxxxx/sample-container-rootfs 2019-11-20T11:23:32.631134894Z root
$ sudo runc kill ubuntu18
$ sudo runc list
ID PID STATUS BUNDLE CREATED OWNER
ubuntu18 4398 running /home/xxxxx/sample-container-rootfs 2019-11-20T11:23:32.631134894Z root
$ sudo runc kill ubuntu18 KILL
$ sudo runc list
ID PID STATUS BUNDLE CREATED OWNER
ubuntu18 0 stopped /home/xxxxx/sample-container-rootfs 2019-11-20T11:23:32.631134894Z root
$ sudo runc delete ubuntu18
$ sudo runc list
ID PID STATUS BUNDLE CREATED OWNER
Discussion