小浜です。
今回はWindows 10 20H2 に WSL 2 をインストールして、その中でSQL ServerとRedisを起動してみます。
WSL2とは
- 参考 https://www.atmarkit.co.jp/ait/articles/1906/14/news019.html 完全なLinuxがWindows 10上で稼働する? 「WSL 2」とは:Windows 10 The Latest – @IT
WSL2は、専用の仮想マシン環境である「Light Weight utility Virtual Machine」(軽量ユーティリティーVM)を使い、ローカルパッチ(Microsoftによる独自パッチ)を当てたLinuxカーネルバイナリを動作させ、仮想マシン内にLinuxの実行環境を作ったものとのことです。
WSL2側は、ホスト機であるWindows PCとは別のIPアドレスを持っていて、別の仮想マシンと考えて良いです。
起動は約2秒と高速なので快適です。
WSL2側からは Cドライブが /mnt/c/ 以下にマウントされて見えており、
WSL2側からホスト機であるWindows PC側のファイルを(若干遅いですが)読み書きできます。
WSL2のインストール
- 参考 https://docs.microsoft.com/ja-jp/windows/wsl/install-win10 Windows Subsystem for Linux (WSL) を Windows 10 にインストールする | Microsoft Docs
- 参考 https://docs.microsoft.com/en-us/windows/wsl/install-win10 Install Windows Subsystem for Linux (WSL) on Windows 10 | Microsoft Docs
- 参考 https://www.kkaneko.jp/tools/wsl/wsl2.html WSL 2 のインストール,Ubuntu 20.04, 18.04 のインストールと利用
■ WSL2 インストール
管理者権限のPowerShellから実施します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# Windows Subsubsystem for Linux を有効化する
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
# 仮想マシンプラットフォームのオプションコンポーネントを有効化する
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# WSL の既定(デフォルト)のバージョンを 2 に設定する
wsl --set-default-version 2
# マイクロソフト・ストアを開く
start ms-windows-store:
# マイクロソフト・ストアから ubuntu 20.04 LTS をインストール
# WSLのバージョン表示
wsl -l -v
|
以下は古いのが有効になっている場合の表示例
1
2
3
4
5
|
PS C:\Users\george> wsl -l -v
NAMESTATE VERSION
* Ubuntu-18.04Stopped 1
Ubuntu-20.04Running 2
PS C:\Users\george>
|
- デフォルト起動の指定
1
2
3
|
# wsl2 Ubuntu-20.04 の方をデフォルトにする
wsl --set-default Ubuntu-20.04
wsl -l -v
|
- wslの起動
1
2
3
4
5
6
7
|
# Ubuntu側のコマンドの起動
wsl ip a
# wslの起動
wsl
# スタートメニューからWSL2を起動するのもアリ。
|
WSL2 Ubuntu 20.04 LTS セットアップ
- 参考 https://qiita.com/v2okimochi/items/f53edcf79a4b71f519b1 Windows10 WSL2にLinux居城を爆誕させる – Qiita
WSL2の中のUbuntuの設定関連はココ
ここでは、WSL2の中にインストールしたUbuntuの設定を行います。
■ wslの起動
1
2
3
4
5
6
7
|
# Ubuntu側のコマンドの起動
wsl ip a
# wslの起動
wsl
# スタートメニューからWSL2を起動するのもアリ。
|
■ WSL2の中のUbuntu 20.04の設定
- sudo可能ユーザーを追加します。
1
2
3
|
sudo bash
su -
visudo
|
以下のようにsudoersに記載してユーザーgeorgeをsudo可能にします。
ユーザー名は各自のものに読み替えてください。
1
|
george ALL=(ALL) NOPASSWD: ALL
|
- ロケールの指定
1
2
3
|
sudo apt -y install language-pack-ja
sudo update-locale LANG=ja_JP.UTF8
sudo apt -y install manpages-ja manpages-ja-dev
|
- 便利コマンドのインストール
1
2
3
4
5
6
7
8
9
10
|
# よく使うコマンドをインストール
sudo apt install -y vim
sudo apt install -y zip unzip
sudo apt install -y git
# 以下のコマンドは趣味のソフトなのでお好みでインストール。
sudo apt install -y emacs
sudo apt install -y xorg
sudo apt install -y x11-apps
sudo apt install -y firefox
|
WSL2側のIPアドレスをhostsに登録する
WSL2のデフォルト設定では、WSL2側のIPアドレスはWindows PCとは違うものがついていて、起動する毎に毎回ランダムに変わります。
また、内部の仮想DHCPサーバからのIPアドレスリース時間はおそらく9時間から24時間程度と予想されるため、長時間起動し続けるような使い方は向いていないようです。
1
2
3
4
5
|
PS C:\HOME> wsl ip a
4: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
inet 172.24.156.166/20 brd 172.24.159.255 scope global eth0
valid_lft forever preferred_lft forever
PS C:\HOME>
|
Windows PCのPowerShellとかから、wsl ip a とすれば上のような表示が得られるので、
文字列加工して C:Windows/System32/drivers/etc/hosts を編集する MSYS2 bash スクリプトを参考までに以下に示します。
hostsファイルを書き換えるためAdministratorsの特権がついた状態で実行する必要です。
hostsファイルに記入すれば、Windows側からは、wsl2.hyperv.local というホスト名でアクセスすれば、wsl2側のIPアドレスに到達できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
cat > wsl-ubuntu-start.sh << "EOF"
#!/bin/bash
#
# wsl2側のIPアドレスを/etc/hostsに登録する
#
function wsl-ubuntu-start() {
# wsl コマンド存在チェック
if type wsl 1>/dev/null 2>/dev/null ; then
WSL_COMMAND_FOUND=yes
else
echo "wsl command not found. abort."
return 1
fi
WSL2_HOST_IP_ADDR=$( wsl ip -4 -br a | grep eth0 | awk '{print $3}' | sed -e 's%/.*$%%g' )
if [ -z "${WSL2_HOST_IP_ADDR}" ] ; then
echo "wsl ip addr is null. abort."
return 1
fi
WSL2_HOST_NAME="wsl2.hyperv.local wsl2"
WSL2_HOSTS_LINE="${WSL2_HOST_IP_ADDR} ${WSL2_HOST_NAME}"
WINDOWS_HOSTS_FILE="/c/windows/system32/drivers/etc/hosts"
WINDOWS_HOSTS_FILE_2="/c/windows/system32/drivers/etc/hosts_2"
cp ${WINDOWS_HOSTS_FILE} ${WINDOWS_HOSTS_FILE_2}
RC=$?
if [ $RC -ne 0 ]; then
echo "file copy failed. abort."
return 1
fi
cat ${WINDOWS_HOSTS_FILE_2} | grep -v "${WSL2_HOST_NAME}" > ${WINDOWS_HOSTS_FILE}
echo "${WSL2_HOSTS_LINE}" >> ${WINDOWS_HOSTS_FILE}
cat ${WINDOWS_HOSTS_FILE}
}
wsl-ubuntu-start
#
# end of file
#
EOF
chmod +xwsl-ubuntu-start.sh
# スクリプト実行
bash wsl-ubuntu-start.sh
|
(別解)WSL2側のLISTENポートをWindows側からアクセス可能なように設定する
- 参考 https://roy-n-roy.github.io/Windows/WSL%EF%BC%86%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A/wslconfig/ wsl.conf と .wslconfig – roy-n-roy メモ
なお、.wslconfig の設定次第では以下のような設定があるので、WSL2側でLISTENしているポートがあれば、Windows PC側でLISTENしているように見せかける設定があるようです。
1
|
localhostForwarding=true# WSLのネットワークポート待ち受けを、ホストマシンにフォワーディングする
|
つまり、http://localhost:3000/ とかにアクセスすると、実はWSL2側で動作している node express に行く、というようなことも可能とのことです。
WSL2 Ubuntu 20.04 Docker 環境構築
- 参考 https://qiita.com/amenoyoya/items/ca9210593395dbfc8531 WSL2 + Ubuntu 20.04 + Docker 開発環境構築 – Qiita
WSL2を使うDocker環境構築では、Docker for Windows Desktop (WSL2対応版) をインストールして使うのが普通です。
ここでは WSL2 Ubuntu側にストレートにLinux用のDockerパッケージをインストールしてみます。
以下、Qiitaの記事のそのまんまですが、WSL2へのDockerのインストール方法を紹介します。
WSL2のUbuntu上での操作を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# アップデート
sudo apt update && sudo apt upgrade -y
# -- Ubuntu 20.04 on WSL2
# Docker (Community Edition) インストール
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update && sudo apt install -y docker-ce
## dockerデーモン起動
sudo service docker start
# WSL2 では、デーモンをスタートアップに登録することができない
# スタートアップに登録したい場合は、Windowsのタスクスケジューラに登録する必要がある
# 参考: https://qiita.com/Ningensei848/items/75adeb29bb143633d60c
# Windows再起動の度に sudo service docker start すれば良いだけなので、ここではスタートアップ登録までは行わない
# WSL2 には cgroup 用ディレクトリがデフォルトで作られていないため作成しておく
## これをしておかないと Docker でプロセスのグループ化が必要になったときにエラーが起きる
sudo mkdir -p /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
# docker-compose 導入
sudo curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Dockerを sudo なしで実行可能に
## ※ カレントユーザーをdockerグループに所属させた上で docker.sock へのグループ書き込み権限を付与すればよい
sudo gpasswd -a $USER docker
sudo chgrp docker /var/run/docker.sock
sudo service docker restart
# 一度ログアウトしないと反映されないため、一旦 exit
exit
|
WSL2スタートアップ時にdocker serviceを起動するハック
- 参考 https://qiita.com/amenoyoya/items/41a2334cbc1facb87864 WSL2でスタートアップスクリプトを実行するHack – Qiita
wsl起動時にdocker serviceを開始するハックです。
これまたQiitaの記事のそのまんまですが紹介します。
WSL2のUbuntuは起動時に各種デーモン(Windowsでいうサービス)を起動しないため非常に高速に起動するのは良いですがちょっと不便な面もあります。
Docker用のデーモンをWSL2起動する毎に手動で起動しないといけないのです。
このハックを使うと、Docker用のデーモンをWSL2起動時に自答的に開始することができます。
WSL2のUbuntu上での操作を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# /sbin/mount -a 実行時に rc ファイルシステムをマウントするように設定
echo 'none none rc defaults 0 0' | sudo tee -a /etc/fstab
# => これにより起動時に /sbin/mount.rc ファイルが呼び出されるようになる
# /sbin/mount.rc ファイルを実行可能スクリプトとして作成
echo '#!/bin/bash' | sudo tee /sbin/mount.rc
sudo chmod +x /sbin/mount.rc
# service docker start を /sbin/mount.rc に追記
echo 'service docker start' | sudo tee -a /sbin/mount.rc
# WSL2 には cgroup 用ディレクトリがデフォルトで作られていないため、以下もスタートアップスクリプトに登録しておく
## これをしておかないと Docker でプロセスのグループ化が必要になったときにエラーが起きる
echo 'mkdir -p /sys/fs/cgroup/systemd && mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd' | sudo tee -a /sbin/mount.rc
# スタートアップスクリプト確認
sudo cat /sbin/mount.rc
|
Microsoft SQL Server の docker image を使う
- 参考 https://hub.docker.com/_/microsoft-mssql-server Microsoft SQL Server
- 参考 https://docs.microsoft.com/ja-jp/sql/linux/sql-server-linux-docker-container-deployment?view=sql-server-ver15&pivots=cs1-bash SQL Server Docker コンテナーをデプロイして接続する – SQL Server | Microsoft Docs
- 参考 https://ittech-nsnl.hatenablog.com/entry/2019/10/27/003013 DockerでSQL Server環境を構築する – ITエンジニア日記 ~NO SKILL, NO LIFE~
Dockerの動作サンプルとして、Microsoft SQL ServerのLinux版のDockerイメージを使ってみます。
WSL2のUbuntu上での操作を示します。
1
2
3
4
5
6
7
8
9
|
# dockerイメージの取得
docker image pull mcr.microsoft.com/mssql/server:2017-latest
# dockerコマンドによる起動
# パスワードには大文字、小文字、記号が含まれている必要がある
docker run --name mssql1 -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=yourStrong(!)Password' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latest
# docker exec で Microsoft SQL Server のコンテナの中に乗り込む
docker exec -i -t mssql1 bash
|
Microsoft SQL Server のコンテナの中での操作。 SQL Serverを操作するコマンドラインツール sqlcmd を起動します。
1
2
|
# To connect Microsoft SQL server , use sqlcmd.
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$SA_PASSWORD"
|
sqlcmdの中の操作で、データベースの作成を行います。GOが必用なのが特徴的ですね。
最後のQUITでsqlcmdから脱出します。
1
2
3
4
5
|
CREATE DATABASE TestDB
GO
USE TestDB
GO
QUIT
|
SQL serverのdockerの中から脱出する。
1
|
exit
|
以上で、SQL Serverが起動しました。
Redis image を使う
- 参考 https://hub.docker.com/_/redis redis
- 参考 https://qiita.com/masataka715/items/abfd4b870024cbcebda7 Dockerで簡単にRedis試す – Qiita
上の記事通りに作っていきます。docker-composeを使っています。
作業用のディレクトリ testbed を作って、その中に docker-compose file を作ります。
WSL2のUbuntu上での操作を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
mkdir testbed
cd testbed
# docker-compose file の作成
cat > docker-compose.yml << "EOF"
version: '3'
services:
redis:
image: "redis:latest"
container_name: redis_test #下記のコマンド時に使用するコンテナ名
ports:
- "6379:6379" #redisのデフォルトのポートは6379
EOF
# docker image の pull
docker-compose pull
# 起動
docker-compose up -d
# ログ表示
docker-compose logs
# 停止
docker-compose down
|
以上で、Redisのサーバーが起動しました。
あとがき
Windows PC側からは、wsl2.hyperv.local:1433 や、 wsl2.hyperv.local:6379 でアクセスすることができます。
開発用の通信相手や、動作検証用のWEB/APIサーバとしても利用できます。
アプリのバージョン毎に検証用サーバを切り替えて起動するなんて使い方も考えられます(相応のディスク容量は必要ですが)。
Linux版のDockerイメージで提供されているJupyter Notebook のdockerイメージも起動できるので、色々役に立つと思います。