====== WSL2/Ubuntu に memcached サービス をインストールする ======
--- //[[http://www.y2sunlight.com|y2sunlight]] 2020-12-10//
[[wsl2:top|WSL2に戻る]]
関連記事
* [[wsl2:install|WSL2 インストール]]
* [[wsl2:command|WSL2 コマンドリファレンス]]
* [[wsl2:interop|WSL2 LinuxとのWindowsの相互運用性]]
* [[wsl2:clone|WSL2 ディストリビューションの複製]]
* [[wsl2:terminal|Windows ターミナル]]
Windows マシン上に memcached をインストールしたい場合は今でもあるのではないでしょうか。以前は memcached のWindowsバイナリを配布しているサイトもいくつかあり、筆者もそれを利用していましたが、最近はあまり見かけなくなりました。そんな事情もあり、本章では、WSL2上のLinux に memcached を設置する方法を考えてみました。ここで説明する方法は、memcached 以外のサーバに対してもそのまま応用できると思いますので、ご参考になれば幸いです。
本章では、WSL2 上の Ubuntu に memcached をインストールする方法について説明します。本章でインストールする Ubuntu は以下の通りです:
* Ubuntu 20.04.1 LTS
-----
===== 前提条件 =====
本章の前提条件としては、次の2つです。
- WSL2 に Ubuntuがインストールされている事(必須)。\\ バージョンは ''Ubuntu 20.04.1 LTS'' を想定していますが、それ以外のバージョンでも可能だと思います。まだインストールがお済でない場合は、本編の「[[wsl2:install|WSL2 インストール]]」を参照して下さい。\\ \\
- Windowsターミナルがインストールされている事(推奨)。 \\ 必ずしも必要ではありませんが、本章では、Windowsターミナルで操作する事を前提に説明します。インストールについては本編の「[[wsl2:terminal|Windows ターミナル]]」を参照して下さい。
\\
===== Ubuntuの初期設定 =====
Ubuntuがインストール直後の場合は、効率良く作業を行う為に、いくつかの準備が必要になります。既に準備が出来ている場合、または内容に必要性を感じない場合は、本項を飛ばして[[#memcachedのインストール|次項]]に移って下さい。
本章では、Windowsターミナルで操作します。
==== Windowsターミナルの設定 ====
最初に、Ubuntuのターミナルの設定を行います。
Windowsターミナルを開いて [プルダウンメニュー]から[設定]を選択して ''setting.json'' を開きます。''Ubuntu-20.04'' の設定箇所に、以下のように "startingDirectory" を追加します。
{
// 以下は Ubuntu-20.04 の例です
"guid": "{07b52e3e-de2c-5db4-bd2d-ba144ed6c273}",
"hidden": false,
"name": "Ubuntu-20.04",
"source": "Windows.Terminal.Wsl",
+ "startingDirectory": "//wsl$/Ubuntu-20.04/home/user-name"
}
* ''user-name'' の部分は Ubuntu を最初に起動した時に設定したユーザ名を入力します。
Windowsターミナルでは、シェルが開始されるディレクトリの既定値が %USERPROFILE% になっているので、これを上の設定で、Linuxユーザのホームディレクトリに変えるようにしています。
それでは、Windowsターミナルの[プルダウンメニュー]から[Ubuntu-20.04]を選択して初期設定を続けます。
\\
==== 管理者(root)のパスワード設定 ====
Microsoft Store からインストールした Ubuntu はrootユーザのパスワードが分からないので、最初に設定しておきます:
$ sudo su - # rootにログイン
# passwd # パスワード変更
# exit # 終わったら元のユーザに戻る
\\
==== /etc/sudoers ====
開発用のローカルサーバなので、rootで運用しても良いですが、''sudo'' の設定もしておきます。''viduso'' を実行して ''/etc/sudoers'' の sudoグループの箇所を書き換え、''sudo'' でパスワードが不要になるように設定します:
$ sudo viduso
# ...
# Allow members of group sudo to execute any command
- %sudo ALL=(ALL:ALL) ALL
+ %sudo ALL=(ALL) NOPASSWD:ALL
# ...
Ubuntuを最初に起動した時に設定したユーザは sudoグループに入っているようなので、上の修正をすれば十分です。id を実行して確かめてみましょう:
$ id
uid=1000(y2sunlight) gid=1000(y2sunlight) groups=1000(y2sunlight),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev)
パスワードが不要になるような設定は、特にサービスをWindows側で自動起動する場合に必要になります。
> ''注意''
> 上の''id''コマンドの結果は Microsoft Store からインストールした場合だけです。
\\
==== パッケージの更新 ====
パッケージを最新の状態に更新します:
$ sudo apt update # 最新のパッケージ情報の取得
$ sudo apt upgrade # パッケージを最新に更新する
\\
===== memcachedのインストール =====
''net-tools'' をインストールします。(iproute2をご利用の方は不要です)
$ sudo apt install net-tools
''memcached'' をインストールします。
$ sudo apt install memcached
initのスクリプトが出来ているか確認します:
$ ls -l /etc/init.d/ -l
-rwxr-xr-x 1 root root 3481 May 15 2020 /etc/init.d/memcached
> WSL2では、Windowsとの相互運用性のために SysV init が使われています。systemd ではないので注意して下さい。尚、ネットでは WSL2の init を systemd に変更するHackも存在しますが、本編では別段の理由がない限り Microsoftの思想に従います。
\\
===== memcachedの実行 =====
''service memcached status'' で現在の memcached の状態を調べます:
$ service memcached status
memcached: memcached is not running
''sudo service memcached start'' で memcached を起動します:
$ sudo service memcached start
Starting memcached: memcached.
''ps'' と ''netstat'' でプロセスをポートを確認します。memcached のリスニングポートは 11211 です。
$ ps -aux | grep [m]emcached
memcache 13177 0.0 0.0 406264 4892 ? Sl 15:25 0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -P /var/run/memcached/memcached.pid
$ netstat -an|grep 11211
tcp 0 0 127.0.0.1:11211
\\
===== 動作テスト =====
telnet で memcached と接続後、コマンドを送信して動作テストを行います。memcachedプロトコルのコマンドについての日本語の解説は以下が詳しいです。
* https://research.sakura.ad.jp/2010/03/26/kvs-memcached/
==== Ubuntuからのテスト ====
Ubuntuターミナルから ''telnet'' を起動して memcached のポート 11211 と接続します:
$ telnet localhost 11211
以下の set コマンドを送信して、memcached にデータを格納します。
set foo 0 0 3
ABC
* setコマンドの第1引数はキー、続く数字は「''<フラグ>'' ''<有効期間(秒)>'' ''<データサイズ>''」 です。
* 有効期間(秒)が0の時は基本的に自動削除されません。
実行結果
set foo 0 0 3
ABC
STORED
次に get コマンドを送信して、memcached からデータを取得します。
get foo
* getコマンドの引数はキーです。
* setコマンドで指定したキーと同じものを指定します。
実行結果
get foo
VALUE foo 0 3
ABC
END
telnet を終了するには ''Ctrl + ]'' を押してから、''close'' を実行して下さい。
\\
==== WSL2の仮想ネットワーク ====
Ubuntuに設置したmemcachedはもちろんローカル開発用です。Windows側からmemcachedにアクセスする前に、WSL2の仮想ネットワークについて説明しておきましょう。
まず、Ubuntuのネットワークを ''ifcobnfig'' で調べます:
$ ifconfig
eth0: flags=4163 mtu 1500
inet 192.168.93.54 netmask 255.255.255.240 broadcast 192.168.93.63
...
この例の場合、UbuntuのIPアドレスは、''192.168.93.54'' であることが分かります。このIPアドレスはUbuntuを再起動すると変わります。このネットワークインターフェースをWSL2仮想インターフェースと呼ぶことにします。
次に Windows の PowerShell で ''ipconfig'' を実行します。
> ipconfig
Windows IP 構成
イーサネット アダプター イーサネット:
接続固有の DNS サフィックス . . . . .:
リンクローカル IPv6 アドレス. . . . .: fe80::a058:d977:ab7:9f83%6
IPv4 アドレス . . . . . . . . . . . .: 192.168.11.18
サブネット マスク . . . . . . . . . .: 255.255.255.0
デフォルト ゲートウェイ . . . . . . .: 192.168.11.1
イーサネット アダプター vEthernet (WSL):
接続固有の DNS サフィックス . . . . .:
リンクローカル IPv6 アドレス. . . . .: fe80::2998:efde:6735:ce3b%17
IPv4 アドレス . . . . . . . . . . . .: 192.168.93.49
サブネット マスク . . . . . . . . . .: 255.255.255.240
デフォルト ゲートウェイ . . . . . . .:
この例では、Windowsはイーサネット(外部インターフェース)とvEthernet(WSL)の2つのネットワークインターフェースを持ち、vEthernet(WSL) の IPアドレスは、''192.168.93.49'' であることが分かります。このIPアドレスもWindowsを再起動すると変わります。このネットワークインターフェースをWin仮想インターフェースと呼ぶことにします。
WSL2仮想インターフェース と Win仮想インターフェースは、同じ仮想ネットワーク(''192.168.93.0/24'')に属します。WSL2側で開いている memcached のリスニングポート(''11211'')は Win側でも同じポートを ''wslhost.exe'' がリスニングするようになっています。そして、wslhost.exe が受け取ったパケットはWSL2側の同じポートに転送されます。
Windows の PowerShell で ''netstat'' を実行し、memcached のポート番号(''11211'')を調べてみましょう:
> netstat -an|Select-String "11211"
TCP 127.0.0.1:11211 0.0.0.0:0 LISTENING
確かに、Ubuntuで稼働している memcached のポートがWindows でも開いているのが分かります。
結果的に、この仕組みによって Win仮想インターフェースへの要求はWSL2仮想インターフェースに転送され、Windows側からは ''localhost'' とWSL2側のポート番号で Ubuntu のサービスにアクセス出来るようになります。memcached の場合は、Windosw側は ''localhost:11211'' でサービスを利用できます。
\\
==== Windowsからのテスト ====
Windows側から先に格納したmemcacheのデータを取得してみます。
PowerShellで ''telnet'' を起動します。''telnet'' をインストールしていない場合は、本編の「[[tools:telnet|Telnet]]」を参照するか、[[tools:teraterm|TeraTerm]] などの任意のTCPポートに接続できるアプリケーションをご用意下さい。
> telnet
ローカルエコーをONにして、memcached(''localhost:11711'')に接続します。
Microsoft Telnet クライアントへようこそ
エスケープ文字は 'CTRL+]' です
Microsoft Telnet> set localecho
ローカル エコー: オン
Microsoft Telnet> open localhost 11211
接続中: localhost...
get コマンドを送信して、memcached からデータを取得します。
get foo
* getコマンドの引数はキーです。
* setコマンドで指定したキーと同じものを指定します。
実行結果
get foo
VALUE foo 0 3
ABC
END
telnet を終了するには ''Ctrl + ]'' を押してから、''quit''コマンドを実行して下さい。
\\
===== サービスの自動起動 =====
通常のLinuxでは、ブートシーケンスの中で、カーネルにより ''プロセスID = 1'' の 初期プロセス(''SysV init'' または ''Systemd'' などが有名)が起動され、この初期プロセスによって各種デーモンが起動されます。WSL2では、''SysV init'' が採用されていますが、Windows との相互運用性のためにカスタマイズさており、ブートシーケンスの中でデーモンの起動は行われません。
本章は、開発用のmemcachedサービスを設置することが目的なので、当然のことながら、Windows起動時にmemcachedサービスも起動したいわけです。この問題を解決するために、ネットではいろいろな策が考えられていますが、本章ではWindowsのスタート時に ''wsl'' コマンドで Ubuntu側に設置したサービス起動用のスクリプトを起動する方法を提案します。
\\
==== サービス起動用のスクリプト ====
Ubuntuのbashターミナルを起動して、''/usr/local/bin'' にサービス起動用のスクリプト( ''wsl-service-start.sh'' )を設置します。
$ cd /usr/local/bin
$ sudo vi wsl-service-start.sh
スクリプトの内容は以下の通りです。''sudo vi'' で新規に作成して下さい。
{{fa>folder-open-o}} ** /usr/local/bin/wsl-service-start.sh **
#!/bin/bash
# Set services list
# services=( "servie1" "service2" "service3")
services=( "memcached")
for service in "${services[@]}"
do
if (($(ps -ef | grep -v grep | grep $service | wc -l)==0))
then
service $service start
fi
done
* services配列に起動するサービス名を設定して下さい。仕掛けはご覧の通りです。
* サービスが起動していない場合のみ service コマンドでサービスを起動します。
スクリプトが出来たら、''sudo chmod'' で実行権限を付与します。
$ sudo chmod +x wsl-service-start.sh
\\
==== スタートアップの登録 ====
Windows側でユーザのスタートアップフォルダを開きます。[ファイル名を指定して実行]から開くには、''shell:startup'' を実行します。また、PowerShell から開くには以下のように入力して下さい。
> explorer shell:startup
このフォルダの中に、以下のファイル( ''wsl-service-start.bat'' )を作成して下さい。
{{fa>folder-open-o}} ** {User Startup}\wsl-service-start.bat **
wsl -d Ubuntu-20.04 -u y2sunlight sudo wsl-service-start.sh
* ''-d'' にはディストリビューション名を指定します。
* ''-u'' にはユーザ名を指定します。このユーザは[[#etc_sudoers|sudoers]]でパスワード無しでsudo が実行できるようにしておくのが良いかもしれません。
準備が出来たら、Ubuntuを停止(''wsl --shutdown'')して、wsl-service-start.batを実行して下さい。memcachedのポート(''11211'')が開いていたら成功です:
> netstat -an|Select-String "11211"
TCP 127.0.0.1:11211 0.0.0.0:0 LISTENING
尚、ここでは、ユーザのスタートアップフォルダを利用しましたが、タスクスケジューラなどの他の適当な方法でも良いと思います。理想的には、Windowsの起動時に ''wsl -d Ubuntu-20.04'' のみを実行し、Ubuntuのブートシーケンスの中で必要なサービスを起動するのが、エレガンスだと思うのですが、手軽な良い方法が見つかりませんでした。何か妙案のある方はコメント頂ければ有難いです。
\\