しばたテックブログ

PowerShellを中心に気分で書いている技術ブログです。

Windows 10のコンテナーとDocker for Windowsを共存させる

いろいろあってちょっと遅くなりましたが

stknohg.hatenablog.jp

の続きです。

2016/10/18 追記

バージョン 1.12.2 Bata26よりDocker for Windowsdockerd.exeが同梱される様になりGUIでDocker Engineの切り替えができる様になりました。

stknohg.hatenablog.jp

dockerd.exeが同梱されているバージョンであれば以降の手順は不要です。

Windows 10コンテナーのDockerとDocker for Windows

念のため最初に触れておきますが、Windows 10コンテナーのDockerDocker for Windowsは全くの別物です。

Windows 10コンテナーのDockerWindowsイメージを扱い、Docker Engineとしてdockerd.exeが提供されています。

Docker for WindowsDocker Toolboxの流れをくむツールで、Hyper-V上にLinux仮想マシン(Alpine Linux)を立て、その仮想マシン上にあるDocker EngineがLinuxイメージを扱います。
そして仮想マシンと通信するプロキシサーバーとしてcom.docker.service等が提供されています。

ちなみにクライアントであるdocker.exeは両者共通の様です。

Windows 10コンテナーとDocker for Windowsを共存させる

以上をふまえてWindows 10コンテナーとDocker for Windowsを共存させる方法について説明していきます。

0. はじめに

今回は前回の手順でWindows 10コンテナーのDockerをインストールした後にDocker for Windowsをインストールする手順とします。

1. Windows 10コンテナーのDockerの設定変更

理由は後述しますが、デフォルト設定ではWindows 10コンテナーのDockerとDocker for Windowsを同時に起動することはできません。
このため最初にWindows 10コンテナーのDockerサービスを停止しておきます。

# Windows 10コンテナーのDockerサービス(dockerd.exe)の停止
Stop-Service docker

また、現時点ではDocker for Windowsのインストール先はC:\Program Files\Docker\Docker固定です。
部分的にインストールディレクトリが被ってしまうのでWindows 10コンテナーのDockerサービスのインストールディレクトリを変えいておいた方が無難です。

本エントリではインストールディレクトリをC:\Program Files\DockerWinContainerに変更しておきます。

# リネーム
Move-Item 'C:\Program Files\Docker\' 'C:\Program Files\DockerWinContainer\'

# サービス解除+再登録
cd 'C:\Program Files\DockerWinContainer\'
.\dockerd --unregister-service
.\dockerd --register-service

2. Docker for Windowsのインストール

続けてDocker for Windowsをインストールします。
手順はMSIインストーラーを実行して画面の指示に従うだけなので特に私から言うことは無い感じです。

インストールするとPATHにdocker.exeのあるC:\Program Files\Docker\Docker\Resources\binが追加されるので、Windows 10コンテナーのDockerとどちらを優先させるかは適当に設定してくだい。

今回は前回設定したPATHを削除してC:\Program Files\Docker\Docker\Resources\binだけを見る様にします。
これはDocker for Windowsに付いているdocker.exeを使うということになります。

3. Windows 10コンテナーとDocker for Windowsを共存させる

先ほど言った様にデフォルト設定ではWindows 10コンテナーのDockerとDocker for Windowsを同時に起動することはできません。
理由は単純で、どちらのDockerもデフォルトでは名前付きパイプで待ち受けを行うためポートの競合が起きてしまうのが原因です。

なのでWindows 10コンテナーとDocker for Windowsを共存させるにはポートの競合が起きない様にどちらかの待ち受けポートを変えてやれば良いです。

今回はWindows 10コンテナーのDockerの方の設定を変えて共存させます。
Dockerの設定についてはMSDNの以下のサイトに詳しく記載されています。

msdn.microsoft.com

こちらによれば、Windows 10コンテナーのDocker Engineの設定はC:\ProgramData\Docker\config\daemon.jsonに設定します。
デフォルトではdaemon.jsonはありませんので新規に作る必要があります。

待ち受けの設定はhostsキーとなり、例えば以下の様にするとTCP 2375番ポートで待ち受けする様になります。

{
    "hosts": ["tcp://0.0.0.0:2375"]
}

PowerShellからだと以下の様な感じでファイルを追加できます。

# -Encodingはutf8だとBOM付きになるからダメ
@"
{
    "hosts": ["tcp://0.0.0.0:2375"]
}
"@ | Out-File -FilePath (Join-Path $env:ProgramData "Docker\config\daemon.json") -Encoding default

これでポートの競合を回避できます。
あとはWindows 10コンテナーのDocker、Docker for Windows両方を起動すればOKです。

4. 確認と接続先の切り替え

最後に起動の確認と両ツールの切り替え方法について説明します。

最初にサービスを確認して両ツールが起動されているのを確認します。

PS C:\> Get-Service *docker*

Status   Name               DisplayName
------   ----               -----------
Running  com.docker.service Docker for Windows Service
Running  docker             Docker Engine

この状態でdocker versionを実行してみます。

# docker.exeはDocker for Windowsについているやつ
PS C:\> where.exe docker
C:\Program Files\Docker\Docker\Resources\bin\docker.exe

# docker version
PS C:\> docker version
Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 21:04:48 2016
 OS/Arch:      windows/amd64
 Experimental: true

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 21:04:48 2016
 OS/Arch:      linux/amd64
 Experimental: true

OS/Arch: linux/amd64とある様にDocker for Windowsに接続していることがわかります。
これはdocker.exeのデフォルトが名前付きパイプで接続する様になっているためです。

(Windowsに限った話ではないですが)Dockerの接続先を変更するにはDOCKER_HOST環境変数を設定してやれば良いです。
前項でWindows 10コンテナーのDocker EngineはTCP 2375版ポートで待ち受けする様にしましたのでDOCKER_HOST環境変数を以下の様に変更します。

$env:DOCKER_HOST="tcp://localhost:2375"

改めてdocker versionを実行すると以下の様に結果が変わります。

# 接続先変更
PS C:\> $env:DOCKER_HOST="tcp://localhost:2375"

# docker version
PS C:\> docker version
Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 21:04:48 2016
 OS/Arch:      windows/amd64
 Experimental: true

Server:
 Version:      1.13.0-dev
 API version:  1.25
 Go version:   go1.6.3
 Git commit:   85428a1
 Built:        Fri Aug  5 14:55:24 2016
 OS/Arch:      windows/amd64

OS/Arch: windows/amd64と接続先が切り替わっていることがわかります。

最後に

とりあえずこんな感じです。

ここまでの流れでわかるかと思いますが、クライアント目線で見た場合、Windows 10コンテナーのDockerとDocker for Windowsは単純に個別のDocker Engineであり、片方はLinuxイメージを、もう片方はWindowsイメージを扱うサーバーという体になります。

あとWindows 10コンテナーのDockerは正式にはなんて呼称すれば良いんでしょうね?
ブログ書いてて非常につらかったのでわかる方いましたら是非教えてください。