カーネルの観点から見たLinuxKit

はじめに

Docker社はDockerCon2017において、Dockerコンテナの実行にフォーカスした軽量Linuxである、LinuxKitをリリースしました。

以下関連URLです。

本記事はLinuxKitについて網羅的な説明をすることではなくて、LinuxKitに同梱されているカーネルがどのようなものかをざっと眺めることです。なぜカーネルだけなのかというと、単に私がカーネル屋さんなのでカーネルに興味があっただけです。

本記事のLinuxKitの対象バージョンは、本記事執筆時点(2017年4月19日)で最新のcommit:f2d6752751318477ec86e4677514d5a4890249c1です。

カーネルは独自実装かどうか

LinuxKitに同梱されているカーネルは、独自実装したようなものではなく、みなさんがお使いのlinux kernelと同じものいくつかのパッチを当てたものです。カーネルバージョンは自分で選択もできるようですが、本書執筆現在で最新のv4.10 stable kernelもサポートしているようです。

カーネルに組み込まれている、モジュール化されている機能の数

通常のlinux distributionはなるべく多くの機能、デバイスをサポートするために、多くの機能を組み込んでいる、あるいはモジュール化していますが、LinuxKitに同梱されているカーネルはかなり思い切った作りになっており、ほとんどの機能を無効化しています。Ubuntu 16.04のカーネルの設定ファイルと、LinuxKitのデフォルトの設定ファイルのそれを比較してみます。

Ubuntu 16.04のカーネル LinuxKitのカーネル
有効化 2177 1540
モジュール化 4592 1

UbuntuカーネルよりもLinuxKitのそれのほうがはるかに軽量であることがわかります。モジュールに至っては1つしかありません。これがLinuxKitの軽量化、起動の高速化に一役買っていると考えられます。

どのような設定が組み込まれている、あるいはモジュール化されているのか。

CPU関連

CONFIG_NR_CPUS=128
...
# CONFIG_SCHED_SMT is not set
CONFIG_SCHED_MC=y

最多で128のコアまでサポートしているようです。この数が多ければ多いほど、CPUごとに存在するデータの数が増えますので、無暗に多くのCPUをサポートしない方針だと考えられます。Ubuntuの場合は512です。

マルチコアはサポートしているものの、ハイパースレッドはサポートしていないようです。

ファイルシステム関連

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT2=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
# CONFIG_EXT4_ENCRYPTION is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_F2FS_FS is not set
# CONFIG_FS_DAX is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
...
# CONFIG_QUOTA is not set
# CONFIG_QUOTACTL is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
CONFIG_OVERLAY_FS=y
...

ローカルファイルシステムext4だけが有効化されています。XFSやBtrfsなどの、その他よく使われるファイルシステムは使わないようです。

Dockerのストレージドライバとしてよく使われるoverlayfsは有効化されています。

セキュリティ

#
# Security options
#
CONFIG_KEYS=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_BIG_KEYS=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_KEY_DH_OPERATIONS=y
CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY=y
# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
# CONFIG_SECURITY_SELINUX is not set
# CONFIG_SECURITY_SMACK is not set
# CONFIG_SECURITY_TOMOYO is not set
# CONFIG_SECURITY_APPARMOR is not set
# CONFIG_SECURITY_LOADPIN is not set
CONFIG_SECURITY_YAMA=y
CONFIG_INTEGRITY=y
# CONFIG_INTEGRITY_SIGNATURE is not set
CONFIG_INTEGRITY_AUDIT=y
# CONFIG_IMA is not set
# CONFIG_EVM is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y

セキュリティモジュールは、なんと一番使われているSELinuxが無効化されています。そのかわり(?)、なぜかマイナーなYAMAが有効化されています。SELinuxのサポートについては今後の課題のようです。

namespaceとcgroup

コンテナ実装の肝であるnamespaceについてはひととおり有効化されているようです。

CONFIG_CGROUPS=y
CONFIG_PAGE_COUNTER=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y

コンテナのリソース制御をするcgroupについても多くが有効化されています。

CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y

仮想化

CONFIG_XEN=y
...
CONFIG_KVM_GUEST=y
...
CONFIG_HYPERV=y
...

Xen, KVM, Hyper-Vなどの主要なハイパーバイザのguestとして動くように設定されています。Widnows上や各種IaaS上で動かしたりする場合を考えれば当然必要でしょう。VIRTIOデバイスも用意されています。

おわりに

興味のある設定項目だけを適当に書き散らしたので、重要なところが漏れてことが多々あるかと思いますが、ご容赦ください。