WSL

WSL(Windows Subsystem for Linux)の中身をちょっと詳しくみてみる

人物紹介

  • デジ子 
    ロボットだけど、進化し過ぎてデジタル全般苦手。

  • せんぱい
    IT全般とくい。人が少ないIT部署になぜITが分からないデジ子が派遣されたのか解せない。

せんぱい「では、今日はWindows Subsystem for Linux、通称WSLの特徴について見ていくよ」

参考記事

この記事を読んでヤバイ。。。と思ってコンテナについての知識もおさえたいなーと思っていたら
ちょうど、ウェブDBプレス.vol117 にてこれらを活用した開発環境を整える特集が掲載されていました。

また、上記記事を書かれた方が、実際にWEBでもこちらを書かれてました!
本記事は、自分が理解するように上記をちょっと噛み砕いたものになります。
詳細は上記記事を確認いただくとよいと思います!

WSLのメリット

Windows⇔Linux間のでのやりとりがスムーズ!

せんぱい「WSLの場合はとても簡単。WindowsからLinux上にあるファイルにアクセスするには、」

\wsl$[ディストリビューションの名前]

せんぱい「のみたいなパスにアクセスすればOKなんだ!
この機能を使用すると、WSL上で動作させているPHPスクリプトを、Windows上のエディタからダイレクトに編集することが可能になるよ」

デジ子「ダイレクトに!」

せんぱい「LinuxからWindowsにアクセスする場合は/mnt/[ドライブ名]といったパスで、Windowsの指定したドライブ直下にアクセスすることができるよ。
例えば、Cドライブにアクセスする場合は /mnt/c のようになるね」

WSLのアーキテクチャ(構造)を見てみるよ

WSL1とWSL2の違い

WSL1

WSL1はLinuxカーネルのファンクションコールがLXCoreというシステムにより、Windowsへのファンクションコールに変換されている。
つまり、WSL1にはLinuxカーネルは存在していない。
多数のファンクションコールを、LXCoreでは変換しきれない。
よって、Linuxの動作を忠実に再現することはできない。
その為、Linuxのファンクションコールに強く依存するDockerなどは動作しない。

せんぱいメモ!

ファンクションコールの役割は、大きく分けると2つがある。

  • 基本的な機能をあらかじめ用意することによってプログラムの負担を少なくすること。
  • すべてのプログラムが共通の手順を使用することによって、移植性や汎用性を高めること。

WSL2

Hyper-Vベースの仮想マシンサービス上にLinuxカーネルを搭載したOSが動作する。
これにより、Windows上で、フル互換のLinuxを動作させることができる。
更に、このHyper-VはWSL2専用にカスタマイズされた軽量なもの。
そして、LinuxカーネルもMicrosoft独自パッチを当てることで軽量化を実現させている。
結果、約2秒の高速起動を実現。

WSL2がオススメの理由は、「Docker」が動作すること。
WSL2はフル互換のLinuxだから強くカーネルに依存するソフトウェアのDockerも動作する!

Hyper-V(ハイパーブイ)は、マイクロソフトが提供するハイパーバイザベースのx64向け仮想化システム。
1台のコンピュータ(サーバ)で複数の仮想機械を実現する。

デジ子「せんぱい。。。ちょっと落ち着いてください

せんぱい「落ち着いているよ!」

デジ子「ハイパーバイザーって。。。なんすか!?

せんぱい「ハイパーバイザーは、コンピュータを仮想化するためのソフトウェアのことだよ。
物理的なマシンの中に、仮想的なコンピュータを作り出し、実行する際に使用するんだ」

デジ子「バド・ワイザーのような感じということですね?

せんぱい「それどんな感じになるの!?
ハイパーバイザーは、hypervisor。
ハイパーバイザーはそのまま直訳すると、ハイパーな管理者、という意味。
OSのことをスーパーバイザとも言ったりするんだけど、ハイパーは更にその上のことを指すからハイパーとつくんだよね。
ハイパーバイザーという言葉は、上位層からプログラムを管理するという意味から生まれてるんだ」

デジ子「まあ、とにかく、強いやつなんですね

せんぱい「すごいざっくりした理解!
ハイパーバイザは大きく分けると、2種類があって、作成した仮想機械(バーチャルマシン)でそれぞれのOS(ゲストOS)を動かすことができるんだ。」

  • ハードウェアの上で直接稼働するタイプ
  • 他のOSの上で稼働するタイプ

せんぱい「まぁ、ハイパーバイザーについてはこのあたりにしておこうか」

デジ子「・・・ぐー」

せんぱい「寝てる!」

WSL1とWSL2のパフォーマンスの違い

  • それぞれのファイルシステム
    WSL 1→NTFS
    WSL 2→EXTA4でフォーマットされたVHD(Vittual Hard Disk)

せんぱい「EXTA4はLinuxカーネル標準のファイルシステム。
これにより、ディスクパフォーマンスが大幅に改善したんだ」

デジ子「それぞれのシステムの保存形式もどんなものか気になりますね」

せんぱいワンポイントメモ!!

NT File System【NTFS】
NT File System【NTFS】とは、Windows NT系の標準ファイルシステムで、現在主流のファイルシステムです。
Windows NT系(ウィンドウズ エヌティけい)はマイクロソフトが開発したWindows NTのアーキテクチャに基づいて製作されたオペレーティングシステム (OS) の総称。
遅くとも Windows 98/98SE/me のサポートが終了した2006年以降から2020年現在に至る Windows の主流系統となっている。

せんぱい「でも、WSL1の方が得意な処理もある。
それはWSL上のLinuxからWindowsのファイルにアクセスする場合なんだ。
それぞれ、アクセスする際に使用するプロトコルが違っている。」

  • WSL1 DrvFsプロトコル
  • WSL2 Plan 9 FileSystem Protocol(9P)

せんぱい「この性能の差は、上記プロトコルの違いによるものじゃないかと思ってる。
WSL 2の方が、機能面ではメリットが多いので」

WSL 2 はWSL 1をインストールし、Microsoft StoreからUbuntsなどのディストリビューションをインストール
その後、そのディストリビューションをコマンドでWSL 2に変換することで使えるようになる
その変換に10分ほどかかるので、ちょっとだけ手間がかかる。

WSL 2はHyper-Vのサブセット機能を利用する為、その実行には仮想マシン支援機能が必要になる。
これは、PCで仮想化機能を使用する際に仮想化ソフトウェアが処理する時間をCPUで分担し処理してくれるものになる

また、さっきも触れたようにWindows側へのアクセスが多い場合はWSL 1の方がよいと言える。

WindowsとLinuxのGUIアプリケーションが同じデスクトップで簡単に操作できるようになるのもそう遠くないかも!

WSLを使用したWindowsとLinuxのシームレスな開発を目指すよ!

Linux基盤で実行するアプリケーション開発

要件例その1

  • 開発言語 PHP
  • Webサーバー Apache HTTP Server
  • アプリケーション実行基盤 Linux

WSLを使用しない場合

WSL

WSLを使用する場合

WSLに開発に必要なミドルウェア、(Apache HTTP Server、PHP)をインストールする。
エクスプローラーに \wsl$[ディストーションの名前] を入力すると、WindowsからLinuxのファイルにアクセスできる。

せんぱい「ぼくは Debian を利用しているので、」

\wsl$\Debian

せんぱい「このように入力してアクセスできるよ。
だから、Apache HTTP Server のDocument Root の」

\wsl$\Debian\var\www\html\ にアクセスして、その配下に作成したphpを設置

そして、 http://localhost/test.php にアクセスすると「hoge」と表示されるのが分かる。

要件例その2 デバッグ環境の構築の場合

開発の生産性をあげるにはデバッグ環境は必須。
ブレークポイントを打ち、スキップ実行し、変数の内容を目で追いながら、ロジックを確認していく。。。
というのは開発工数を大きく削減するものとして広く認知されている。

Apatch HTTP Server や Tomcat などのミドルウェアを実行するEclipseのようなIDEでは、デバッグ機能がそのIDEの中に組み込まれているので環境構築は容易。

だけど、Apatche HTTP Server やPHP などのランタイムやミドルウェアはローカルPC、つまりWindows上で動いているので本番環境にあるLinuxで動作させたいときはその環境の差異によって想定しない動作が発生する可能性がある。

なぜなら、LXCoreが全てのファンクションコールに対応できない可能性があるから。。。!

デジ子「LXCoreさん、がんばってるんですけどね」

せんぱい「知り合い!?」

WSLを使用しない場合

ユースケース その1で使用したWindowsの中にLinuxが稼働するような環境のデバッグは
ローカルのPCで編集したデバッグ対象のプログラムを何らかの方法で仮想化ソフトウェアに同期させる必要がある。

そして更に、開発エディタ上で動作するデバッガと仮想化ソフトウェア上にあるデバッグ対象のプログラムを通信させてデバッグに必要な情報をやりとりする必要がある。

デバッグ対象のプログラムを同期させる為にはSCPやFTPでのアップロードやSambaでファイル共有などを行う必要がある。
その為、手間が結構かかる。

デバッグに必要な情報を開発エディタ側に送る為にはローカルPCと仮想化ソフトウェア上にあるLinuxが相互に通信する必要があってこの通信の設定も一苦労。

WSLを使用する場合!

使わない方法に比べて一気にシンプル!
WSLと合わせてVisual Studio Code(以下、VS Code) というエディタの組み合わせで実現が可能。
VS Code の拡張機能の中で、「Remote Development」が協力。

Remote Development により、SSHで接続可能なリモートサーバやコンテナ、WSL上にあるファイルをVS Codeから直接編集できるようになる。

つまりつまり、ローカルPCにソースコードを持つ必要はない。
リモートサーバー上のファイルをあたかもローカルPCにあるファイルのように扱うことができる。

更に、Remote Developmentを使用するとVS Code の拡張機能をリモートサーバーにインストールし、リモートサーバー上で動作させることができる。

つまり、Remote Devlopmentの拡張機能を導入することでWSLを使わない場合の下記工程を簡略化させることができる。

  • デバッグ対象プログラムのLinux上への同期
  • デバッグ対象プログラムとデバッグ用モジュール間の通信

実際にやってみると。。。
WSLを起動

$sudo su -
# apt-get update && apt-get install -y php apache2 php-dev php-pear 

PHPでデバッグするために必要なモジュール「Xdebug」をインストール。

# pecl install xdebug

PECLって?

PECL(ピクル、PHP Extension Community Library)は、PHPで利用できる拡張ライブラリ(パッケージ)を提供しているサービス。

PECLで提供されるライブラリはCで記述されているため、PHPで記述されたPEARのライブラリよりも高速に動作する。
PECLにより提供されるライブラリはPHPの拡張モジュールとしてインストールされる。
一方で、PEARライブラリはPHPのバージョンアップに伴う再インストールが原則として不要なのに対し、PECL拡張モジュールはPHP内部のAPIに依存する部分があるため、PHPのバージョンアップに伴いAPIが変更された場合は再コンパイルを必要とする。

2つに分断されたPHPの世界

PHPの世界では、ライブラリ配布方式が2つの世界に分断されてしまっています。
ライブラリの種類 配布サイト インストーラ/
PHP言語で書かれたライブラリ Packagist (https://packagist.org/) Composer
C言語で書かれたライブラリ PECL (https://pecl.php.net/) pecl

Xdebugの設定を行う。/etc/php/7.2/mods-available/xdebug.ini を作成し、下記のように記述。

zend_extension=/usr/lib/php/20170718/xdebug.so
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_enable = 127.0.0.1

設定を有効にするよう、上記 xdebug.ini のシンボリックリンクを /etc/php/7.2/apache2/conf.d に作成する。

#cd  /etc/php/7.2/apache2/conf.d
#ln -s /etc/php/7.2/mods-available/xdebug.ini

せんぱいのメモ!

lnコマンド――ファイルのハードリンクとシンボリックリンクを作る。

# /etc/init.d/apache2 restart

続いてRemote Devlopmentを可能にする拡張機能をVS Codeにインストールする。
VS Codeの左側の、Activity Bar にあるExtensionsアイコンをクリック。

検索欄に「remote development」と入力する。
候補に出てくる、「Remote Development」の拡張機能をインストール。

実際に接続するには?

VS Code 左下隅の緑になってる 「><」こんなアイコンをクリック。
そうすると、上部にメニューが出てくるのでそこから 「Remote -WSL: New Window」を選択する。

そうすると、WSLのWindowsにぐいんぐいんと接続を試みる。
Side Bar のExploreにある「Open Folder」をクリックするとWSL上のディレクトリが表示されているのを見ることができる筈!

同様に、 デバッグ用の「php debug」も設定していく。

ユースケースその3 SSHによるポートフォワード

顧客のネットワークやクラウド上にあるデータベースなどにアクセスする際、踏み台サーバーを経由したSSHポートフォワードを使用することがある。

「ポートフォワーディング」とは、インターネットから特定のポート番号宛てに届いたパケットを、あらかじめ設定しておいたLAN側の機器に転送する機能。
1つのグローバルIPアドレスでポート毎に複数のサーバーへ振り分けを行ったり、ポート変換を行うことができる。

一般的に多くの企業では、セキュリティ上の観点から外部との通信は最小限に抑えるだろう。
ポートフォワーディングを用いることでインターネットに接続するグローバルIPアドレスをひとつに絞り、効率的にセキュリティ対策などが行え、社内LANにつながる複数のローカルコンピューターが直接、外部と通信する心配がない。ポートフォワーディングは、SSLといった暗号化技術を併用するケースがほとんどで、通信全体が暗号化される。

ポートフォワードを使用すると踏み台サーバーにSSH接続さえできれば、踏み台経由であらゆるサービスに接続することが可能となる!

例えば、例えば、顧客ネットワーク上にあるMySQLサーバーに対して踏み台サーバーへのSSH接続経由のポートフォワードでアクセスできる。
具体的にいうと、踏み台サーバーのホスト名をbastion.example.com、踏み台サーバーのホスト名をmysql.example.comとするとLinuxやmacだとつぎのコマンドで実現できる。

デジ子「ポートフォワード…ポートピアと響き似てますね」

せんぱい「犯人はヤスなやつ!
ポートフォワード(port forward)ね!
インターネットから特定のポート番号宛てに届いたパケットを、あらかじめ設定しておいたLAN側の機器に転送する機能のことね!」

踏み台サーバーのホスト名を bastion.example.com

このコマンドを実施し、クライアントPCのMySQLクライアントツールでlocalhostの3306宛に接続するとMySQLサーバー上のMySQLが利用することができる。

物理的なマシンが1台でも複数の仮想環境を構築することで並列して作業ができます。
OSよりも上位の層からプログラムを実行するので、仮想化を実現するためのOSを必要としない。

ハイパーバイザーには二種類あり、狭義にはハードウェア上でプログラムを直接稼働する方式がある。
また、広義にはOS上でアプリケーションソフトとして稼働し、その上で様々なOSを動作できるようにするものも含まれている。
前者の例としてXenやVMwareESX、KVMなどがあり、後者の例としてVMwareServerやVirtualPCなどがある。

こういった仮想的なコンピュータを仮想マシンというが、仮想マシンを作成することで、同じ物理マシン内で複数の異なるOSを並列に実行することが可能!
Virtual Serverを置き換える形で。

順番に見ていってみる。
まずは予備知識として「ls」コマンドと「シンボリックリンク」について簡単に説明。

「ls」コマンドは「ファイルやディレクトリの一覧を表示するときに使うコマンド」。

シンボリックリンクは「ファイルやフォルダの代理人ファイル」。
Windowsでの詳しい人は「ショートカット」みたいなもの。

ファンクションコール、といってもその動作は深いんだけど。。。

MS-DOSは、文字を表示したりキーボードから入力を行う時
プログラムが直接それを行うのではなく、OSが代行する。
つまり、プログラムはOSに対してOSが提供しているサービスを要求する

MS-DOSが提供する各種のサービスを要求するには 21 番にシステムコールする。
割り込みタイプ21番は特別なシステムコールで、さらに分岐していく。
このシステムコールは AH レジスタの内容によって目的のサブルーチンに分岐する。
この21番のシステムコールを特別に、ファンクションコールと呼ぶ

「Hyper-V」は、単一のハードウェア上で複数のOSの同時実行を可能にするハイパーバイザー型の仮想化技術。
ちょっと想像するのが難しいかもしれないが、ハイパーバイザーの視点から見れば、Hyper-Vの仮想マシンを管理する(そして実行しているように見える)Windows 10のOS(ホストOS、管理OS)もまた“一種の仮想マシン”とみなしていると言える。
ホストOSからは、Hyper-Vの管理インタフェース(「Hyper-Vマネージャー」やWMI(Windows Management Instrumentation)、仮想マシンバスなど)を通じて、仮想マシンとそのゲストOSにアクセスすることができる。

Bash on Ubuntu on Windowsは、Linuxカーネルが存在し、その上で動く「/bin/bash」プロセスではない。
プロセスの視点から見ると、Windows上で動く他のプロセスと全く同じように見えるのだ!

デジ子「うーん、ちょっと後半だいぶ複雑な感じになりましたけど

せんぱい「まあ、WSL上で動いているLinuxのシステムも、Windows10で動いているシステムも同じプロセスで見えるんやで、という事だよね」

まとめ

せんぱい「WSLでは、Windowsでさくさく動作するLinux環境をつくることができるんだ。」

デジ子「WSLでのプロセスは、Windows10と同じ感じだから処理もサクサク、ということですね!」

せんぱい「そう、そして互いにファイルのやりとりも簡単!このサクサク感を出す為に、これまでの仮想化でありそうでなかった工夫を沢山しているんだ!」

下記詳細はこの号の「Windows 最新開発環境」、もしくは下記記事を書かれた方の記事をご参考ください!

%d人のブロガーが「いいね」をつけました。