kavo’s diary

備忘録

ISUCON10予選問題をUbuntu18.04@WSL2(Windows 10 Home)で動かすまでのメモ、トラブルシュート集

ISUCON10予選問題をUbuntu18@WSL2(Windows 10 Home)で動かしたときのメモ。末尾にトラブルシュートもまとめた。

環境

大体は2020/09/19の最新バージョン。

  • ホストOS側(Windows)
    • Windows 10 Home 2004 19041.508
    • WSL2
    • Docker desktop 2.3.0.5 (48029)
  • ゲストOS側(Ubuntu)
    • Ubuntu 18.04.5 LTS
    • Docker-compose 1.27.3
    • Go 1.15.2

ソース

github.com

ゴール

WSL2のUbuntu上でdocker-composeでアプリを立ち上げ、ブラウザでWebアプリ画面を確認し、ベンチマーカーでスコアを出す。

手順

基本的にGitHub - isucon/isucon10-qualify: ISUCON10予選の「問題の起動方法」を中心に色々設定を挟む形になっている。

WSL2インストール

WSL2はWindows 10 バージョン2004に含まれる。 Windows 10 バージョン2004の更新配布は段階的に行われているらしく、私のPCではまだ来ていなかった。 ただ、手動インストールは可能で、少し不安はあったがやってみた(結果問題なく動作した)。 大体以下を参考にすればOK。Ubuntuは本番と同じ18.04を選ぶ。

WSL2導入|WinアップデートからWSL2を既定にするまでのスクショ - Qiita

Install Docker Desktop

Windows 10 Home で WSL 2 + Docker を使う - Qiita

docker-composeをインストール

Install Docker Compose | Docker Documentationを参考にインストール。

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

再起動しないとパスが通らなかった。PowerShellからシャットダウン(自動再起動する)。

PS> wsl -t Ubuntu-18.04

またコンソールを開く。

$ docker-compose --version
docker-compose version 1.27.3, build 4092ae5d

クローン、諸々インストール、パス設定

$ git clone https://github.com/isucon/isucon10-qualify.git
$ sudo apt install -y gcc make python3-pip
$ pip3 install -r requirements.txt

golangはaptでは入れない。aptだと1.10が入ってしまうが、使用するライブラリwaytが1.13以上を必要とするため、最新版を手動で入れる。

$ wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz
$ sudo tar -xvf go1.15.2.linux-amd64.tar.gz
$ sudo mv go /usr/local

wgetが進まない場合、後述の # ホストNWとゲストNWのMTU値が一致していないとダウンロードがタイムアウトすることがある 参照。

Goの環境変数を設定する。.profileにexportを追加する。

$ vi ~/.profile
export GOROOT=/usr/local/go
export GOPATH=~
export PATH=$GOROOT/bin:/usr/local/go/bin:$GOPATH/go/bin:$PATH
$ source ~/.profile

$ go version
go version go1.15.2 linux/amd64

ライブラリインストール。

$ go get github.com/orisano/wayt
$ wayt
wayt: subcommand is required:
Available SubCommands:
...

sudoでgo,waytが実行できるようにsudoパスを設定(makeで必要)

$ sudo visudo

Defaults secure_pathにパスを書き足す。 /home/koのところは自分の設定に合わせる。

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/home/ko/bin:/usr/local/go/bin"

動作確認

$ sudo go version
$ sudo wayt
wayt: subcommand is required:
Available SubCommands:
...

docker-composeのためにPATHに docker-credential-desktop.exeのあるディレクトリを追加し、~/.docker/config.jsonを一度削除しておく(これをしないと認識してくれないことがある)。

echo 'export PATH="$PATH:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/ProgramData/DockerDesktop/version-bin"' >> ~/.profile
tail ~/.profile
source ~/.profile

rm ~/.docker/config.json

初期データの生成

$ cd isucon10-qualify/initial-data
$ sudo make

エラーなく終わればOK。

  • Windows側でdocker desktopがrunningになっていること。タスクトレイアイコンから状態が分かる。
  • Ubuntu側で3306ポートを使っていないこと。既存のmysqlがあったりする場合停止する。
  • ERROR: error pulling image configuration: unexpected EOFが出て止まった場合、とりあえずもう何回か試すとよい。

問題サーバーを立ち上げ

$ cd isucon10-qualify/webapp/
make isuumo/go
(そのままログtail状態へ)

アプリをブラウザで確認

Microsoft Storeから起動してもう1つ窓を開く。

f:id:kavohtn:20200920050014p:plain

IPを確認する。

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1454
inet xxx.xxx.xxx.xxx netmask 255.255.240.0 broadcast 172.yyy.yyy.yyy
...

PowerShellで先程確認したxxx.xxx.xxx.xxxへポートフォワーディング を行う。Connection resetと出ることがあるがその後も転送は続いている。この手順は ISUCON10 予選マニュアル · GitHubによる。

PS C:\WINDOWS\system32> ssh localhost -L localhost:8080:xxx.xxx.xxx.xxx:80 -N
kex_exchange_identification: read: Connection reset
PS C:\WINDOWS\system32>

ブラウザで http://localhost:8080/ にアクセスし、ISUUMOの画面が見えればOK。 f:id:kavohtn:20200920045956p:plain

ベンチマークを実行

ビルドして実行し、スコアが出れば完了。

$ cd ~/isucon10-qualify/bench
$ sudo make
$ ./bench
...
2020/09/20 02:32:04 bench.go:110: 最終的な負荷レベル: 8
{"pass":true,"score":1310,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":40}],"reason":"OK","language":"go"}

トラブルシュート

docker desktopが起動していないとdocker-composeがFileNotFoundErrorで終了する

docker desktopを起動してもう一度やってみる。docker desktopはタスクトレイアイコンから状態が分かる。

$ sudo make
...
docker-compose -f ../webapp/docker-compose/go.yaml down -v
Traceback (most recent call last):
  File "urllib3/connectionpool.py", line 677, in urlopen
  File "urllib3/connectionpool.py", line 392, in _make_request
  File "http/client.py", line 1252, in request
  File "http/client.py", line 1298, in _send_request
  File "http/client.py", line 1247, in endheaders
  File "http/client.py", line 1026, in _send_output
  File "http/client.py", line 966, in send
  File "docker/transport/unixconn.py", line 43, in connect
FileNotFoundError: [Errno 2] No such file or directory
...

参考: During startup check that docker is running · Issue #774 · jupyterhub/repo2docker · GitHub

docker-composeがdocker.credentials.errors.InitializationErrorで終了する

PATHに docker-credential-desktop.exeのあるディレクトリを追加し、また、それでも上手く行かない場合は~/.docker/config.jsonを一度削除する。

$ sudo make
...
Traceback (most recent call last):
  File "bin/docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 67, in main
  File "compose/cli/main.py", line 126, in perform_command
  File "compose/cli/main.py", line 1070, in up
  File "compose/cli/main.py", line 1066, in up
  File "compose/project.py", line 615, in up
  File "compose/service.py", line 356, in ensure_image_exists
  File "compose/service.py", line 1267, in pull
  File "compose/progress_stream.py", line 99, in get_digest_from_pull
  File "compose/service.py", line 1234, in _do_pull
  File "docker/api/image.py", line 396, in pull
  File "docker/auth.py", line 48, in get_config_header
  File "docker/auth.py", line 324, in resolve_authconfig
  File "docker/auth.py", line 235, in resolve_authconfig
  File "docker/auth.py", line 262, in _resolve_authconfig_credstore
  File "docker/auth.py", line 287, in _get_store_instance
  File "docker/credentials/store.py", line 25, in __init__
docker.credentials.errors.InitializationError: docker-credential-desktop.exe not installed or not available in PATH
[7239] Failed to execute script docker-compose
Makefile:22: recipe for target 'verification_data' failed
make: *** [verification_data] Error 255

参考: WSL2上のdocker-composeで認証エラー - roy-n-roy メモ `docker-compose up` fails in WSL 2 environment · Issue #7495 · docker/compose · GitHub

ホストNWとゲストNWのMTU値が一致していないとダウンロードがタイムアウトすることがある

ホスト側でPowerShellでMTUを確認。この場合1454。

PS C:\WINDOWS\system32> netsh interface ipv4 show subinterface

   MTU  MediaSenseState  受信バイト   送信バイト  インターフェイス
------  ---------------  -----------  ----------  -----------------
...
  1454                1  159585932    7359736  ブロードバンド接続
...

ゲスト側でMTUを確認。元がいくつだったか取りそこねた。ゲスト側も1454に合わせて、何かwgetしてみる。ダウンロードが成功すればOK.

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1xxx
...

$ sudo ip link set eth0 mtu 1454

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1454
...

$ wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz

参考: WSL2 fails to make HTTPS connection if Windows is using VPN · Issue #4698 · microsoft/WSL · GitHub

waytのコマンドが通らない

バイナリが存在するか、PATHにそのフォルダが入っているか、.profileに書いたパスは正確か、.profileを読み込んだか、sudo実行時はsudoにPATH等が継承されているかを確認する。

$ find / -name wayt 2>/dev/null
/home/ko/src/github.com/orisano/wayt
/home/ko/go/src/github.com/orisano/wayt
/home/ko/bin/wayt

$ env|grep GO

$ cat ~/.profile

$ source ~/.profile

$ sudo visudo

$ wayt

$ sudo wayt

go get github.com/orisano/waytが上手く行かない

-u -vをつけてログを出してみる。TLS handshake timeoutしてるようなら上記のMTUのトラブルシュートを試す。

$ go get -u -v  github.com/orisano/wayt

...
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc": https fetch: Get "https://google.golang.org/grpc?go-get=1": net/http: TLS handshake timeout
...

../../go/src/github.com/orisano/wayt/http.go:45:14: undefined: http.NewRequestWithContextが出てるようなら使っているgoのバージョンが古いので上げる。