はじめに
Dockerを始めとしたコンテナ型仮想化を技術として捉えた際に出てくる用語に「Namespace」と「CGROUP」があります。
Dockerとは?
本記事ではNamespaceとはなんぞや?といった層を対象に、分かりやすく説明してみました。
このあたりを抑えてなくてもDockerを利用することは可能ですが、バックグラウンドの知識として知っておくと役立つこともあると思います。
Namespaceとは?
日本語ではそのまま「名前空間」と訳されますが、こちらは特にDockerやUNIX系OS独特の用語ではなくて広く使われる概念です。
名前空間とは、要素名が重複しても識別できるように名前の集合へ与えられる識別名を指します。
要は、Dockerのようなコンテナ技術においては一つのカーネルの上で隔離環境を用意する必要があるのでプロセスIDはもちろんのこと、ファイルシステムやユーザID諸々の名前空間を分離することが求められるわけです。
よってDockerの文脈で「Namespace」と言えば
「プロセス毎に名前空間を分離する機能」を指します。
Namespaceで分離するものに
- mount
- uts
- ipc
- user
- pid
- net
などがありますが、今回は「プロセス毎にホスト名を分離する」utsを参考に詳しく解説していきます。*1
unshareコマンドで名前空間を変更する
Namespaceの機能を実現するためにunshare
コマンドを利用します。
コマンドの配置場所は以下で
$ which unshare /usr/bin/unshare
マニュアルの抜粋は以下です。
unshare - run program with some namespaces unshared from parent
UTS namespace
Setting hostname or domainname will not affect the rest of the system.
For further details, see namespaces(7) and the discussion of the CLONE_NEWUTS flag in clone(2).
要は他のプロセスに影響なくホスト名の変更が可能です。
試してみましょう。
まずは名前空間を分離する前の情報を確認します。
$ echo $$ 6911 $ hostname instance-1
名前空間を確認する「lsns」を使うと以下のようにutsは一つしかありません。
$ lsns NS TYPE NPROCS PID USER COMMAND 4026531835 cgroup 74 1 root /sbin/init 4026531836 pid 74 1 root /sbin/init 4026531837 user 74 1 root /sbin/init 4026531838 uts 74 1 root /sbin/init 4026531839 ipc 74 1 root /sbin/init 4026531840 mnt 72 1 root /sbin/init 4026531857 mnt 1 13 root kdevtmpfs 4026531957 net 74 1 root /sbin/init 4026532137 mnt 1 440 root /lib/systemd/systemd-udevd
ところがutsを分離すると
$ unshare --uts
プロセスIDが変更されています。ただしホスト名は引き継いでいます。
$ echo $$ 6987 $ hostname instance-1
先ほど同様、名前空間のリストを表示させると
$ lsns NS TYPE NPROCS PID USER COMMAND 4026531835 cgroup 75 1 root /sbin/init 4026531836 pid 75 1 root /sbin/init 4026531837 user 75 1 root /sbin/init 4026531838 uts 73 1 root /sbin/init 4026531839 ipc 75 1 root /sbin/init 4026531840 mnt 73 1 root /sbin/init 4026531857 mnt 1 13 root kdevtmpfs 4026531957 net 75 1 root /sbin/init 4026532137 mnt 1 440 root /lib/systemd/systemd-udevd 4026532144 uts 2 6987 root -bash
先ほど確認したプロセスIDを持つ新たな名前空間が作成されていることが分かります。
試しにホスト名を変更すると変更されます。
$ hostname instance-2 $ hostname instance-2
確かにホスト名が変更されていますが、この名前空間を閉じれば
$ exit logout $ hostname instance-1
元のホスト名は変更されていません。Namespaceによる名前空間の分離が成功しています。
終わりに
今回はホスト名に絞って説明をしましたが、同じ理屈でファイルシステムやユーザー名も分離することができます。
この分離によって、Dockerではあたかも全く別の環境のように環境を編集することができます。
本記事にてDockerの肝の一つである「Namespace」のイメージが掴んでいただければ幸いです。
*1:uts : Unix Timesharing System の略