Windows Server 1709上でLinuxコンテナを動かす（lcow）

この記事は、「[クラウド時代のシステム管理](https://www.takanyan.net/win1709-lcow/)」の記事を転記したものです。
Windows ServerのHyper-Vと最新のDocker、LinuxKitを組み合わせて、Windows Server上でLinuxコンテナを動かす「Linux Container on Windows」（略してLCOW）を使う方法について解説します。2017年10月14日に私が発表した資料から、バージョンやドキュメントの場所が変わっているので、<a href="https://www.slideshare.net/anikundesu/windows-server-2016linux-80799410" rel="noopener" target="_blank">当時の登壇資料</a>とはURLのリンク先が異なっています。

<!--more-->

## 1. Hyper-VコンテナーとLinuxKitについて

### 1-1. Hyper-Vコンテナーとは

Hyper-VコンテナーはWindowsのコンテナ機能の一つで、1つのコンテナごとに1つのOSがあり、Docker APIによる簡単操作とHyper-VによるOS丸ごとの分離によるセキュリティを両立しています。コンテナ上のプロセスの分離のされ方のイメージは次の図のようになります。

<a href="https://www.takanyan.net/wp-content/uploads/2018/02/hyper-v-container-windows.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/hyper-v-container-windows.png" alt="Hyper-Vコンテナーのプロセス分離イメージ" class="aligncenter size-full wp-image-416" /></a>

### 1-2. LinuxKitとは

LinuxKitはコンテナを起動するために最低限必要なLinux機能のみを実装した小さなLinuxイメージです。Hyper-Vで利用するLinuxKitの実体は、Hyper-V仮想マシン構成に必要なEFIイメージとRAMディスクイメージの2つのファイルです。Hyper-Vコンテナー上でLinuxKitを利用する場合のコンテナ内プロセスの分離イメージは次の図のようになります。

<a href="https://www.takanyan.net/wp-content/uploads/2018/02/hyper-v-container-linuxkit.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/hyper-v-container-linuxkit.png" alt="Hyper-Vコンテナ上でLinuxKitを使う場合のプロセス分離イメージ" class="aligncenter size-full wp-image-417" /></a>


## 2. Linux Container on Windows (LCOW)のセットアップ

Linux Container on Windowsを利用するにはWindows Server version 1709もしくはWindows10 Version 1709以上（Pro）とHyper-Vの機能が必要になります。ここでは、Windows Server version 1709を利用した場合のセットアップ手順を紹介します。手順の流れは<a href="https://github.com/linuxkit/lcow" rel="noopener" target="_blank">github上の「LinuxKit based LCOW images」のREADME</a>をもとに行います。 

### 2-1. Windows Server version 1709上での機能の有効化

Windows Server version 1709ではGUIが廃止されたServer Core版（とコンテナ専用のNano Server）のみが提供されています。このあたりの詳細は<a href="https://docs.microsoft.com/ja-jp/windows-server/get-started/get-started-with-1709" rel="noopener" target="_blank">マイクロソフトのドキュメントサイトなどにも解説があります</a>。

まず、Windows Server 1709をISOからインストールし、インストール後は<code>sconfig</code>コマンドを使ってホスト名、IP（固定IPに設定）、Remote Desktopの有効化を行います。

<a href="https://www.takanyan.net/wp-content/uploads/2018/02/sconfig.png"><img src="https://www.takanyan.net/wp-content/uploads/2018/02/sconfig.png" alt="sconfigコマンドによる初期設定画面" class="aligncenter size-full wp-image-420" /></a>

初期設定を実施後、Hyper-Vとコンテナー機能を有効にするため、Powershellを起動して以下のコマンドを実行します。その後、OS再起動をします。

```PowerShell
C:\> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\> Install-WindowsFeature Hyper-V,Containers –IncludeManagementTools
（中略）
PS C:\> Restart-Comptuer -Force
```


### 2-2. LinuxKitの準備

LCOW対応LinuxKitイメージを<a href="https://github.com/linuxkit/lcow/releases" rel="noopener" target="_blank">githubのLCOWリリースページ</a>に記載のリンクからダウンロードします。本記事執筆時点では、「v4.12.14-2a3a94cc」がPre-Releaseとして公開されており、ページの下のほうにrelease.zipというリンクがあります。このrelease.zipのURLを控えておきます。このファイルをWindows Server version 1709に展開するために、以下のコマンドを実行します。

```PowerShell
PS C:\> mkdir "$Env:ProgramFiles\Linux Containers"
PS C:\> Invoke-WebRequest -UseBasicParsing -OutFile release.zip https://github.com/linuxkit/lcow/files/1482864/release.zip
　※最後の引数にあるリンクは、事前に確認したrelease.zipファイルのURLです。
PS C:\> Expand-Archive release.zip -DestinationPath "$Env:ProgramFiles\Linux Containers\.“
PS C:\> rm release.zip
```

### 2-3. LCOW対応のDocker環境のセットアップ

LCOW対応のDockerデーモンおよびDockerクライアントは、Docker本家からダウンロードします。下記はDocker本件のNightly Buildからダウンロードしているため、毎日更新されます。また、コンテナイメージを保存するフォルダもこのタイミングで作成します。

```PowerShell
PS C:\> mkdir “$Env:ProgramFiles\lcow”      ←docker実行ファイルのインストールフォルダ作成
PS C:\> cd "$Env:ProgramFiles\lcow"
PS C:\Program Files\lcow\> Invoke-WebRequest -UseBasicParsing -OutFile dockerd.exe https://master.dockerproject.org/windows/x86_64/dockerd.exe
PS C:\Program Files\lcow\> Invoke-WebRequest -UseBasicParsing -OutFile docker.exe https://master.dockerproject.org/windows/x86_64/docker.exe
PS C:\Program Files\lcow\> mkdir C:\lcow    ←コンテナイメージの保存フォルダを事前作成
```

ここまででLCOW対応Dockerの準備ができたので、デーモンを起動します。本手順では実行していませんが、もし通常のWindows Serverコンテナー用にPowerShell経由でDockerクライアントをインストールしていた場合、普通に起動するとポート番号がかぶってしまうため、名前付きパイプとしてデーモンを公開するようにします。また、Dockerデーモンをコンソールで起動すると大量の出力が出るため、別Windowを立ち上げてから行います。

```PowerShell
PS C:\Program Files\lcow\> Start-Process powershell
（別ウィンドウでPowerShellが起動）

PS C:\Users\Administrator> cd 'C:\Program Files\lcow'
PS C:\Program Files\lcow> .\dockerd.exe -D --experimental -H "npipe:////./pipe//docker_lcow" --data-root c:\lcow
（大量の出力が出る。プロンプトはずっと返ってこない）
```

以前は環境変数としてLCOW対応を許可する「LCOW_SUPPORTED」という変数を定義していましたが、<code>master-dockerproject-2018-01-20, build 44a1168a</code>以降のビルドでは不要となりました。

## 3. コンテナを起動してみる

以上でLCOWの準備ができましたので、Linux、Windowsそれぞれのコンテナを起動してみます。

### 3-1. Linuxベースのコンテナの起動

LinuxベースかWindowsベースかを指定する<code>--platform</code>引数を指定します。Linuxベースのコンテナの場合は以下の通りです。

```
PS C:\Program Files\lcow> .\docker -H "npipe:////./pipe//docker_lcow" run -it --rm --platform linux busybox sh
（イメージのダウンロード）
/ # uname -a
Linux 00d86d6ee862 4.12.14-linuxkit #1 SMP Mon Sep 25 12:27:00 UTC 2017 x86_64 GNU/Linux
/ #
/ # exit
PS C:\Program Files\lcow>
```

### 3-2. Windowsベースのコンテナの起動

続けてWindowsベースとしてnanoserverを起動してみます。引数に<code>--platform windows</code>を指定します。

```PowerShell
PS C:\Program Files\lcow> .\docker -H "npipe:////./pipe//docker_lcow" run -it --rm --platform windows microsoft/nanoserv
er:1709
（イメージのダウンロード）
Microsoft Windows [Version 10.0.16299.192]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\>
C:\> exit
PS C:\Program Files\lcow>
```

以上の2つのコンテナを起動した後、コンテナイメージとしてLinux、Windowsの両方が一つの画面に並んでいることを確認します。

```PowerShell
PS C:\Program Files\lcow> .\docker -H "npipe:////./pipe//docker_lcow" images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
busybox                latest              5b0d59026729        11 days ago         3.41MB
microsoft/nanoserver   1709                c4f1aa3885f1        4 weeks ago         303MB
```

以上で、Linux Container on Windowsのセットアップと動作確認ができました。