Windows Server Containers を PowerShell で操作する #windows #docker
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
Windows Server Containers
前回の記事「Windows Server Containers を Docker で操作する」に引き続き、今回は PowerShell でコンテナを操作してみます。PowerShell を使う場合は、Docker デーモンは不要になります。
本稿では、以下の作業を PowerShell で行ってみたいと思います。
- コンテナの作成
- コンテナからコンテナイメージの作成
- コンテナイメージのエクスポート
なお、Windows Server 2016 TP3 の環境は、前回の記事で構築したものを使用します。
/lab/11385
コンテナを作成する
まずは、インストールされているコンテナイメージを調べてみます。このイメージは、セットアップスクリプトによってインストールされたものです。
PS C:\> Get-ContainerImage Name Publisher Version IsOSImage ---- --------- ------- --------- WindowsServerCore CN=Microsoft 10.0.10514.0 True
このイメージから、コンテナを作成します。コンテナの名前は MyContainer にし、コマンドの戻り値(コンテナオブジェクト)を $ctn という変数で受け取ります。この変数は、後の操作で使用します。作成時に -SwitchName パラメーターを指定して、仮想スイッチに接続します。
作成されたコンテナは、停止状態となっています。
PS C:\> $ctn = New-Container -Name MyContainer -ContainerImageName WindowsServerCore -SwitchName "Virtual Switch" PS C:\> $ctn Name State Uptime ParentImageName ---- ----- ------ --------------- MyContainer Off 00:00:00 WindowsServerCore
コンテナに追加したネットワークアダプタを確認するには、Get-ContainerNetworkAdapter を使うか、コンテナオブジェクト(この例では $ctn)の NetworkAdapters プロパティを参照することで可能です。
PS C:\> Get-ContainerNetworkAdapter $ctn Connected : True DynamicMacAddressEnabled : True Id : Microsoft:1F377C23-0DCA-48C7-B8EA-6FD2EB2F9112\32CDD3C5-58E3-44BD-9A50-CC7B1F3F2A2D MacAddress : 000000000000 Name : Network Adapter SwitchId : 92c176c6-94c7-47f7-b371-87ebda987e25 SwitchName : Virtual Switch CimSession : CimSession: . ComputerName : SV2016 IsDeleted : False
コンテナ内の OS に変更を加える
コンテナを開始します。
PS C:\> Start-Container $ctn PS C:\> $ctn Name State Uptime ParentImageName ---- ----- ------ --------------- MyContainer Running 00:00:05.6280000 WindowsServerCore
コンテナの PowerShell session に入ります。
PS C:\> Enter-PSSession -ContainerId $ctn.Id -RunAsAdministrator [6ff0a690-e8c]: PS C:\Windows\system32>
ユーザーを作成します。名前は CTN とし、適当なパスワードを設定します。その後、Administrators グループへ追加します。
net user(ユーザー一覧表示)でホスト名が取得できずにエラーとなっていますが、Windows コンテナの不具合(実装がまだ不完全)と思われます。
[6ff0a690-e8c]: PS C:\Windows\system32> net user /add CTN The command completed successfully. [6ff0a690-e8c]: PS C:\Windows\system32> net user CTN Password4Me The command completed successfully. [6ff0a690-e8c]: PS C:\Windows\system32> net localgroup Administrators /add CTN The command completed successfully. [6ff0a690-e8c]: PS C:\Windows\system32> net user User accounts for \\ <- ホスト名が取得できていない ------------------------------------------------------------------------------ Administrator CTN DefaultAccount Guest The command completed with one or more errors. [6ff0a690-e8c]: PS C:\Windows\system32> net user CTN User name CTN Full Name Comment User's comment Country/region code 000 (System Default) Account active Yes Account expires Never Password last set 9/9/2015 3:30:24 PM Password expires 10/21/2015 3:30:24 PM Password changeable 9/9/2015 3:30:24 PM Password required Yes User may change password Yes Workstations allowed All Logon script User profile Home directory Last logon Never Logon hours allowed All Local Group Memberships *Administrators *Users Global Group memberships *None The command completed successfully.
簡単なテキストファイルを作成します。
[6ff0a690-e8c]: PS C:\Windows\system32> echo "This is my container." > C:\Users\Public\Documents\readme.txt [6ff0a690-e8c]: PS C:\Windows\system32> cat C:\Users\Public\Documents\readme.txt This is my container.
適当なレジストリキーを作成します。ここでは、HKLM\SOFTWARE に CTN というキーを追加し、そこに Version = 1.0.0.0 という 値とデータを追加します。
[6ff0a690-e8c]: PS C:\Windows\system32> New-Item "HKLM:\SOFTWARE\CTN" Hive: HKEY_LOCAL_MACHINE\SOFTWARE Name Property ---- -------- CTN [6ff0a690-e8c]: PS C:\Windows\system32> New-ItemProperty "HKLM:\SOFTWARE\CTN" "Version" -Value "1.0.0.0" -PropertyType String Version : 1.0.0.0 PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\CTN PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE PSChildName : CTN PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry
コンテナを停止する
exit でコンテナの PowerShell session から抜けた後、コンテナを停止します。
[6ff0a690-e8c]: PS C:\Windows\system32> exit PS C:\> Stop-Container $ctn PS C:\> $ctn Name State Uptime ParentImageName ---- ----- ------ --------------- MyContainer Off 00:00:00 WindowsServerCore
停止したコンテナから、新しいコンテナイメージを作成する
先ほど停止したコンテナのオブジェクトと、イメージ名、発行者、バージョンを指定して、新しいコンテナイメージを作成します。
PS C:\> New-ContainerImage $ctn -Name MyImage -Publisher CTN -Version 1.0.0.0 Name Publisher Version IsOSImage ---- --------- ------- --------- MyImage CN=CTN 1.0.0.0 False PS C:\> Get-ContainerImage -Name MyImage | Select-Object * Publisher : CN=CTN Name : MyImage Version : 1.0.0.0 IsOSImage : False ParentImage : ContainerImage (Name = 'WindowsServerCore') [Publisher = 'CN=Microsoft', Version = '10.0.10514.0'] FullName : CN=CTN_MyImage_1.0.0.0 CimSession : CimSession: . ComputerName : SV2016 IsDeleted : False
作成したイメージでコンテナを作成する
作成したイメージでコンテナを作成します。コンテナオブジェクトは $ctn2 という変数で受け取ります。作成後、コンテナを開始して、コンテナの PowerShell session に接続します。
PS C:\> $ctn2 = New-Container -Name MyContainer2 -ContainerImageName MyImage -SwitchName "Virtual Switch" PS C:\> Start-Container $ctn2 PS C:\> Get-Container Name State Uptime ParentImageName ---- ----- ------ --------------- MyContainer2 Running 00:00:06.8210000 MyImage MyContainer Off 00:00:00 WindowsServerCore PS C:\> Enter-PSSession -ContainerId $ctn2.Id -RunAsAdministrator [2881d8eb-41c]: PS C:\Windows\system32>
CTN ユーザーが存在していることを確認します。Administrators グループに追加されており、パスワードの有効期限なども同じになっています。
[2881d8eb-41c]: PS C:\Windows\system32> net user CTN User name CTN Full Name Comment User's comment Country/region code 000 (System Default) Account active Yes Account expires Never Password last set 9/9/2015 3:30:24 PM Password expires 10/21/2015 3:30:24 PM Password changeable 9/9/2015 3:30:24 PM Password required Yes User may change password Yes Workstations allowed All Logon script User profile Home directory Last logon Never Logon hours allowed All Local Group Memberships *Administrators *Users Global Group memberships *None The command completed successfully.
テキストファイルを確認します。
[2881d8eb-41c]: PS C:\Windows\system32> cat C:\Users\Public\Documents\readme.txt This is my container.
レジストリキー HKLM\SOFTWARE\CTN の値とデータを確認します。Version=1.0.0.0 が設定されています。
[2881d8eb-41c]: PS C:\Windows\system32> Get-ItemProperty "HKLM:\SOFTWARE\CTN" "Version" Version : 1.0.0.0 PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\CTN PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE PSChildName : CTN PSDrive : HKLM PSProvider : Microsoft.PowerShell.Core\Registry
コンテナイメージをエクスポートする
先ほど作成したコンテナイメージ MyImage をエクスポートします。エクスポートすると、ファイルシステムやレジストリへの変更がパッケージ化され、Windows ランタイム(Windows ストア)アプリパッケージ形式(.appx)で保存されます。
詳しくは、以下を参照してください。
https://msdn.microsoft.com/ja-jp/library/windows/apps/hh464929.aspx
appx ファイルは、親イメージ WindowsServerCore の差分になります。よって、他のコンテナホストへインポートする場合は、そのホスト上に WindowsServerCore イメージが予め用意されていないと、エラーになります。
PS C:\> Export-ContainerImage -Name MyImage -Path C:\ PS C:\> ls -Filter *.appx Directory: C:\ Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2015/09/09 17:13 281571897 CN=CTN_MyImage_1.0.0.0.APPX
エクスポートしたパッケージの中身を確認する
アプリパッケージの中身を確認してみます。appx は zip 形式での圧縮ファイルなので、拡張子を .zip へ変更すれば、簡単にパッケージ内部を確認できます。
または、Windows SDK に付属の makeappx.exe を使用してアンパックします。
https://msdn.microsoft.com/en-us/library/windows/desktop/hh446767(v=vs.85).aspx
拡張子を変更する方法が楽ですが、ここでは makeappx.exe を使ってみます。以下のコマンドで Windows Standalone SDK for Windows 10 のインストーラをダウンロードし、実行します。
※sdksetup.exe 実行後は、すぐにプロンプトが表示されますが、インストーラはバックグラウンドで動作しています。インストールが終わったかどうかを確認するには、sdksetup.exe のプロセスが終了したことを確認します。
PS C:\> wget -uri https://go.microsoft.com/fwlink/p/?LinkId=619296 -OutFile C:\sdksetup.exe PS C:\> .\sdksetup.exe /features OptionId.WindowsSoftwareDevelopmentKit /q
makeappx.exe は、C:\Program Files (x86)\Windows Kits\10\bin\x64 配下にあります。これを実行して、イメージを C:\myimage へアンパックします。
PS C:\Program Files (x86)\Windows Kits\10\bin\x64> .\makeappx.exe unpack /p C:\CN=CTN_MyImage_1.0.0.0.APPX /d C:\myimage /nv …
アンパックされたファイルの中に、readme.txt のペイロードファイルがあることを確認できます。AppManifest.xml には、コンテナイメージのバージョンや依存関係などが定義されています。
PS C:\> ls -Path C:\myimage Directory: C:\myimage Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2015/09/09 17:18 Files d----- 2015/09/09 17:20 Hives -a---- 2015/09/09 17:18 1836912 AppxBlockMap.xml -a---- 2015/09/09 17:18 2010 AppxManifest.xml -a---- 2015/09/09 17:20 600 tombstones.txt PS C:\> ls -Recurse -Path C:\myimage -Filter readme.txt Directory: C:\myimage\Files\Users\Public\Documents Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2015/09/09 17:18 264 readme.txt PS C:\> cat C:\myimage\Files\Users\Public\Documents\readme.txt _ _ ー‹ _ _・E , __ __ __ __ _ ・E_ _ __ __ __ __ __ __ _ ___ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ _ 0 T h i s i s m y c o n t a i n e r .
レジストリハイブは Hives フォルダ配下にあります。Software_Delta に CTN キーが記録されています。
PS C:\> ls -Path C:\myimage\Hives Directory: C:\myimage\Hives Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2015/09/09 17:20 20480 DefaultUser_Delta -a---- 2015/09/09 17:20 12288 Sam_Delta -a---- 2015/09/09 17:20 8192 Security_Delta -a---- 2015/09/09 17:20 1544192 Software_Delta -a---- 2015/09/09 17:20 90112 System_Delta
まとめ
PowerShell でコンテナの操作をしてみましたが、Docker とは設計思想の違いが感じられました。例えば、コンテナの起動時に、PowerShell ではコマンドの指定が不要であり、常にデタッチド・モードで起動しますが、Docker ではコンテナ OS で動かすコマンドの指定が必要です。ただし、どちらを使用しても最終的にはコンテナの起動やイメージの管理ができるので、馴染みやすい方を使用すればよいでしょう。
あと、現状では PowerShell と Docker 間でのコンテナやイメージの共有ができないので、「PowerShell で作成したイメージを、docker コマンドで Docker のレジストリへプッシュする」 といったことはできません。ここの改善にも期待したいところです。
最後に、検証環境で発生した不具合と思われる事象をまとめておきます。
- コンテナ OS のホスト名の取得
docker inspection, hostname コマンド, $env:COMPUTERNAME で返ってくる値が異なる。 - 長い処理は応答が返ってこなくなる(固まる)
Get-WindowsFeature, Add-WindowsFeature など。機能の追加ができなかった。
- リモートデスクトップ接続
https://msdn.microsoft.com/virtualization/windowscontainers/about/work_in_progress
このページの Accessing windows server container with Remote Desktop を参考に試したが、以下のエラーで接続できず。
- コンテナ OS で netstat コマンドを実行すると、ホスト OS や別のコンテナ OS の状態も返ってくる。
[2881d8eb-41c]: PS C:\Windows\system32> netstat -ano Active Connections Proto Local Address Foreign Address State PID TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 2220 TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 3140 TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 632 TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 TCP 0.0.0.0:2179 0.0.0.0:0 LISTENING 1936 TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 5176 TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 860 TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 4356 …
参考文献
Windows Containers
https://msdn.microsoft.com/virtualization/windowscontainers/containers_welcome
アプリパッケージと展開
https://msdn.microsoft.com/ja-jp/library/windows/desktop/hh464929.aspx
レジストリ構造
https://msdn.microsoft.com/ja-jp/library/Cc776231(v=WS.10).aspx