Docker入門1 仮想化からコンテナまで


「Docker/Kubernetes 実践コンテナ開発入門」より引用。
>Dockerはコンテナ型仮想化技術を実現するために実行される常駐アプリケーションと、それを操作するためのコマンドフロントインターフェースから成るプロダクトです。

はい、難しいですね。自分なりに整理しながら理解したいと思います。

## 仮想化ってなに？
よく、システムごとにサーバーは分けられます。例えば、検索系のシステムだったり、情報系のシステムだったり、勘定系のシステムだったり。サーバーを分けた方が、お互いのシステムのこと考慮しなくて良いので楽なんですよね。違うOS使えたり、好きにパッケージインストールしたり。
でも、物理的なサーバーってお高いです。ハードウェアベンダーのメジャーな会社だと、NEC、富士通、日立あたりですかね。サーバー買うとなると、保守含めて1台100万はします。しかも、１つのシステムだけではそんなにリソース（CPU、メモリ、ディスク）使わない場合も多いです。
そこで、物理的なサーバーは1台だけど、その上で複数のサーバーを動かせないかな？と思うわけです。そこで登場するのが`サーバー仮想化`です。
仮想的に、サーバーを分けるのです。（なんちゃって複数サーバー）
そうすることで、１つの物理サーバーで違うOSを使えたり、リソースを有効活用できたりします。
仮想化の仕組みにはいくつか種類があるので、見ていきましょう。

![Untitled Diagram (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/047d13ae-f190-3c09-88ce-2dcf69b959b0.png)


### ホストOS型
サーバー仮想化の１つ目の方法です。仮想化ソフトウェアをインストールすると、ゲストOSとしてホストOSとは異なるOSをインストールすることができます。
例えば、Mac上でWindowsを動かしたい時にVirtualBoxという仮想化ソフトウェアを使うと、これが実現できます。

![Untitled Diagram (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/48d41f55-8703-1f6a-035d-ed24ac38b930.png)

### ハイパーバイザー型
サーバー仮想化の2つ目の方法です。仮想化サーバーとしてのみ使用する場合、ホストOSいらないですよね。ハイパーバイザーという仮想化ソフトウェアを使うと、ホストOSなしで仮想サーバーが動かせます。

![Untitled Diagram (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/18a6ad40-b2ef-df2f-b1fe-3adc4b933f7f.png)

### コンテナ型
ホストOS型のサーバー仮想化と似ていますが、違います。
そもそも、物理サーバーの有効活用が目的のサーバー仮想化とは違い、アプリケーションを実行環境（プログラミング言語を実行するためのランタイムや、ライブラリなど）ごと持ち運びできるコンテナにすることで、アプリケーションの開発でよく悩まされるJavaのバージョンの違いなどの`環境依存を減らそう`という目的が大きいようです。
どのような仕組みなのか、詳しく見ていきましょう。

![Untitled Diagram (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/907d7f1f-0fbb-8756-fcf1-47de034de9cf.png)

## OSってなに？
コンテナの話に行く前に、OSってなに？という話を挟みます。
OSは大きく分けて、`カーネル`と`シェル`に分けられ、次のような役割を担っています。

* カーネル・・・OSの中核を担っており、CPU・メモリ・デバイスなどを管理する
* シェル・・・ユーザーがターミナルから実行したコマンドをカーネルに伝える

![Untitled Diagram (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/b8fee1a1-5178-3f73-e72f-f6a01749203b.png)

## コンテナの仕組み
実は、Dockerのコンテナは、Linuxのカーネルの機能を使って実現されています。
コンテナの中で作成した物をホストOSや他のコンテナから隔離するための機能で、具体的には、Linuxカーネルのコンテナごとに独立した空間を作れる機能[^1]や、CPUやメモリの割り当てをコンテナごとに制御したりする機能を使っています。

[^1]: Linuxカーネルのnamespaceという機能で、ネットワークの分離や、プロセスIDが同じサーバー内でも違うコンテナだったら同じIDになっても良いなど。参考3のページにて詳しく解説されています。

このためDockerを使いたい場合、ホストOSのカーネルはLinuxである必要がありますし、コンテナで使用するOS（の一部機能。シェルなど。）はLinuxカーネルを使用する`Linuxディストリビューション`[^2]である必要があります。
[^2]: LinuxディストリビューションはUbuntu、Debian、CentOS、Alpineなどがあります。カーネルはLinuxで、シェルはディストリビューションごとに異なります。
（追記：元々はLinuxカーネルに依存していましたが、Windowsでも使用できるようになったとのことです。）

![Untitled Diagram (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/5d006258-adf8-9cd9-d5cd-998a7a2b3608.png)

また、コンテナは環境依存性が薄いので、他の人が作ったコンテナを使うことも容易です。
ユーザーが作成したコンテナをインターネット上にアップロードして公開・共有できる[Docker Hub](https://hub.docker.com/)というサービスがあり、MySQLを使いたいな、という時にDockerHubからコンテナイメージ（後述）を取得して簡単にセットアップできたりもします。

##  次のページ
[Docker入門2 基本的なコマンドを使ってみる \- Qiita](https://qiita.com/maruuuuu/items/2fa62de1a483817fb51e)

## 参考
1. [サーバ仮想化の基本を学ぶ \| IT価値創造塾](https://vmware-juku.jp/whatsvm/whatsvm02/)
2. [【図解】「Docker\(コンテナ\)でUbuntuを構築する」ってどういう意味？ \- Qiita](https://qiita.com/ko_koyama_m/items/0e65849b91a329529675)
3. [Linuxカーネル Docker関連 namespaceのメモ – Rest Term](https://rest-term.com/archives/3287/)
4. [俺は Linux コンテナについてなんにも解っていなかった 〜 haconiwa で学ぶ Linux コンテナ \(1\) 〜 \| cloudpack\.media](https://cloudpack.media/30811)
5. [Linuxディストリビューションの比較 \- Wikiwand](https://www.wikiwand.com/ja/Linux%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E6%AF%94%E8%BC%83)