Dockerについて整理してみる
January 3, 2021
完全に自分のための整理用メモです。Docker について勉強する中で、特に疑問に思って調べた点について整理してみます。
Docker は Linux の上でしか動かない #
そもそも Docker の機能は、Linux の「namespace」や「cgroup」や「overlayfs」といった機能をうまいこと組み合わせて実現している。
namespaces
namespace 内のプロセスは他の namespace 内のプロセスとリソースが隔離されていて、プロセスごとの環境を構築することが可能です。
cgroup
cgroup は、タスクをグループ化したり、グループ内のタスクに様々なリソース制御を行う仕組みです。先程の namespace はホスト名や PID などのリソースを制御する仕組みですが、cgroup は CPU やメモリなどの物理的なリソースを制御します。
OverlayFS
overlayfs はユニオンファイルシステムの 1 つで、ディレクトリを重ね合わせて 1 つのディレクトリツリーを構成できます。overlayfs は、上位層と下位層をマージっして 1 つのファイルシステムとして見せる仕組みで、ディレクトリはマージ、その他のファイルは上位層にあるファイルだけ見え、上位層がなければ下位層にあるファイルが見えます。
Docker コンテナの仕組み -namespace、cgroup、overlayfs- | ネットワークエンジニアを目指して
Docker for Mac / Windows は仮想化された Linux の上で動いている #
Docker が Linux 上でしか動かないのなら、なんで Docker for Mac / Windows は、Mac や Windows で動くんだ?となると思いますが(私はなりました)、実際には仮想 Linux の上で動いています。
Docker for Mac の場合は、HyperKit という仮想マシン上で Linux が稼働し、その上で Docker が動いています。なお、HyperKit は Docker が製作した仮想化ツールです。HyperKit は macOS に搭載されている Hypervisor Framework という機能を利用して作られているようです。
Docker for Windows の場合は、マイクロソフトの仮想化システムである Hyper-V の上で Linux が稼働し、その上で Docker が動いています。
Hyper-V
Hyper-V(ハイパー V、はいぱーぶい)は、マイクロソフトが提供するハイパーバイザベースの x64 向け仮想化システムで、1 台のコンピュータ(サーバ)で複数の仮想機械を実現する。
ちなみに、Docker for Mac / Windows が仮想マシン上で動かしている Linux は、moby linux という名前らしいです。
コンテナの OS は、ディストリビューションの皮を被せるだけ #
Docker イメージの中で OS のイメージというものを見かけたとき、私は以下のはてなブログや Qiita 記事に書いてある通りの疑問を持ちました。
Dockerfile で Alpine Linux が登場して、コンテナの OS だよって言われてよく分からなくなった。コンテナで OS が動いているの?ってなった。
Docker のコンテナで動く OS がよく分からなかった | はてなブログ - だだだだだだいありー
Docker 環境を定義する Dockerfile では、DockerHub とかで公開されているベースイメージを元にコンテナ環境を構築します。
その中には、Ubuntu とか CentOS とかのイメージもありますが、Docker は仮想化によりホスト OS の上で別の OS を動かすような仕組みでは無かったはずです。どういうことでしょう?
答えはそれぞれの記事にも書いてくれていますが、自分の言葉で整理します。その前に Linux ディストリビューションについておさらい。
Linux ディストリビューションは Linux カーネルとその他ソフトウェア群を 1 つにまとめ、利用者が容易にインストール・利用できるようにしたものである。
Debian 系や Red Hat 系といった様々なディストリビューションがありますが、それらの違いは「その他ソフトウェア群」の部分であり、「Linux カーネル」の部分は共通しています。
これを受けて、答えは以下の通りです。
- Docker は Linux 上で動く前提なので、ホスト OS(Docker の下にいる OS)は当然 Linux。
- ディストリビューションが違っても Linux カーネルは共通。
- コンテナの OS に従って、そのコンテナのディレクトリ構成が行われたり、「その他ソフトウェア群」の部分が構築される。Linux カーネルは含まれない。
- コンテナ上で実行されるすべての命令は、コンテナのディストリビューションを通して、ホスト OS(Docker の下にいるサーバの大元の OS)の Linux カーネルによって処理される。
つまり、コンテナの OS とは、正確には OS ではなく、ディストリビューションの皮を被せるだけといった感じだと思います。
上記で参照した引用元意外にも、以下の teratail が参考になったのでリンクを貼っておきます。
Docker - Docker のコンテナ内で使われる OS について| teratail
1つのコンテナに1つの機能が Docker のベストプラクティス #
Docker のイメージの作り方を学んでいた時に私が感じたことは、1つのイメージに Web サーバと AP サーバと DB サーバをまとめちゃいけないの?でした。
これもやはり teratail で同様の質問をされている方がいました。
Docker って 1 つのコンテナに複数のパッケージをインストールして構築してはいけないのでしょうか?| teratail
回答の中にある通り、機能的には1つのコンテナにまとめることは可能ではあるが、1コンテナ1機能とするのがベストプラクティスとのこと。Docker 公式にもベストプラクティスを示したページがあり、ばっちり書いていました。
Decouple applications
Each container should have only one concern. Decoupling applications into multiple containers makes it easier to scale horizontally and reuse containers. For instance, a web application stack might consist of three separate containers, each with its own unique image, to manage the web application, database, and an in-memory cache in a decoupled manner.
Best practices for writing Dockerfiles | Docker Documentation
「アプリを分離せよ!それぞれのコンテナはただ1つの関心ごとに対処する形の方が良いよ!」とのことです。
他にも色々ベストプラクティスが書いてあるので、とりあえず全部目を通したいですね(…そのうち)。
コンテナは目新しい技術というわけでもない #
これは、私が以前の会社に勤めていた時の話なのですが、私が先輩に「最近は Docker なるものがキテるらしいですよ?(そもそも Docker がどんなものはよく分かってない)」と言ったところ、先輩から「似たような技術自体は昔からずっとあるけどね。まあ流行り廃りかね。」と返されました。
(あれから年月が経ち…)今になって Docker の勉強を始めたわけですが、調べみると確かに関連技術の考え方自体は昔からあるようです。
どんな技術的変遷を辿ってきたかは調べればすぐ出てきますが、例えば以下の記事ではコンテナ・仮想化技術について主要なものとその経緯をまとめてくださっています。
知らぬはエンジニアの恥。今さら聞けない【コンテナ/仮想化技術】11 選 - paiza 開発日誌
その他 #
Docker 全般については以下の記事が非常にわかりやすいです。
【連載】世界一わかりみが深いコンテナ & Docker 入門 | SIOS Tech. Lab
以上でした!