LoginSignup
0
0

WSL2のUbuntuでDocker compose upとport forwarding設定を同期させたい

Last updated at Posted at 2023-11-12

目的

Windows Server 2022のWSL2でUbuntuを起動し、外部PCからsshでログインしdocker containerのコントロールを行う。

状況

WSL2は思っていた以上に癖があるが、ネット上の情報をもとにやりたいことはできている。
ただし、WSL2側の設定でPort Forwardingを設定する必要があり、Ubuntuでportのbindを一度手放すと再度bindできない(エラーする)。なので、docker compose downして、再度up -dが通常のUbuntu環境のようにはできない。
これは不便。なので、これを解決する。

*Docker自体のインストールでもいろいろあったがここでは触れない。
*取り急ぎ解決はしたんだが、本当にこんな面倒なことしなければならないんだろうか?
*Docker for windowsは利用しない。

環境

  • Windows 2022 Server (21H2 Build 20348.2031)
  • Ubuntu 22.04.1 LTS
  • Docker 24.0.5

前提

方針

できるだけWindowsにはログインすることなしに対応したい。
そのため、Ubuntuのスクリプトで対応する。

docker compose起動をラップする

docker compose upする前に、port forwarding設定を一度削除し、container起動後再設定する。

dc_up.sh
#!/bin/bash

export PATH="$PATH":/mnt/c/Windows/System32/

# WSL自身のIP addressは起動ごとに変わる可能性があるので取得する
IP=$(ip address show eth0 | awk '/inet / {print $2}' | awk -F / '{print $1}')
#
# ここに公開用ポートを列挙します
# 例: LISTENPORTS=(8080 8081)
# 例のように手動指定してもよいが、面倒なのでdocker-compose.ymlファイルのport:指定を自動で読み取る
# ports:の次の行を取得->最初の数字項目を取得->スペースで連結
LISTENPORTS=(`grep 'ports:' -A 2 ./docker-compose.yml | awk 'match($0, /([0-9]+)/,a){print a[1]}' | paste -s -d ' '`)

#-------------------------------------------------------------------------------------
# delete port forwarding
# port forwarding設定を削除しておかないとdocker composeで起動時に失敗します。謎仕様
echo '================================'
echo 'Delete port forwroding'
for port in "${LISTENPORTS[@]}"
do
	netsh.exe interface portproxy delete v4tov4 listenport=$port
done
netsh.exe interface portproxy show all

#-------------------------------------------------------------------------------------
# Run docker container
echo '================================'
echo 'Start Docker Containers'
cd /home/username/docker_dir/
docker compose up -d

#-------------------------------------------------------------------------------------
# re-add port forwarding
echo '================================'
echo 'Re-add port forwroding'
for port in "${LISTENPORTS[@]}"
do
	netsh.exe interface portproxy add    v4tov4 listenport=$port connectaddress=$IP
done
netsh.exe interface portproxy show all

#-------------------------------------------------------------------------------------
# Check docker container
echo '================================'
echo 'Check Docker Containers'
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}\t{{.Image}}"

停止時(docker compose down)にport forwardingを止めたければ似た感じでどうぞ。

sshd

sshd自体はUbuntu起動時にsystemdで自動起動する設定にしてあるが、Ubuntu自体(WSL2)の再起動時には同じ問題がある。

こちらは、systemdのスクリプトをフックする。
ExecStartPre行の変更と、ExecStartPost行の追加。他はデフォルトのまま。
実行スクリプトは /usr/local/bin/へ置いた。

/etc/systemd/system/sshd.service
...

[Service]
EnvironmentFile=-/etc/default/ssh
#ExecStartPre=/usr/sbin/sshd -t
ExecStartPre=/usr/local/bin/sshd_ExecStartPre.sh
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecStartPost=/usr/local/bin/sshd_ExecStartPost.sh
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

...
sshd_ExecStartPre.sh
#!/bin/bash
export PATH=$PATH:/mnt/c/Windows/System32/

#-------------------------------------------------------------------------------------
# delete port forwarding
PORT=22
netsh.exe interface portproxy delete v4tov4 listenport=$PORT
netsh.exe interface portproxy show all

# Original 
/usr/sbin/sshd -t
sshd_ExecStartPost.sh
#!/bin/bash
export PATH=$PATH:/mnt/c/Windows/System32/

# WSL自身のIP addressは起動ごとに変わる可能性があるので取得する
IP=$(ip address show eth0 | awk '/inet / {print $2}' | awk -F / '{print $1}')

#-------------------------------------------------------------------------------------
# re-add port forwarding
PORT=22
echo '================================'
echo 'Re-add port forwroding'
netsh.exe interface portproxy add    v4tov4 listenport=$PORT connectaddress=$IP
netsh.exe interface portproxy show all

ちなみに動作確認はsystemdのログを確認する。

sudo journalctl -u ssh --since="yesterday"

おわり。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0