Dockerコンテナが専用namespaceに属していることを確認する

概要

  • dockerコンテナによるLinux上の各種リソースの隔離[1] は、linuxのnamespace(名前空間)という機能を使って実現されています [2]
  • 実際にdockerコンテナを作成し、defautの名前空間とは異なる名前空間がdocker用に作成されることを確認します

ログ

# 環境
$ uname -r
5.3.0-28-generic

$ docker -v
Docker version 19.03.5, build 633a0ea838

# コンテナ起動
$ docker run -d centos tail -f /dev/null
024357195f98466deca2c6e2d6e6db24ac8efc0d7b1a442fcec3249c4193e434

# containerのPID確認
$ docker inspect 024357195f98 --format '{{.State.Pid}}'
3799

# docker containerがdefaultのnsとは別のNamespaceに所属していることを確認
$ sudo ls -l /proc/3799/ns/
合計 0
lrwxrwxrwx 1 root root 0  215 23:49 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0  215 23:49 ipc -> 'ipc:[4026532396]'
lrwxrwxrwx 1 root root 0  215 23:49 mnt -> 'mnt:[4026532394]'
lrwxrwxrwx 1 root root 0  215 23:47 net -> 'net:[4026532399]'
lrwxrwxrwx 1 root root 0  215 23:49 pid -> 'pid:[4026532397]'
lrwxrwxrwx 1 root root 0  215 23:49 pid_for_children -> 'pid:[4026532397]'
lrwxrwxrwx 1 root root 0  215 23:49 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0  215 23:49 uts -> 'uts:[4026532395]'

$ sudo ls -l /proc/1/ns/
合計 0
lrwxrwxrwx 1 root root 0  215 23:49 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0  215 23:49 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0  215 23:49 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0  215 23:49 net -> 'net:[4026532008]'
lrwxrwxrwx 1 root root 0  215 23:49 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0  215 23:49 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0  215 23:49 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0  215 23:49 uts -> 'uts:[4026531838]'

# container用のnetwork namespaceの中でip addr show
$  sudo nsenter -t 3799 -n ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# defaultのnamespaceの中にはeth0は存在しない
$ ip addr show eth0
Device "eth0" does not exist.

参考: containerdが実際にnamespaceを作成していることを strace で確認する

# containerdのPID確認
$ systemctl status containerd
● containerd.service - containerd container runtime
()
 Main PID: 1351 (containerd)()

# straceをcontainerd processにアタッチ
$ sudo strace -ff -e unshare -p 1351

# 再度 centos containerを作成すると...
$ docker run -d centos tail -f /dev/null

# straceのSTDOUTに以下のように出力される [3]
strace: Process 1351 attached with 20 threads

()
[pid  5004] unshare(CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWPID) = 0
()

参考: ip netns list してもdockerコンテナ用に作成されたnamespaceが表示されないのはなぜか

脚注

[1] 「隔離」という言葉の具体的な意味については、以下を参照ください ※過去に開催の社内勉強会のリンクです
kubernetesソースコードリーディング 第4回 - APC 技術ブログ

[2] Kernelレベルの実装については、以下にて言及されています

[3] unshareシステムコールのmanページ
UNSHARE

/* https://sunrise033.com/entry/hatena-blog-how-to-hierarchicalize-categories */