ケ・セラ・セラ

備忘録とか思いつくまま

WSL2 と Docker (compose)ーその2

混乱その2、ネットワークについて。

WindowsホストからWSL2へのNW接続にはホストでport forwardが必要?

という疑問。

手元でdocker-composeで立ち上げている、Docker Desktop for Windows based on WSL2でのJenkins/Rocket.chat/wiki.jsをバックエンドに持つnginx、特にホストでport fowardしなくてもWindowsホスト名のURLでアクセスできている(Windows Defender Firewallでinboudは開けている)のです。

 

まずは仕組みの情報収集から。

一昨年(2019年)の8、9月頃、Windows 10 Build 18945リリースの記事でホストWindowsからlocalhostでWSL2にNWアクセスできる改良が盛り込まれたという記事がメディアから多数リリースされてました。

WSL2化に伴い、”本物”のLinux KernelをLWUVM(軽量ユーティリティ)で動作させて「WSL 2 と WSL 1 の比較 | Microsoft Docs」の機能比較でWSL1の「」を「」に改良したわけですが、これによってWSL2側のTCP/IPスタックも本物化されネットワークセグメントがHyer-Vの仮想ネットワークスイッチを使って分離されたことに起因するものとなっています。

確かに我が家も記事通りになっています。

f:id:kittantan:20210111150555p:plain
f:id:kittantan:20210111152328p:plain

Docker composeでnginx(port:8443)を含むサーバーを立ち上げた状態で、Windowsホストでポートの状態をnetstatで見ると以下のような感じです。わかりやすくする為、関係のない情報は削除しています。

f:id:kittantan:20210111183346p:plain

対象プログラムがまちまち([com.docker.backend.exe]/[svchost.exe]/[wslhost.exe)なのが謎ですが、0.0.0.0:8443(IPv4)/[::]:8443/[::1]:8443(IPv6)でlocalhostをListenしているのが、恐らく記事にあるlocalhostで接続できる様になった部分。

すべてがwslhost.exeだと記事の内容と整合してスッキリするのですが、記事はあくまでWSL2に関するものですので、Docker Desktop for Windowsサービスを停止した状態で確認してみるのがいいかもしれません。

Docker コンテナとHost間の通信に関しては、Windows環境ですと”host.docker.internal”が関わっていそうです。

”host.docker.internal”はWindows/Macのみ(Linuxにはない、というか必要性がそもそもない?)にある、コンテナからホストに接続する為のスペシャDNS名(出所:Docker公式ドキュメント)。

コンテナ起動してChromeでアクセスした状態netstatすると以下のような感じになりました(同じく間引いています)。

f:id:kittantan:20210111205028p:plain

6つのポートを使っている理由はわからないのですが、”host.docker.internal”の仕組みを使ってHOST-コンテナ間通信を実現してくれている様です。

 

冒頭の疑問の自己結論。

  • HOST→WSL2間のlocalhoost接続とは全く別の仕組み。
  • Docker Desktop for Windowsを使っていれば、Dockerfile(docker-compose.yml)での定義に沿って適切にDokcerがHOST-コンテナ双方向の通信をセットアップしてくれる。

Ubuntu on WSL2にDebianパッケージでDocker導入するパターンを「WSL2 と Docker (compose)ーその1 - ケ・セラ・セラ」で言及しましたけど、同じ機構は機能しないでしょうし、WSL2によるHOSTとのネットワーク分離と相まって、HOSTのサーバー名で外部からコンテナにアクセスするには、こちらの場合、手動でport fowardが必要そうですね。

※現環境を壊して試すインセンティブが今はないので未検証です。

やはり、Winな環境での通常運用では、素直にWin向けを使うのがベターというありきたりな顛末となりました。

 

最後に利用しているDocker Desktop for Windows環境情報を。

f:id:kittantan:20210111221537p:plain

 

WSL2 と Docker (compose)ーその1

WSL2でWindowsでも真っ当なLinux環境が使える!という情報に期待して色々触り始めて時間が経った事で、分かってきたり更に悩みが深くなったりしたことを書いてみます。

仮想マシン上を含むピュアLinuxな環境だと発生しない悩み事が殆どです。

今回は、

Docker (compse)は、「Docke Desktop for Windows based on WSL2」にすべき?WSL2上のUbuntuUbuntuパッケージで導入すべき?

です。

ネット上の情報、特に個人の記事を見ていると、この2つを比較した上でどちらを使っているっという内容のものは殆ど無く混在しているので、検索結果を通しで見ているとちょっと混乱してしまいます。導入するだけであればどちらも可能。こういう時はまず公式。

docs.docker.com

WindowsであればやはりDocker Desktop for Windows。選択肢としてもUbuntu on WLS2へのパッケージ導入の言及はないですね。

以下のページ、比較ではなく筆者の方ご自身がやりたいことを時系列に実施されている中で両方のパターンを言及されていて分かりやすかったです。

hnakamur.github.io

WSL2で動くUbuntu(MS的にはアプリ)は公式のDesktop版でもServer版でもなく、WSL用ディストリビューションで、initプロセスはデーモン起動する仕組みの部分、今時ですとsystetmdが置き換え(先祖返り?)られていている様です。

故に、任意のサービス系パッケージはインストールはできれども、プート時にサービス起動できない。

なので、Ubuntu on WSL2にDebianパッケージでdocker (compose)を導入すると、Docker Daemonの手動起動が毎回必要になるという不便があるというのが現状の様。

systemdを動かすのも実験的に好奇心を満たす意味では面白そうですが、安定運用観点だとアップデートにも影響がありそうで難あり。

Ubuntu on WLS2にdockerをパッケージインストールすると「動かなかった」で終わっているドキュメントがネット上に多数あったのですが恐らくEngine自体の起動ができていなかったんだろうと推察されます。

Windows 10でDocker (compose)をハック的ではなく、通常運用で使うなら「Docker Desktop for Windows」が良さそうですね。

 

Wiki.jsなGraphQLでユーザー作成試行中の続き(タイムゾーン)

Wiki.jsなGraphqlでユーザー作成試行中 その2 - ケ・セラ・セラでやりきった感出してましたGrarphQLでのユーザー作成、出来はしたのですけど、途中いくつか想定外のことがおこったのでその内容を。

  • Wikiの記事を作成すると時間が過去になる
    システム時刻のlocaltimeだろうと踏んで、「Alpine Linux でタイムゾーンを変更する - Qiita」あたりを参考にWiki.js DockerコンテナのAlpine LinuxタイムゾーンをAsia/Tokyoにするも記事作成時刻は変わらず。

    Release Notes | Wiki.jsのtimezoneに関する対応内容をみるとどうも「User Profile」に設定がある(ユーザー毎?)様で、デフォルトはNewYork。(通りでGMTとの時差でもなかったわけです)

    f:id:kittantan:20201226010621p:plain

    UserMutationsスキーマを調べると”update”なるものがあって、ユーザー毎のtimezone要素があり、そこにタイムゾーン文字列(”Asia/Tokyo”)を指定してリクエストすれば変更できそうなことがわかる。

    f:id:kittantan:20201226011500p:plain

f:id:kittantan:20201226011634p:plain

これで無事に編集時間がJSTになるようにJenkinsジョブからユーザー作成できるようになりました。

でも、なぜcreateのパラメータには無いんだろう?

  • createのレスポンス”uses”が作成成功してもnull
    createでtimezone属性設定できないのでupdateを改めて呼ぶわけですが、ユーザー特定のためwiki.jsシステムが割り振るユーザーidをパラメータに指定して呼び出す必要があります。
    createのレスポンスにあるから余裕と思っていたのですがどうしてもnullしか返却されない(Wiki.js Ver.2.5.170)。
    仕方ないのでcreate後にusers: UserQueryのserchでユーザーIDを取得してupdateのパラメータにしています。
    私の使い方の問題なのかシステムのもんだいなのか、いやはや。

JenkinsからWebsocket通知でWebページをリアルタイム更新する

ユースケースMTGの出席簿webページ

  1. rocketchatで出欠をbotに返信。受付JOBをbot scriptからのHTTP Requestでパラメータ付き起動。
  2. 受付JOBでは、メンバーの出欠一覧データを更新しつつ、HTML Publisherで出欠一覧webページのデータをデプロイ。
  3. 主催者・参加者は2.のwebページで出欠状況を確認。

複数のユーザーから非同期に出欠通知がくるので、出欠データ更新のタイミングで一覧webページをリアルタイム更新したい。

 

一覧更新JOBのビルド完了をトリガにwebsocketで更新通知するのは以下のPluginで実現。

インストールする時ののプラグイン管理画面でwebsocket検索すると、最近も更新されている類似のプラグインもある。

inなしの方は7年前くらいから更新されていないみたいなんだけど、作者のページ(↓)もあって参考情報が多いので一旦inなしでwebページ(JS)側も対応して出来栄え確認しようと思う。

mzp.hatenadiary.org

 

システム構成上ブラウザからはリバースproxyのnginx経由になるので、nginxのwebsocketの有効化?も必要かな?(↓参考)

uorat.hatenablog.com

 

まだまだ試したいことが尽きない。そして試すと次々試したくなってきりがない。

Wiki.jsなGraphqlでユーザー作成試行中 その2

昨日の続き。

顛末はgraphqlの使い方ではなくて、wiki.jsのユーザー作成SCHIMAの要素、provierKeyの意味がわからず適当に設定してたことが原因。

Responseのmessage要素を表示で判明。

providerKeyとは認証プロバイダの識別子の様で、LocalDBの場合は”local”を指定するのが正解っぽいです。

f:id:kittantan:20201224000846p:plain

wiki.jsのAdministratorユーザー画面

プロバイダ欄の()の中がKeyの様子。

慣れてくると使い勝手が良くて、ユーザー削除(ユーザーid検索)、グループ作成などなども一気に成功!

Play-groundで成功した結果をCURL COPYしてJenkinsジョブのシェル実行からも難なく成功!

Wiki.js、Jenkinsはdocker-composeのコンテナで立ち上げているので、Docker内NWのホスト名(コンテナ名)に書き換える程度でほぼコピペで行ける!!

これで、手作業ユーザー登録完全排除できます。

Wiki.jsなGraphqlでユーザー作成試行中

Rocket Chat + Wiki.js+JenkinsなChatOptシステムもどきを作成しているわけです。

Jenkins Jobで「ユーザー登録」する仕組みにしていて、ユーザーごとのJOB作成などなどの初期化を行っており、その中でフロントアプリのユーザー作成や設定なんかも行ってるのです。

Rocket Chat は未だ多少嗜みのあるRESTfulなので案外あっさりとできたのですけども、こちらは新しすぎなのもあってズバリな情報も少ないので、地道にGraphqlの仕組みや開発手法を調べつつここまで来ました。

f:id:kittantan:20201222030059p:plain

認証は通ってますけど失敗ですね。レスポンス詳細化して原因究明。

初GraphqlでとりあえずPlay-groundにたどり着いて、ググりながら触りながらmutationの扱いとAuthoniation Headerの設定は何とか使える様に。

うまく行けばcURLコピーができたりもするのでJenkinsジョブからWiki.jsのユーザー作成もできそう。

Webエンジニアじゃない素人丸出しっすね(;^ω^)

参考ページ

qiita.com

qiita.com

qiita.com

最初に追加しておくplugin (update2020/12/29)

最初に追加しておくplugin(棚卸し) - ケ・セラ・セラの続き。

Viewのカスタマイズ関連

集計Webページのリアルタイム更新

処理高速化(ツールのcloneをJOBで共通利用)

WebSocket通知JOBの呼び分け(2002/12/29追加)