テクノロジー

WSLとDockerと開発と

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

また、GCPを導入を検討するにあたりいろいろ調べていて、Google Cloud Consoleを操作するのにはWSLを活用するとよい、とあったので興味もあったところでした。

「Windows 最新開発環境」、こちらの記事を参考に、特に実際の開発環境の構築例を重点的に
ポイントをまとめていきたいと思います。

上記特殊は大きく4つに分かれる特集となっていました。

  1. Windowsでの開発課題
  2. WSL(Windows Subsystem for Linux)が開発にもたらすメリット
  3. 実践!WSL1&2、Windows Terminal/シェルの統合が生み出すLinuxとの親和性
  4. 開発/実行環境の差異によるデプロイ問題の改善 Remote Developmentで簡単コンテナ活用

こちらの記事の、実際の構成例の部分を重点的にみつつ、ざっくりポイントだけ見ていきたいと思います。

  1. Windowsでの開発課題

Windowsは初心者でも馴染みやすかったり、シェアが広かったりいつの時代も広く利用されてきたOS。
しかし、サーバーサイドのアプリケーションの実行基盤はCentOSやDebianなどのLinuxである事が多かった。

この、「開発環境と実行環境の差異」によって、実行環境で動作させたら想定しない等の課題があった。

Windowsによる開発の歴史

1.1つの開発環境を共有パターン

Windows上のエディタで作成したコードをFTPなどでLinux上のサーバーにアップロードする方法。

エンジニア全員でサーバー上の同じ開発環境を共有する為、開発環境を壊しかねない、チャレンジングなコードのアップロードはご法度。

2.Windows上に開発に必要なミドルウェアを構築パターン

アプリケーション開発に必要なミドルウェア(Apache HTTP Server や MySQL など)をローカルのWindowsで動かす方法。
代表例がXAMPPなど。

「開発環境と実行基盤の差異」による問題は残る

3.仮想環境で改善を図るパターン

仮想環境はOSの中にOSをエミュレートする方法。
エミュレート(emulate)とは、あるものががそれとは異なる別のハードウェアやソフトウェアの環境を模倣すること。

Windows上で作成したプログラムをどのように仮想環境のLinuxに転送するかが課題。
FTP、SCP(Secure Copy Protocol)、SMB(Server Message Block)などいろいろあるけれど利用できるよう設定するのが一苦労。

Windowsによる開発の改善方法

これまでの改善方法を解決する方法として、下記3つの技術がポイント!

  • Windows Subsystem for Linux(WSL)
  • Windows Terminal
  • Visual Studio Code

それぞれ、簡単に触れると

  • Windows Subsystem for Linux(WSL)
    Windowsの中でLinuxを実行できるテクノロジー。

  • Windows Terminal
    PowerShell、コマンドプロンプト、WSL上で動作するシェルなどの複数のコマンドラインを一つの統合した環境で操作できるターミナル。WindowsのCUIとしてはコマンドプロンプトが歴史長いですけど「コマンドプロンプトに置き換わるもの」 として「PowerShell」が標準になっていくらしい。
    PowerShellのメリットとしては下記があると。

  • コマンドレットを使える

  • Microsoftサービスも操作できる
  • 複数の命令を組み合わせて高度な処理を実行できる
  • 統合開発環境「PowerShell ISE」が用意されている

  • Visual Studio Code
    Microsoftによって開発されたコードエディタ。
    Microsoftだから、更にWindowsとも相性がいいのかな?

そんな感じで、
– Windows Subsystem for Linux(WSL)
– Windows Terminal
– Visual Studio Code

をインストールする。

インストール方法は下記記事や公式などを参考にしてもらうとよいかと思います。
Linux 用 Windows サブシステムをインストールする

Windows Terminal

Visual Studio Code

  1. WSL(Windows Subsystem for Linux)が開発にもたらすメリットとは!?
    まず、導入が簡単
    WSLを導入するまでは数ステップ、10分ほどでOSインストール済の環境を準備することができる。
    そして、起動が一瞬。

そして、WindowsとLinux間の親和性が高い。
Windows⇔Linux間で相互にファイルをやりとりするのも簡単。
別の仮想環境を構築するパターンだと、CIFS(Common Internet File System)プロトコルに対応したサーバーを立てたりする必要があったがWSLではとても簡単。

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

のように記述する。
Debianの場合は

\\wsl$\Debian

の場所にアクセスすると、ファイルを参照できる。

逆に、LinuxからWindowsにアクセスする場合は

/mnt/[ドライブ名]

のようにすることでアクセスできる。
なので、Cドライブの場合は

/mnt/c

となる。

WSL 1 と WSL 2との違い

WSL1 

LinuxカーネルファンクションコールをLXCoreというサブシステムによってWindowsへのファンクションコールに変換されている。
Linuxカーネルが存在しない。

LXCore と呼ばれる「サブシステム」が作り出しており、カーネルへのファンクションコールをWindowsカーネルへのファンクションコールに変換して動作している。

「Hyper-V」は、単一のハードウェア上で複数のOSの同時実行を可能にするハイパーバイザー型の仮想化技術です。
ちょっと想像するのが難しいかもしれませんが、ハイパーバイザーの視点から見れば、Hyper-Vの仮想マシンを管理する(そして実行しているように見える)Windows 10のOS(ホストOS、管理OS)もまた“一種の仮想マシン”といえます。

ホストOSからは、Hyper-Vの管理インタフェース(「Hyper-Vマネージャー」やWMI(Windows Management Instrumentation)、仮想マシンバスなど)を通じて、仮想マシンとそのゲストOSにアクセスすることができます。

WSL1にはLinuxカーネルが存在しない為、ファンクションコールのすべてをLXCoreでは変換しきれない。
なので、複雑なシステムは再現できない。
WSL 2はフル互換のLinuxが動作する環境。
これらの課題を克服し、Dockerを動作させる事ができる為、開発にはオススメ!

ただ、Windows側へのアクセスが多い場合はWLS2より、WDL1が推奨されるそう。
セットアップにはWSL2のほうがひと手間かかる為、DockerなどのLinuxネイティブな機能が不要であれば、WSL 1を使うのもあり。

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

比較項目 WSL 1 WSL 2
実現方法 LXCoreによるコマンドの変換 Linuxカーネル
LXCoreによるコマンドの変換 Linuxカーネル
実現方法 LXCoreによるコマンドの変換 Linuxカーネル

4.開発/実行環境の差異によるデプロイ問題の改善!Remote Developmentで簡単コンテナ活用

ここから、実際

  • Windows Subsystem for Linux(WSL)
  • Windows Terminal
  • Visual Studio Code

を活用し、どのように開発環境を整えるとよいのか!の話になります。
とにかくコンテナによって仮想環境を構築できるハードルが下がり、それによりそれぞれで開発環境などを気軽に共有できるようになりました!
ということなんですね。

Windowsにおける開発については「開発環境と実行基盤の差」が問題であった。
Windowsで開発するけれど、本番環境はlinux、という場合が多かった。

その問題に、大きく貢献したのがWSL。
数ステップでWindow上にLinuxを構築でき、またWindowsとの親和性が高く相互のファイルアクセスも簡単。

起動も簡単、使いたいときにすぐ使える。

この、非常に有用なWSLと同じ、仮想化によってWindowsでの開発問題を改善、利便性を加速させるものとして「Docker」がある。

簡単に、Dockerとは何か?なぜ開発にDockerが必要なのか?

環境をまるごと扱う!Docker

Dockerはコンテナ型の仮想環境を作成・配布・実行する仕組みを持ってる。

仮想化方法として、
「ホスト型仮想化」
「コンテナ型仮想化」
「ハイパーバイザ型仮想化」

などがある。

  • ホスト型仮想化
    仮想化ソフトウェアの上でカーネルを内包したゲストOSが稼働しさらにそのOS上でプロセスが動作する

  • コンテナ型仮想化
    仮想化ソフトウェアやゲストOSというものは存在しない。
    Linuxカーネルの機能である「namespace」により、プロセス空間やネットワーク、ファイルシステムを分離し、さらにホストOSのカーネルを利用することになる。

※他に仮想化タイプとしてハイパーバイザ型がある

コンテナ内にはカーネルを含む必要ない。
「namespace」により区切られ、その空間がホスト型仮想化におけるゲストOSに相当する。

このコンテナの中でUbuntuやCentOSといった様々なOSが稼働。

コンテナの最大のメリットはカーネルを含まないことによる軽量化で、それにより可搬性が向上すること。

Dockerならではの開発スタイル!

コンテナを稼働させるツールの、Dockerが入っているPCやサーバーがあると
そのコンテナをどこでも動作させることができる。

  1. 開発リーダーはDockerfileとソースコードをGitリポジトリにpushする
  2. 開発エンジニアはGitリポジトリからDockerfileとソースコードをclone、またはpullする(開発エンジニアのPC上にあるGitで実行)
  3. 開発エンジニアはDockerfileを使用し、開発環境のコンテナを作成。(開発エンジニアのPC上にあるDockerエンジニアがDockerfileの内容に従って適宜Docker Hubを参照しながら構築)
  4. 開発エンジニアはソースコードの修正、Gitリポジトリへのpush/pullを繰り返す(Dockerコンテナ内のGitで実行)
  5. 開発リーダーはGitリポジトリにpushされたソースコードに基づきDockerイメージを作成、DockerリポジトリにPushする

Kubernetesなどのコンテナオーケストレータにより読み込まれる。
コンテナオーケストラはコンテナを本番環境で実用的に稼働させる仕組み。

開発リーダーが最初に作成したDockerイメージ(コンテナのもととなるイメージ)は開発環境・本番環境において同じものが使用されている。

重要なポイントとして、OSを含む環境ごと・Dockerリポジトリを経由して開発環境と本番環境との間でやりとりを行っている。

Dockerイメージの中に開発に必要なものが入っている
よって、開発エンジニアが自ら開発環境を構築する手間が省ける

開発環境で動作したコンテナをまるごと持っている為、本番環境はDockerコンテナさえ動けばよい

Dockerによる開発スタイルではコンテナのその可搬性の高さから、WSLと同じ開発環境と実行基盤の差異をなくすことができる。
また、開発エンジニアが開発環境を構築する手間を省くこともできる。

WSL2とDockerは相性ぴったり!

これまで、WindowsでDockerを使用するには Windows10 Pro以上が必要だった。

Docker Desktop for Windowsは、Moby VMというLinuxカーネルを使いコンテナを起動。
その仮想マシン内のLinuxカーネルを使用しコンテナを起動する。
Moby VMの起動には仮想化ハイパーバイザであるHyper-Vが必要となる。
Heper-VはWindows 10 Pro 以上が必要。

一方、Docker Desk WSL 2 backend の場合はDockerコンテナ稼働に必要な仮想化ハイパーバイザ、Linux仮想マシン、LinuxカーネルはすべてWSL2をインストールすると自動的に作成される。
さらに、WSL2専用の軽量化Hyper-VはWindows10 Homeにも利用できるよう設計されている。

Docker Desktop WSL 2 backend と組み合わせることでWindows 10 HomeでもDockerが利用できる。

さらにさらに、Visual Studio CodeとDockerは相性ぴったり!

Visual Studio Code(以下、VS Code {なんかバーサスみたい})

開発エンジニアはDockerfileを使用し、開発環境のコンテナを作成。(開発エンジニアのPC上にあるDockerエンジニアがDockerfileの内容に従って適宜Docker Hubを参照しながら構築)

上記を実行する為にはDockerfileをもとにdocker buildコマンドを実行しコンテナを作成、さらにホスト上のソースコードをコンテナにマウントするためdockerコマンドを実行したりと多くのコマンド操作が必要となる。

これだけで多くの工数が必要となる。

VS CodeのRemote Development拡張機能を使用すると、これらをすべて自動化できる。
その為の設定ファイルはdevcontainer.jsonもGitリポジトリに事前にPushしておき、開発エンジニアにPullしてもらう。
Remote Development拡張機能に読み込ませれば自動でDocker周りの環境が構築される。

実践編!WindowsにおいてのDockerによる開発!

開発の流れ!

  1. WSL 2 を使用可能とする
  2. Docker Desktop WSL 2 backendをインストールする
  3. ソースコード、及びコンテナ関連設定ファイルの作成、そしてGitへpush
  4. ソースコード及びコンテナ関連設定ファイルをGitからCloneする
  5. コンテナ化された開発環境の展開を行う
  6. ソースコードの修正、及びGitへpushする

Windows 10 が稼働している環境を「ホストOS」(接待する側、なのでいろいろおもてなしする側)。
ホストOS上でコンテナとして稼働している環境を「コンテナ」と呼ぶ。

何はともあれ、WSL 2を使用可能に

Docker Desktop WSL 2 backend を使用するためにはWSL 2の Linuxカーネルを更新する必要がある。
Microsoft公式ページのUpdating the WSL 2 Linux karnelページへ行き、Kanelをダウンロードし、実行する。

Docker Desktop WSL 2 backendをインストール!

Docker公式ページへ。
「Download」の節からダウンロード。

下記へ遷移し、「Get Docker Desktop for Windows」をクリック。
https://hub.docker.com/editions/community/docker-ce-desktop-windows/

このインストールは Windows10 の状態でよいのかな?
Docker for Windowsだから、Windowsか。

ソースコード、そしてコンテナ関連設定ファイルの作成・GitへのPush!

GitリポジトリにPushするためのコンテナ関連の設定ファイルとソースコードを作成する。
これがベースとなる開発環境。

そのファイル群やディレクトリ構成は下記みたいになる。

GitリポジトリのTop
|-.devcontainer
| |-devcontainer.json
| |-Dockerfile
|_src
  |_index.php

devcontainer配下devcontainer.json

Remote Development拡張機能を使用すると、VS CodeからDockerコンテナに接続し、Docker上のファイルを直接編集でき、Dockerコンテナ自体の生成も拡張機能で作成することができる。

devcontainer.jsonは生成するコンテナファイルの詳細について記述・その記述内容によってコンテナのイメージやマウントの設定などを決定する。

参考にした記事では下記にて設定してある。

{
# 設定を一意に識別する任意の名称にする
"name": "Hello", 

# コンテナを生成するためのDockerfileのファイル名を指定する
"dockerFile": "Dockerfile",

# この設定によりホストOSのポート80宛の通信がコンテナの80に転送される
# ホストPCからブラウザで動作確認するために必要
"forwardPorts": [80],

#デフォルトでは、VS Codeからのコンテナ起動時のコマンドはwhile sleep 1000; do :; doneに上書きされてしまうがspれwp防止する為 "overrideCommand": false,

#GitリポジトリのsrcディレクトリをApacheのドキュメントルートである/var/www/htmlにマウント
"mounts": [
    "source=${localWorkspaceFolder}/src,target=/var/www/html/,type=bind,consistency=cached"
    ]
}

devcontainer配下Dockerfile

VS CodeのRemote Development拡張機能で生成されるコンテナ内で実施するコマンドを定義したDockerfile。
devcontainer配下devcontainer.jsonで定義されている。

参照した記事では下記の内容で設定されている

# PHPとApache HTTP ServerがインストールされたOfficialイメージをpullする
FROM php:7.2.30-apache

#修正したソースコードをGitリポジトリにアップするためにgitをインストール
RUN apt-get update && apt-get -y install git

上記、DockerfileでGitをインストールしているがVS CodeのGitの機能はコンテナ側で動作する。
その為、コンテナ側にもGitのインストールが必要となる。

src/index.phpの生成

サンプル、ブラウザでHey!と表示するだけの簡単なPHPスクリプト。

<?php
echo "hoge";
?>

作成したファイルをGitリポジトリにPush。

$ git add.
$ git commit -a -m "first commit"
$ git push origin master

先程GitリポジトリにPushしたファイルをClone(2回目以降はPull)


$git clone https://repo.example.com/ntake/webapp

コンテナ化された開発環境を展開

  • さっきGitリポジトリからCloneしたファイル
  • Remote Development拡張機能

上記により、開発環境に必要なDockerコンテナを生成する。

VS Codeを起動し、左下の緑ボタンをクリック!
コマンドリストが表示され、その中から「Remote-Containers:Open Folder in Container”’」をクリック。

そして先程CloneしたGitディレクトリを選択。
VS Code右下に通知が表示され、コンテナの生成がはじまる。
初回ははコンテナ生成したりと時間がかかるが、二回目以降は素早く起動できる。

ソースコードの修正、そしてGitへのPush

コンテナ内のソースコードを修正・VS CodeでGitリポジトリへPushする操作まで説明。
index.phpを編集し、次のfugaと表示するスクリプトに変更。

<?php
echo "Bye!";
    >    

修正がおわったらVS Codeの左メニューにある、Source Controlボタンをクリック。
Commitコメントを入力して、上部に出てきたチェックボタンをクリックし、Commit。
次はPushで、下部の、上矢印をクリックするとPushは完了となる。

ホストPCのブラウザからhttp://localhost/にアクセスすると、ブラウザ上に「Bye」が表示されるだろう。
VSCodeからGitリポジトリへPushはコンテナ内で行われているが、コンテナ内にはGitリポジトリへの認証情報を定義していないにも関わらず問題なくPushできた。
それは、ホストOS上でHTTPSでCloneした場合に限り、その認証情報をコンテナでも再利用できるから。
※SSHのキーの場合は別途設定が必要

開発を終了するとき

開発を終えてVS Codeを終了させる。
同時に、コンテナも終了するが、コンテナからホストOS上のソースコードをマウントしていたのでコンテナ上でソースコードに加えた変更やGitの操作履歴が消えることはない。

さいごに

PCを起動すると、右下にDockerくじらさんがいる…!
ちょっとほっこり。
かつてのOfficeイルカさんみたい。

また、ここで参考にさせていた記事を紹介させていただきます。

上記号の、「Windows 最新開発環境」でした!

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