検索
連載
その知識、ホントに正しい? Windowsにまつわる都市伝説(150):

Windowsコンテナはデスクトップの夢を見ない

Windows Server 2016およびWindows 10 バージョン1607からは、Dockerのサポートが追加されました。WindowsがDockerに対応したことで、“デスクトップアプリをDockerでコンテナ化したい”という声を聞いたことがありますが、実現不可能なことです(少なくとも現時点では)。チャレンジすることは止めませんが、無駄な努力に終わると思います。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Windowsにまつわる都市伝説」のインデックス

Windowsにまつわる都市伝説

LinuxならGUIアプリをコンテナ化できるのに、Windowsだとなぜできないの?

 Dockerの技術は、主にクラウドアプリやサービスの開発現場で、開発とデプロイのスピードアップを図るために使用される技術です。GUIを持つデスクトップアプリのコンテナ化はそもそも想定されていません。

 Linuxデスクトップの場合、X Window Systemの技術を利用してDockerコンテナ側でアプリケーション(Xクライアント)を実行し、Linuxデスクトップ側(Xサーバ)でそのGUIを表示するということは可能なようです(実際に試したことはありません)。

 例えば、この方法でWebブラウザをDockerコンテナで動かすということができるようです。これは興味深いアイデアですが、Linuxデスクトップ側のXサーバに完全に依存しているため、完全なGUIアプリのコンテナ化とはいえないでしょう。

 WindowsでGUIアプリを実行するには、ローカルコンソールに対話的にログオンするか、リモートデスクトップ接続のセッションにログオンしてデスクトップと対話する(あるいは「Microsoft RemoteApp」プログラムを通して対話する)必要があります。Windowsの現在の実装では、ローカルの対話的なログオンとリモートデスクトップ接続の両方が「Remote Desktop Services」(TermService)に依存しています。

 以下の画面1は、「Windows Server, version 1909」で構築したDockerコンテナホストで、Windows Server Core バージョン1909のベースOSイメージ(mcr.microsoft.com/windows/servercore:1909)のWindowsコンテナを実行しているところです。

画面1
画面1 Windowsコンテナでは、Remote Desktop Services、Serverサービス、Windows Defender Firewallサービスは無効化されているか、機能しない

 Remote Desktop Services(TermService)のサービスは停止状態で、起動しようとしてもスタートアップが無効化されていて失敗します。Server(lanmanserver)サービスやWindows Defender Firewall(mpssvc)サービスも無効化されているか機能しません。

 そのため、Windowsコンテナはファイル共有を提供することもできませんし、「Windows Defenderファイアウォール」による保護もありません(WindowsコンテナはNATネットワークとホスト側のWindows Defenderファイアウォールで保護されます)。この制約はライセンス上の制約なのか、技術的な制約なのか分かりません。

 次に画面2を見てください。同じように実行したWindowsコンテナとコンテナホストのそれぞれのプロセス一覧を表示したものです。GUIを利用できるコンテナホスト側では、Windows Sysinternalsの「Process Explorer」(procexp.exe)を使用しました。GUIを使用できないWindowsコンテナでは「PsList」(pslist.exe)を使用しています。

画面2
画面2 Windowsコンテナのプロセスツリー。通常のWindowsにはログオンごとに存在するはずの「winlogon.exe」と「dwm.exe」プロセスが存在しない

 なお、Windowsコンテナ内でWindows Sysinternalsのツールを実行する場合は、初回実行時の「License Agreement」ウィンドウが表示されないように、「-accepteula」オプションを追加する必要があります。そうしないと、異次元の世界にダイアログボックスが表示され、返ってこないでしょう(異次元の世界は冗談です)。

 「プロセス分離モード」(以前は「Windows Serverコンテナ」と呼ばれていたもの)でWindowsコンテナを実行すると、ホスト側で「Wininit.exe」(Windowsスタートアップアプリケーション)プロセスが新たに生成され、コンテナのユーザー環境が準備されます。

 最終的に「docker run」コマンドに指定したコンテナで実行するコマンド(この例の場合は「cmd.exe」)は、新たな「Wininit.exe」のプロセスツリーの中に生成される「CExecSvc.exe」プロセスのさらに子/孫プロセスとして実行されます。ホスト側のコンテナ用の「Wininit.exe」のプロセスツリーは、プロセスIDを含め、コンテナ側に見えるプロセスツリーと一致しています。

 ただし、重要な点が幾つかあります。このプロセスツリーには、対話型ログオンとログオフを担当する「winlogon.exe」(Windowsログオンアプリケーション)プロセスが存在しません。また、デスクトップとウィンドウの描画と合成を担当する「dwm.exe」(デスクトップウィンドウマネージャー)も存在しません。つまり、コンテナには対話的にログオンする方法も、デスクトップも存在しないのです。

Windows 10 Enterpriseのフルイメージ? Windowsイメージの役割とは?

 WindowsコンテナのベースOSイメージとしては、「Windows Server Core」(mcr.microsoft.com/windows/servercore)と「Nano Server」(mcr.microsoft.com/windows/nanoserver)があります。「Windows Server 2019(1809)」がリリースされたときから、「Windows(mcr.microsoft.com/windows)」という巨大なイメージが利用可能になりました。このイメージでWindowsコンテナを実行し、ゲストOSの情報を調べてみると、「Windows 10 Enterprise」のイメージであり、Remote Desktop Servicesは実行中の状態でした。

 また、Windows Server 2019(1809)のコンテナ関連の新機能の1つに、Docker Engine 19.03以降におけるWindowsコンテナでのGPUデバイスのサポートがあります。

 この2つの話を目にすると、Windows 10 Enterpriseのデスクトップ全体、あるいはGUIアプリのコンテナ化の可能性について期待を高める人がいるかもしれません。

 しかし残念でした。Windowsイメージでは、Remote Desktop Servicesは実行中の状態でしたが、ポート3389ではリスンしていない状態でした。

 レジストリを見ると「fDenyTSConnections」でリモート接続が無効になっていたので、有効化した上でサービスを再起動してみましたが、ポート3389でリスンすることはありませんでした(画面3)。そして、GPUデバイスのサポートは、機械学習の高速化などを目的とした、GPUプログラミングのためのものです。決してグラフィックス表示を想定したものではありません。

画面3
画面3 2018年末に突如登場した「Windowsイメージ」は、Windows 10 Enterpriseから構築されたイメージ。最新バージョンのサイズはWindows Server Coreが4.58GB、Nano Serverが2.58GBに対して、Windowsは12.7GB

 Windowsイメージの用途は以下の公式ドキュメントで説明されていますが、Windows Server CoreのWindowsコンテナでアプリを開発するには解決できない依存関係がある場合に、完全なWindows APIセットを提供するものです。

他にリモート接続の方法はないのか、探してみた

 リモートデスクトップ接続以外に、ネットワーク経由でWindowsコンテナのOS環境にリモート接続(もうGUIは関係なく)する方法がないか、幾つか試してみました。

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る