Docker for Windowsの概要と導入

# はじめに

ノートPCを新調したので、OSをWindows10 Proにしました。Docker for Windowsを試してみます。Dockerを使用したいだけなら、実はVirtual Boxや、WSLでも動かせます。

- [windows 10 home で docker を導入するメモ](https://qiita.com/idani/items/fb7681d79eeb48c05144)
- [WSL上でDocker Engineが動くようになっていたっぽいという話](https://qiita.com/yanoshi/items/dcecbf117d9cbd14af87)

じゃあ、なんでProにしたのと言うと

- [Linux Containers on Windows | Microsoft Docs](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/deploy-containers/linux-containers) 
- [WSL 2 に関してよく寄せられる質問 | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-faq)

Hyper-Vが使えると、色々できるからです。ぶっちゃけ Docker for Windows 触りたいだけです。
Dockerまわりの情報の整理と、Windowsにインストールするところまで実施します。

# 環境

- OS: Windows10 Pro 64bit
  - Version: 1903
  - OS build: 18362.418

# そもそもDockerってなに？

[仮想化](https://ja.wikipedia.org/wiki/%E4%BB%AE%E6%83%B3%E5%8C%96)技術の一つです。仮想化とは、1つの物理サーバの上で、複数の仮想的なサーバを動かしたり、逆に複数のサーバを1つのサーバのように見せたりするものという感じです。Dockerの話をする前に少し昔話を。一昔前に流行っていたのは、完全仮想化と呼ばれる技術でした。

## ハイパーバイザ型

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/4addbd99-a74f-58ef-bfdb-885d6493ad90.png)
[What is a Container? | Docker](https://www.docker.com/resources/what-container)より

上記はハイパーバイザ型の完全仮想化の概要図です。サーバにOSの代わりにハイパーバイザという仮想化ソフトウェア(VMware ESXiやXenなど)を動作させます。1台のサーバの上で、複数の仮想ハードウェア(仮想マシン)を動作、更にその仮想ハードウェアにOS/アプリケーションをインストールして動作させるという仕組みでした。イメージ的にサーバの上に、小さなサーバを複数並べる感じですね。

この仕組だと、仮想ハードウェアにCPU/Memory/Storageなどを固定(可変の場合もある)で割り当てる必要があるほか、ハードウェアをエミュレートしているため処理に無駄がありました。殆どのユーザは仮想ハードウェアが必要ではなく、本当に必要なのは仮想ハードウェアで動くアプリケーションでした。

そこで出てきたのが、より軽量なコンテナ型仮想化です。

## コンテナ型

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/51c38b55-9de4-c394-bc78-4d378f0a5708.png)
[What is a Container? | Docker](https://www.docker.com/resources/what-container)より

ということで、コンテナ方式(ここではDocker)ではアプリケーション部分をコンテナという単位で管理するようになりました。コンテナは独立した仮想ハードウェアとしてではなく、OSの1プロセスとして動きます...

Dockerを触り始める前までだったらこの説明だけで納得できるのですが、実際に触り始めると結構疑問が出てきます。

- コンテナってOS含まれないはずなのに、コンテナごとにUbuntu/CentOSとか違うディストリビューション動いてない？
- コンテナって仮想ハードウェアじゃないのに、コンテナごとにネットワークインターフェースとか持ってない？


[なぜDockerではホストOSと違うOSベースのコンテナイメージが動くのか](https://qiita.com/kirikunix/items/33414240b4cacee362da)
[Docker overview | Docker Documentation](https://docs.docker.com/engine/docker-overview/)
[Docker frequently asked questions (FAQ) | Docker Documentation](https://docs.docker.com/engine/faq/)


で答え合わせをすると

- Linux kernel自体は互換性あるので、必要なファイルシステム、ライブラリがあれば他のディストリビューションも動かせる
  - コンテナ内にはディストリビューションごとに必要なファイルシステム、ライブラリだけある。
  - 各コンテナ内の処理は、ホストOSのkernelで動いてるけど、互換性のおかげでディストリビューションごとの動きを再現できている。
- Linux kernelのnamespace/cgroupsを利用して、コンテナごとの独自設定や、ハードウェアのリソースをコンテナごとに割り当てている
  - namespace: プロセスごとに保持する情報を分ける機能。これによってコンテナごとに異なるネットワークインターフェース情報などを定義できる。
  - cgroups: プロセスごとにハードウェアリソースを割り当てる機能。コンテナごとに利用できるCPU/Memoryなどのリソースを制御する。

ということだそうです。Linux kernelすげー。

# Docker for Windows

あれ、WindowsってLinuxとkernel違うからLinux用のコンテナ動かなくない？

> コンテナーは、コンテナーホストとの間でカーネルを共有しているため、Windows で直接 Linuxのコンテナーを実行する方法はありません。

[Linux Containers on Windows | Microsoft Docs](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/deploy-containers/linux-containers)

Oh... 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/fd635ccc-39b0-3cb4-31f5-c42bc098d7f7.png)

[Moby VM の Linux コンテナー](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/deploy-containers/linux-containers#linux-containers-in-a-moby-vm)より

はい、Linuxのコンテナは[Hyper-V](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/about/)のMoby Linux VM上で実行されます。そうなりますよね。[Mac](http://docs.docker.jp/v1.12/engine/installation/mac.html)もほぼこれと同じ方式っぽいですね。ちょっとわかりにくいですが、図の「Windows Container Host」はVMじゃなくてWindows10を指しているみたいですね。

# Linux Containers on Windows

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/ac86b41c-4248-781f-0c0e-b15d1d06262f.png)
[Moby VM の Linux コンテナー](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/deploy-containers/linux-containers#linux-containers-in-a-moby-vm)より

LCOWとよばれる方式です。こちらはWindows/Linuxでそれぞれ分かれていたDocker Demonが一つになってます。これによって、Windows/Linux間で統合されていなかったnamespaceが統合され、Windows/Linuxコンテナを同時実行できるようになるようです。また、Moby Linux VMからUtility VMと呼ばれるVMを使用しています。現状Utility VMはコンテナを起動するごとに作成されてしましますが、LinuxKitコンポーネントの恩恵によりオーバヘッドは少ないようです。

(Moby ProjectおよびLinuxKit周りの知識がないとちょっと掘り下げできなそうですね)

こちらはまだ開発段階の機能らしいので、今回は使用しません。

[図解で理解できる（はず）Microsoftの仮想化技術――Windows上で稼働するLinux、動かしているのはどのテクノロジー？](https://www.atmarkit.co.jp/ait/articles/1710/24/news010_2.html)

# Dockerのエディション

[Windows 10 の windows と Linux のコンテナー | Microsoft Docs](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/quick-start/set-up-environment?tabs=Windows-Server)

公式ページを参考にDockerをインストール...あれ、この手順みんながよくインストールしている`Docker Desktop for Windows` とはちょっと違うような...ということでちょっと調べることに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/f61063df-874d-7085-1fc2-534a7d36cefc.png)

[Install Docker on Windows Server 2019 &#8211; 4sysops](https://4sysops.com/archives/install-docker-on-windows-server-2019/)より




調べてみたところ

- Dockerの基本コンポーネントに、Docker EngineとDocker Clientが存在する
  - Docker Engineには Community Edition(無料版　以下CE)と、Enterprise Edition(有償版　以下EE)が存在する
  - Docker EngineのEEはCEのスーパーセット(上位互換)である。([About Docker Engine - Community | Docker Documentation](https://docs.docker.com/install/)より)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/0a3696ff-ef95-6e4c-b769-de6ec334e081.png)
[Overview of Docker editions | Docker Documentation](https://docs.docker.com/install/overview/)より

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/dcad4dfa-e39f-0790-4c1f-f424a2831c32.png)

[About Docker Enterprise | Docker Documentation](https://docs.docker.com/ee/supported-platforms/)より

また、Docker Enterpriseと呼ばれる製品が存在しており、Docker EnterpriseはDocker Engine EEの機能に加え、セキュリティ/オーケストレーション/デスクトップ向け機能(Docker Desktop Enterprise)なども付与されている。

Microsoftの公式でインストールしていたものはDcoker Engine EEのインストール手順[^1]だったようです。Desktop向けのGUIや、docker-composeなどの機能も欲しかったのでDocker Desktop(Docker Engine CEを含む)をインストールすることにします。

# インストール手順

## Hyper-V の有効化

PowerShellを管理者権限で開き、Hyper-Vの機能を有効化します。

```powershell
PS C:\Users\xxx> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
```

機能を有効化するために再起動します。

```powershell
この操作を完了するために、今すぐコンピューターを再起動しますか?
[Y] Yes  [N] No  [?] ヘルプ (既定値は "Y"):
```

そのままEnterを押します。
再起動後、「プログラムと機能」を開いて有効化しているか確認してみます。

`設定` -> `アプリ` -> `プログラムと機能` -> `Windowsの機能の有効化または無効化`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/8caa5892-8dd9-b652-ae98-fe2289457eca.png)

有効化されていました。

[Windows 10 での Hyper-V の有効化 | Microsoft Docs](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)

## Dockerのインストール

[Get started with Docker for Windows | Docker Documentation](https://docs.docker.com/docker-for-windows/)

上記のリンクから `Docker Desktop for Windows` のインストーラーをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149438/58537407-ce16-10e7-efc3-4601ffd5f770.png)

インストーラを起動するとこの画面が開くので、「OK」ボタンを押してインストールを開始。
再起動後、PowerShellを管理者権限で開き、Dockerのバージョンを確認します。

```powershell
PS C:\Users\xxx> docker --version
Docker version 19.03.4, build 9013bf5

PS C:\Users\xxx> docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
```

問題なさそうです！

# 終わりに

既存の情報の整理や、気になった点を調べたりしてたせいで、あんまりDockerのコマンドなどは触れられませんでした。。。あと、Dockerのエディションは結構変更があってややこしいですね。

[^1]: [Install Docker Engine - Enterprise on Windows Servers | Docker Documentation](https://docs.docker.com/install/windows/docker-ee/)