プロキシ経由でksocketを使用する

(文言およびスクリーンショットを新UIのものに変更しました。2020/1/14)

ksocket を使用するためには、 ksocketとKompira cloudの間でwebsocket通信を確立する必要があります。
ここでは、インターネットに接続するためにプロキシサーバを経由するような環境下で ksocket を実行するための方法を解説します。

ksbridge について

ksbridge は、プロキシサーバを経由する環境下で ksocketとKompira cloud間の通信を行えるようにするミドルウェアです。
以下の図のように、ksocketとKompira cloudの間のブリッジとして動作します。
この図では ksocketとksbridge間の通信に8080ポート、ksbridgeとプロキシサーバ間の通信に3128ポートを例として記載していますが、設定により変更可能です。

+---------------------------------------------+
| intranet                                    |
|                                             |
| +--------------------------------+          |
| | localhost                      |          |
| | +---------+      +----------+  |      +-------+     +---------------+
| | | ksocket | 8080 | ksbridge |  | 3128 | proxy | 443 | Kompira cloud |
| | |         |<---->|          |<-=------=-------=---->|               |
| | |         |  IN  |          |  | OUT  |       |     |               |
| | |         |      |          |  |      |       |     |               |
| | |         |      |          |  |      |       |     |               |
| | +---------+      +----------+  |      +-------+     +---------------+
| +--------------------------------+          |
|                                             |
+---------------------------------------------+

ksbridge を使用する場合、こちらのページ からダウンロードしてください。

使用方法

ksbridge の起動

ksocket をインストールしたサーバに ダウンロードしたksbridgeのファイルを配置し、展開してください。

$ tar zxf ksbridge_0.2.0_linux_x86_64.tar.gz
$ cd ksbridge_0.2.0_linux_x86_64
$ ls
ksbridge  README.md

ファイルが展開できたら、ksbridgeを起動してみましょう。
起動の前に、使用しているプロキシサーバのアカウント情報とポート番号を確認してください。

ここでは、以下のような環境であると仮定して、対応したksbridgeの起動コマンドを記載します。

項目
Kompira cloudのスペースURL yourspace.cloud.kompira.jp
プロキシサーバURL your.proxyserver.co.jp
プロキシサーバのポート番号 3128
プロキシサーバのアカウント名 username
プロキシサーバのアカウントパスワード password
ksocketとksbridge間の接続に使用するポート 8080
$ ./ksbridge -bind 127.0.0.1:8080 -host yourspace.cloud.kompira.jp -proxy http://username:password@your.proxyserver.co.jp:3128
********************************************************************************
ksbridge - Tiny websocket connection bridge server

  listen: ws://127.0.0.1:8080/api/ksocket/connect
  server: wss://yourspace.cloud.kompira.jp/api/ksocket/connect
  proxy:  http://username:password@your.proxyserver.co.jp:3128

********************************************************************************

プロキシサーバへのアクセスにアカウントが必要ない場合は、以下のように指定します。

$ ./ksbridge -bind 127.0.0.1:8080 -host yourspace.cloud.kompira.jp -proxy http://your.proxyserver.co.jp:3128

実行すると、ksbridgeはksocketからの通信を待つ状態となります。

ksocket の設定

次に、ksocketの設定を行います。 まずは、 ksocketドキュメント を参照し、ksocketのインストールを行いましょう。
通常 ksocket の設定ファイルには Kompira cloudのスペースURLを指定するのですが、 ksbridgeを使用する場合、スペースURLは前述のとおり ksbridge 側に設定することになります。
ksocket の設定ファイルには、代わりに ksbridge に対して接続する情報を設定します。

ksocket の設定ファイルである、ksocket.toml を以下のように編集してください。

[connect]
host = "127.0.0.1"   
port = 8080             # ksbridge の bindポートに変更する
protocol = "ws"         # "wss" から "ws" に変更する。設定行が存在しない場合は追加する
token = "FrKc+82kZGG9sdRS5AXnemPN8u6sDdY3PXxbqdB4"    # Kompira cloud上で発行したksocketトークンを設定する

(以下省略)

ksocket の起動

ksocket.toml の設定を反映するために、 ksocket サービスの再起動を行います。

$ systemctl restart ksocket

再起動をすると、ksocketは設定に従って自分の8080ポートにアクセスをしにいきます。 正常に接続ができた場合、ksbridgeでは以下のような表示となります。

$ ./ksbridge -bind 127.0.0.1:8080 -host yourspace.cloud.kompira.jp -proxy http://username:password@your.proxyserver.co.jp:3128
********************************************************************************
ksbridge - Tiny websocket connection bridge server

  listen: ws://127.0.0.1:8080/api/ksocket/connect
  server: wss://yourspace.cloud.kompira.jp/api/ksocket/connect
  proxy:  http://username:password@your.proxyserver.co.jp:3128

********************************************************************************
INFO[0011] connecting to client...
INFO[0011] client has connected
INFO[0011] connecting to server...
INFO[0011] server has connected

また、Kompira cloud にアクセスし「設定 > ksocket」を表示してください。 ステータスが「接続済み」となっていれば ksocket は正常に Kompira cloud に接続できています。

f:id:sugimotofp:20200114151054p:plain

これで ksbridge を介した ksocket と Kompira cloudの接続は完了です。



トラブルシューティング

ksbridge に何も出力されない

ksocketの設定を行い再起動を行っても ksbridge にログが表示されない場合、ksocketがksbridgeに接続しにいけていない可能性があります。
このような場合は、 ksocket のログファイル (デフォルトであれば /opt/fixpoint/ksocket/var/log/ksocket/ksocket.log ) を確認してみましょう。

2018-12-12T19:40:13+0900  DEBUG  ksocket.channel.session:_connector:241  Resumer is waiting disconnection...
2018-12-12T19:40:13+0900  DEBUG  ksocket.channel.session:_connector:243  Disconnected from the peer. Resume connection...
2018-12-12T19:40:13+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:40:13+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [Errno 111] Connect call failed ('127.0.0.1', 8080). Wait 0 sec... [1/120]
2018-12-12T19:40:13+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:40:13+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [Errno 111] Connect call failed ('127.0.0.1', 8080). Wait 0 sec... [2/120]
2018-12-12T19:40:13+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:40:13+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [Errno 111] Connect call failed ('127.0.0.1', 8080). Wait 0 sec... [3/120]

例えば上記のようなログがksocket.logに出力され続けている場合、ksbridge に接続できていない状態です。ksocket.toml での設定を再度確認してみてください。

また、別のパターンとして以下のようなログが出力される場合があります。

2018-12-12T19:45:54+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:45:54+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:833). Wait 0 sec... [1/120]
2018-12-12T19:45:54+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:45:55+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:833). Wait 0 sec... [2/120]
2018-12-12T19:45:55+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...
2018-12-12T19:45:55+0900  WARNING  ksocket.channel.session:_resume:225  Failed to start/resume session: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:833). Wait 0 sec... [3/120]
2018-12-12T19:45:55+0900  DEBUG  ksocket.channel.session:_resume:213  Connecting to the peer. Wait 60.000000 seconds...

このときは、ksocket.toml に protocol: ws という接続方式を変更する設定が正しく読み込まれていません。上述の「ksocketの設定」の項を確認し、protocol行の設定を行いましょう。

「failed to connect server」と表示される

ksbridgeのログで、 failed to connect server と表示される場合、ksocketとksbridgeは疎通できていますが、ksbridgeとプロキシサーバ間の通信が確立できていない場合が考えられます。

$ ./ksbridge -bind 127.0.0.1:8080 -host yourspace.cloud.kompira.jp -proxy http://username:password@no.proxyserver.co.jp:3128
********************************************************************************
ksbridge - Tiny websocket connection bridge server

  listen: ws://127.0.0.1:8080/api/ksocket/connect
  server: wss://yourspace.cloud.kompira.jp/api/ksocket/connect
  proxy:  http://username:password@no.proxyserver.co.jp:3128

********************************************************************************
INFO[0012] connecting to client...
INFO[0012] client has connected
INFO[0012] connecting to server...
ERRO[0012] failed to connect server                      err="dial tcp: lookup no.proxyserver.co.jp on 10.10.10.0:53: no such host" uri="{wss   yourspace.cloud.kompira.jp /api/ksocket/connect  false  }"
INFO[0069] connecting to client...
INFO[0069] client has connected
INFO[0069] connecting to server...
ERRO[0069] failed to connect server                      err="dial tcp: lookup no.proxyserver.co.jp on 10.10.10.0:53: no such host" uri="{wss   yourspace.cloud.kompira.jp /api/ksocket/connect  false  }"

このような場合は、ksbridgeの実行時に指定しているプロキシサーバのサーバ名、アカウント、パスワードが正しいかどうかを確認してください。

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

ノードに文章を記録できる機能を追加しました

Kompira cloudについて、以下の内容を含むアップデートを行いました。

ノードに対して自由に文章を記録できる機能を追加しました

Kompira cloudで構成情報を取得すると、機器・OSごとに「ノード」という名前でデータが登録されます。 今回のアップデートにより、このノードごとに自由に文章を記録できるようになりました。

f:id:kompiracloud:20181130175103p:plain


「ノートの追加」をクリックすると、新しい文章を記録するための編集画面が表示されます。

f:id:kompiracloud:20181130175128p:plain


ノートはタイトルと本文に分かれており、本文は500文字まで記述することができます。

f:id:kompiracloud:20181130175138p:plain

ノードに紐づく担当者の連絡先や保守情報、その他にもちょっとしたメモ書きなど、管理に必要な情報を自由に記載しておくことができます。

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

Kompira cloudのノード一覧をCSV/Excelに出力するツールを作成しました

Kompira cloudに保存されたノードの一覧をCSV/Excelとして出力できるツールを作成しました。

github.com

ブラウザ上で表示されるノード一覧と同等の情報をCSVやExcelに出力することができます。
インストール、設定、実行方法については上記のリンク先のドキュメントを参照して下さい。

設定を行った後、以下のコマンドでCSV/Excelファイルを出力することができます。

# xlsx形式で出力
$ python kc_exporter.py --url https://demo.cloud.kompira.jp/apps/sonar/networks/5c4e20e5-b503-414d-b21c-789ce0b1a50c/managed-nodes --filename demo-test --format xlsx
# (demo-test.xlsxが生成される)

# csv形式で出力
$ python kc_exporter.py --url https://demo.cloud.kompira.jp/apps/sonar/networks/5c4e20e5-b503-414d-b21c-789ce0b1a50c/managed-nodes --filename demo-test --format csv
# (demo-test.csvが生成される)

ここで生成したExcelファイルをWindowsで開いてみます。

f:id:kompiracloud:20181204163921p:plain
demo-test.xlsx

このように、Kompira cloudのノード一覧をブラウザ上で表示したときと同等のデータを、CSV/Excel形式で得ることができます。

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

VimConf 2018 に参加しました

f:id:c255:20181129210326j:plain
Bram Moolenaar 氏の Key note 発表 @VimConf 2018

Kompira cloud 開発チーム築田です。

11月24日に開催された VimConf 2018 に参加してきました。

VimConfについて

VimConf は Vim というテキストエディタの国際カンファレンスです。 Vim をご存じない、または Vim を使っている方の中にも
『テキストエディターで国際カンファレンスって何を発表するの?』
と思う方もいらっしゃるかもしれません。 カンファレンスでどんなことが話されるのか、簡単ではありますがご紹介します。

Vim はテキストエディタとしてはカスタマイズ性が非常に高く スクリプトを用いた機能拡張が行えることもあり、 人それぞれ かなり使い方に差があるテキストエディタです。 そこで、そのカスタマイズの知見を共有したり、知らなかった使い方を共有するなどの発表が行われています。

今回はなんと開発者である Bram Moolenaar 氏が登壇し、 30年以上の歴史があるエディタの成り立ちや今後の展望などの発表もありました。

実際に発表されたスライド等は下記オフィシャルブログに公開されていますので、 興味がある方はぜひ見てみることをおすすめします。

vimconf.wordpress.com

fixpoint との関わり

fixpoint は

  • VimConf シルバースポンサー
  • @aomoriringo が VimConf スタッフ
  • †Dark Vimmer† な @lambdalisue が去年に引き続き VimConf 登壇
  • 社内の 50% が Vim user

と非常に Vim 愛が強い会社です。

Kompira cloud 開発チームでは技術者を募集しており、 現在 会社説明焼肉会 の募集をしていますので、 Vim が好きだ!! という方もそうでない方も 焼肉が食べたい方も 応募をお待ちしてます。

fixpoint会社説明会 (という名目の焼肉おごり会) 応募フォーム

カンファレンス感想等

VimConf には今回初参加だったので、例年との差はわかりませんが、 今年は Bram Moolenaar 氏が来ていたためか、 Vim の本体に関する発表が少し多かったように思いました。 それ以外にもプラグイン開発者、Vim の使用者まで幅広く様々な発表がありました。 全ては書ききれませんが、印象に残った発表をピックアップします。

Keynote - What is the next feature? - @mattn

@mattn 氏の発表では日本における Vim 開発者のコミュニティーとしての vim-jp の話や、その活動が発表されました。 特に日本では、最近も歴史あるエディタの中では Vim の人気が高いように感じていました。 自分はずっとこれが不思議だったのですが、 今回のカンファレンスを通して vim-jp をはじめとする質の良いコミュニティが サポートを行ってきたからここまで広まったのかと納得しました。 実際 Vim に搭載されている日本語ヘルプは質の高いもので非常に読みやすく、 そのような配慮の積み重ねが現在の Vim 人気を支えているのだと思いました。

Keynote - Vim: From hjkl To a platform for plugins - Bram Moolenaar

Bram Moolenaar 氏の発表では Vim のこれまでの歩みとこれからの方向性が話されました。 発表のタイトル "From hjkl To a platform for plugins" からもわかるようにプラグインフレンドリーな方向への拡張を示唆する内容でした。 以前から Vim はテキストエディタであるから、エディタの範疇を超える機能追加はあまり積極的に行われないという話を聞いていたので、 この発表は正直意外に感じましたし、プラグインによる機能拡張の幅が広がることに期待感が高まりました。

Migrating plugins to standard features - @daisuzu

大量のプラグインで捌いていた操作を標準に倒していくという趣旨の発表でした。 私はもうかれこれ 10 年以上 Vim を使い続けています *1 が、最近まではあまりプラグインなども使っていませんでした。 そのこともあり Vim 本体に搭載されている機能でなんとかすることが多く本体機能には比較的詳しいつもりでいたのですが、 それでもまだ知らない本体機能に関する発表もあり、 Vim の奥深さに関心するとともに、新たな活用方法を見つけられたことが収穫でした。 特に Vim には組み込みの補完機能が多数あるのですが、普段あまり使用していない補完機能の説明が非常に参考になりました。

Effective Modern Vim scripting - @lambdalisue

弊社 @lambdalisue の発表で、 Vim でプラグインを書き始めるに当たってのチュートリアルになっています。 私は最近 Vim を使うにあたって設定ファイルに少し長めのロジックを書くことも増えてきたので、 それらのプラグイン化をしたいと思っていました。 ところが Vim プラグインの書き方でまとまった資料があまり無く、またはあっても古い場合がありましたので、 この発表は個人的に非常にタイミングが良く参考になりました。 これからは Vim 設定に書いてあるものをプラグイン化して公開などもしていきたいと思いました。

最後に

今まで自分は Vim を使うだけで、コントリビュートはしてきませんでしたが、 Vim に非常に多くの方々が関わって良くしていっているということを肌で感じることができました。 今までは Vim プラグインを使うことはあっても作ろうとはあまり思っていなかったのですが、 この機会に何かしら自分でも作ってみたいと思えるようになりました。

発表も非常にわかりやすくモチベーションも上がり、本当に良いカンファレンスだったと思います。 VimConf を主催してくださったスタッフの方々、 また数々の良い発表をしていただいた発表者の方々ありがとうございました。

f:id:c255:20181129210702j:plain
アンケート 『Vim で何を書いていますか?』 (意外とHaskell書く人が少ない…)

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

*1:とは言っても Vim だけではなく、 Emacs を使ったり VS Code を使ったりもしました。

Windowsからのパッケージ情報取得機能を強化しました 他

Kompira cloudについて、以下の内容を含むアップデートを行いました。

Windowsからのパッケージ情報取得機能を強化しました

Windowsからのパッケージ取得機能では、これまでWindows Microsoft Installer(MSI)形式のインストーラでインストールされたアプリケーションが対象でした。 今回のアップデートにより、その他の形式でインストールされたパッケージも取得できるようになりました。

カーネル情報が取得できるようになりました

Linuxからの情報取得時、カーネル名、バージョン、リリースバージョンを取得できるようになりました。

  • Linuxでカーネル情報を取得した例
    「ノード詳細情報」より確認することができます。

f:id:kompiracloud:20181119114939p:plain

一覧表示のUIを刷新しました

ノード一覧、スナップショット一覧等、Kompira cloud上の各種一覧表示ページの見た目を刷新しました。
また、URLに選択したカラム、ソートキー、ページ行数等の情報を含められるようになりました。
これにより、自分が表示している一覧ページと同様のページを他の人に共有することができます。

その他の改善、修正

その他、いくつかの改善・修正を行いました。

  • スキャンが異常終了したとき、スナップショットサマリにエラーメッセージを表示するようにしました。
  • ノードの「パッケージ一覧」「WindowsUpdate一覧」が更新される際、変化しないものが削除されてしまう問題を修正しました。
  • スキャンを行う際、「実行する」を選択した時の挙動が「デフォルト値を更新して実行する」と同じになっていた問題を修正しました。
  • ノード一覧、スナップショット一覧において取得できていない値が undefined と表示されることがある問題を修正しました。

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

ローカルネットワークスキャンの実行例

(文言を新UIのものに変更しました。2020/1/14)

ローカルネットワークスキャンの仕組み では、ksocketがどのようにしてネットワーク内の機器を探すのかを解説しています。 本記事では、あるネットワーク環境を例として、ksocketをインストールして実行するとどのようにスキャン処理が行われるのか、ステップごとに詳しく追ってみましょう。

例とするネットワーク環境

今回は、以下のような社内ネットワークが存在すると仮定します。

f:id:kompiracloud:20181203163517p:plain

  • /24 のセグメントが4つ存在する
  • ルータ R1 はSNMP応答が有効な設定になっている
  • ルータ R2 はSNMP応答が無効な設定になっている
  • 192.168.1.0/24 セグメント内のPC (192.168.1.10)にksocketをインストール

この状態でksocketでスキャンを実行すると、どのような結果となるかを見ていきましょう。
スキャンにはいくつかのオプションを指定することができるのですが、ここではどのオプションも指定せず、デフォルト設定で動作させるものと仮定します。

スキャンの実行

スキャン候補IPアドレスの取得

まず初めに、ksocketは以下からIPアドレスの取得を試みます。

  • ksocket動作マシンのデフォルトゲートウェイ
  • ksocket動作マシンのARPキャッシュ

「ksocket動作マシンのデフォルトゲートウェイ」は、今回のネットワーク例の場合 192.168.1.1 です。
「ksocket動作マシンのARPキャッシュ」は、ksocket動作マシンや 192.168.1.0/24 セグメントのネットワーク設定によってどの程度の情報が取得できるかが変わります。場合によっては、 192.168.1.0/24 以下に存在するすべてのマシンIPを取得できるでしょう。

この時点で、ksocketは以下の緑色で示した範囲のIPアドレスを取得していることになります。

f:id:kompiracloud:20181203163533p:plain

新規IPアドレスの検索

ksocketは、前ステップで見つかったIPアドレスの中から、さらに別のIPアドレスを探します。 各IPアドレスより、SSH/WinRM/SNMP を用いて、以下の情報取得を行います。

  • ARP キャッシュテーブル
  • NextHop
  • 機器に割り当てられたIPアドレス一覧

今回のネットワーク例の場合、ルータR1 のSNMP応答が有効な設定になっているので、ここからARPキャッシュテーブルとNextHopが取得できます。
ARPキャッシュテーブルからは 192.168.2.0/24192.168.3.0/24 の中のIPアドレスリストが、NextHopからは 192.168.0.1 が取得できるでしょう。
機器に割り当てられたIPアドレス一覧は、今回の例だと 192.168.0.2, 192.168.2.1, 192.168.3.1 が取得できます。

これにより、図の左側の範囲のIPアドレスを見つけることができました。

f:id:kompiracloud:20181203163548p:plain

新規IPアドレスの検索 (その2)

ksocketは、前項の「新規IPアドレスの検索」処理を、新しいIPアドレスが見つけられなくなるまで繰り返し行います。 つまり、前項で新しく見つかった各IPアドレスより、SSH/WinRM/SNMPを用いて、再度以下の情報取得を行います。

  • ARP キャッシュテーブル
  • NextHop
  • 機器に割り当てられたIPアドレス一覧

しかし、今回のネットワーク例の場合、ルータ R2 のSNMP応答は無効となっています。 もし有効であれば ARPキャッシュテーブルから 10.10.0.0/24 のIPアドレスが取得できるのですが、無効の場合はここで探索は終了することになります。
このようにして見つかった各IPに対して、ksocketは本当にIPアドレスが存在するかどうかを確認し、SSH/WinRM/SNMPでアクセスできる場合は構成情報を取得します。


明示的な探索範囲の追加

上述の、どのオプションも指定しない場合でのスキャンでは、 10.10.0.0/24 までは見つけ出すことができませんでした。
これをスキャンできるようにするためには、「スキャン起点アドレス」 というスキャンオプションを使用します。
スキャン起点アドレス に設定されたIPアドレスは、「スキャン候補IPアドレスの取得」ステップで発見されたIPアドレスと同じように扱われ、結果としてスキャンされる対象となります。
今回のネットワーク例の場合、スキャン起点アドレス = 10.10.0.0/24 と入力することで、以下の赤色で示した部分が探索対象に追加されます。

f:id:kompiracloud:20181203163607p:plain

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら

Windows 用 Docker image を macOS で動かす

f:id:lambdalisue:20181029145429g:plain

どうも有末です。 「仕事で使ってない技術でもいいからブログ書いてくれると嬉しい」と言われ、嬉しさのあまり涙で画面が曇ったので、情報を探すのに苦労した Windows 用 Docker image を macOS で走らせる方法に関して書きます。

僕は弊社プログラマの中で最も多くの Vim プラグインを開発1しています(たぶん)。 基本的にプラグインを開発する際は対象の OS を絞らないように作っているのですが、どうしても普段利用していない Windows や Linux では環境依存のバグが発生することが有ります。 そのため TravisCI (Linux/macOS) や AppVeyor (Windows) を用いて他の OS でも CI テストを回すようにしているのですが、テストが落ちたときに原因特定するのはとても面倒です。

このような場合、テスト環境を Docker にて準備するとローカルでも同じ環境でテストが出来るため色々と捗るのですが Windows 用 Docker image は Windows container でしか動作しません(当たり前ですが)。 ただ、今回みたいなケースはサクッとテスト用に走らせたいだけなので Virtual Box とか駆使したら何とかならないかな?と色々探したところ StefanScherer/windows-docker-machine というお手軽なシステムを見つけたのでご紹介します。 ちなみにパフォーマンスとかライセンスとか諸々あるので運用利用する場合は素直に Windows ホストでやったほうが無難です。

やりたいこと

macOS のターミナルから Windows container を要求する Docker image (例: microsoft/dotnet-samples:dotnetapp-nanoserver)を可能な限りサクッと動かす。

ちなみに Docker for Mac の状態では上記 Docker image の実行は image operating system "windows" cannot be used on this platform. とか言われて動きません。

$ docker run --rm microsoft/dotnet-samples:dotnetapp-nanoserver
Unable to find image 'microsoft/dotnet-samples:dotnetapp-nanoserver' locally
dotnetapp-nanoserver: Pulling from microsoft/dotnet-samples
bce2fbc256ea: Pulling fs layer
b0b5e40cb939: Pulling fs layer
347417e0cada: Pulling fs layer
1e5ea1830940: Pulling fs layer
081f63111c09: Pulling fs layer
94504ab92c8e: Pulling fs layer
4b830cd70a22: Pulling fs layer
c09304867c0b: Pulling fs layer
04d6c936784e: Pulling fs layer
5897a999aef6: Pulling fs layer
b33a195869b0: Pulling fs layer
081f63111c09: Waiting
94504ab92c8e: Waiting
4b830cd70a22: Waiting
04d6c936784e: Waiting
b33a195869b0: Waiting
5897a999aef6: Waiting
1e5ea1830940: Waiting
c09304867c0b: Waiting
docker: image operating system "windows" cannot be used on this platform.
See 'docker run --help'.

依存アプリのインストール

Vagrant および Virtual Box を利用するので Homebrew Cask を利用してインストールしておく。

$ brew cask install vagrant virtualbox

Docker machine の構築

Docker がインストールされた Windows Server 2016 をベースに Windows container を動かすための Docker machine を構築します。 作業内容としては StefanScherer/windows-docker-machine をクローンしてきて vagrant up 2016-box 2 するだけです。 なお、初回構築時はダウンロード等で結構時間がかかります。

$ git clone https://github.com/StefanScherer/windows-docker-machine
$ cd windows-docker-machine
$ vagrant up 2016-box  # 初回は珈琲飲むくらいの時間はかかる

Docker machine の確認

上記で構築が完了すると以下のように docker-machine ls2016-box が出てきます。

$ docker-machine ls
NAME       ACTIVE   DRIVER    STATE     URL                        SWARM   DOCKER          ERRORS
2016-box   -        generic   Running   tcp://192.168.99.90:2376           v18.03.1-ee-3   

このように Windows container を動かすための環境が Docker machine 化したので、以下のように簡単に利用できます。

$ eval $(docker-machine env 2016-box)

なお、上記コマンド実行後に docker version を見ると ServerOS/Archwindows/amd64 になっています。

$ docker version
Client:
 Version:           18.06.1-ce
 API version:       1.37 (downgraded from 1.38)
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:21:31 2018
 OS/Arch:           darwin/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.03.1-ee-3
  API version:      1.37 (minimum version 1.15)
  Go version:       go1.10.2
  Git commit:       b9a5c95
  Built:            Thu Aug 30 18:56:49 2018
  OS/Arch:          windows/amd64
  Experimental:     false

動かしてみる

この状態であれば Windows container が必要な microsoft/dotnet-samples:dotnetapp-nanoserver がちゃんと動作して、よくわからないキャラクターっぽいものが表示されます。

$ docker run --rm microsoft/dotnet-samples:dotnetapp-nanoserver

        Dotnet-bot: Welcome to using .NET Core!
    __________________
                      \
                       \
                          ....
                          ....'
                           ....
                        ..........
                    .............'..'..
                 ................'..'.....
               .......'..........'..'..'....
              ........'..........'..'..'.....
             .'....'..'..........'..'.......'.
             .'..................'...   ......
             .  ......'.........         .....
             .                           ......
            ..    .            ..        ......
           ....       .                 .......
           ......  .......          ............
            ................  ......................
            ........................'................
           ......................'..'......    .......
        .........................'..'.....       .......
     ........    ..'.............'..'....      ..........
   ..'..'...      ...............'.......      ..........
  ...'......     ...... ..........  ......         .......
 ...........   .......              ........        ......
.......        '...'.'.              '.'.'.'         ....
.......       .....'..               ..'.....
   ..       ..........               ..'........
          ............               ..............
         .............               '..............
        ...........'..              .'.'............
       ...............              .'.'.............
      .............'..               ..'..'...........
      ...............                 .'..............
       .........                        ..............
        .....


**Environment**
Platform: .NET Core 2.0
OS: Microsoft Windows 10.0.14393 

なお Docker machine なので docker-machine env --unset を eval すれば戻ります。

$ eval $(docker-machine env --unset)

$ docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:21:31 2018
 OS/Arch:           darwin/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:29:02 2018
  OS/Arch:          linux/amd64
  Experimental:     true

おわりに

macOS からサクッと Windows container を動かすことが出来るようになったため Dockerfile 書くための試行錯誤とかも比較的楽にできるようになりました。 ここまで出来てひとまず満足してしまったので、まだ CI に活かすとかは出来てませんが…… とりあえず、Docker 便利。

Kompira cloud 製品紹介ページはこちら
Kompira cloud 資料ダウンロードはこちら


  1. 残念ながら弊社の仕事として Vim プラグインを開発しているわけではありません。あくまでも趣味です。

  2. 簡略化のために 2016-box を指定していますが、通常は README の通り StefanScherer/packer-windows を使って自前構築する方が良いと思います(びっくりするくらい時間かかりますが)。