(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Docker入門】Namespaceによる名前空間の分離

スポンサーリンク

はじめに

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 の略