今更ながら WSL2 の Alpine で Docker 環境構築
Windows 11 Pro (21H2) で作業した備忘録になります.所々おかしなところがあるかもしれません.
WSL2 の環境構築
1. WSL2 のインストール
試していないのですが,wsl --install
で環境構築ができるようですが,個人的にイメージの保存場所が好ましくないので,Manual installation steps for older versions of WSL | Microsoft Docs の手順で行います.
- 「Win+x」 のショートカットキーで表示されるメニューから設定をクリックします.
- 「アプリ」→「オプション機能」→「Windows のその他の機能」から
Windows の機能
を開きます. - 「Linux 用 Windows サブシステム」,「仮想マシン プラットフォーム」にチェックを入れて, OK をクリックします.再起動を促されるので指示に従います.
-
管理者権限 で
PowerShell
を開き,wsl --update
でカーネルをインストールします. -
wsl --status
で状態を確認します.既定のバージョンが 2 になっていないときは,wsl --set-default-version 2
で変更します.
既定の配布: Ubuntu
既定のバージョン: 2
Linux 用 Windows サブシステムの最終更新日: 2022/03/28
WSL の自動更新が有効になっています。
カーネル バージョン: 5.10.102.1
2. Alpine Linux のインストール
-
downloads | Alpine Linux から alpine-minirootfs-3.16.0-x86_64.tar.gz をダウンロードして,
D:\wsl\distors
に保存する. -
'Windows Terminal' を起動して.
PowerShell
を立ち上げます.
プロンプト(PS D:\wsl\distors>
)は省略しています.
cd D:\wsl\distors
wsl --import Alpine D:\wsl\Alpine .\alpine-minirootfs-3.16.0-x86_64.tar.gz
wsl -l -v # Alpine が表示
wsl -d Alpine # Alpine の実行
exit # exit で シェルを終了して,Alpine 環境から抜ける
wsl -t Alpine # Alpine を終了
- Windows Terminal を再起動すると,メニューに Alpine が追加されるので,そこから Alpine を起動する.
プロキシ環境
apk は --no-cache
を付けて,容量を削減します.
echo $SHELL # シェルの確認 (ash が使用されています)
# システムの更新
apk update
apk upgrade --no-cache
# 必要そうなパッケージのインストール
apk add --no-cache tzdata sudo curl git
apk info # インストールされたパッケージを確認
# タイムゾーンの設定
install -Dm 644 /usr/share/zoneinfo/Asia/Tokyo /etc/zoneinfo/Asia/Tokyo
export TZ='Asia/Tokyo'
echo "export TZ='$TZ'" >> /etc/profile.d/timezone.sh
apk del tzdata
# sudo の設定
echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
# 作業ユーザ=の追加,bash を使用
apk add --no-cache bash bash-completion
adduser ignorant -s /bin/bash # ignorant はユーザ名,適宜変更
adduser ignorant wheel # ignorant はユーザ名,適宜変更
# docker 関連のインストール
apk add --no-cache docker openrc
addgroup ignorant docker # ignorant はユーザ名,適宜変更
# wsl.conf の設定
cat <<EOF > /etc/wsl.conf
[user]
default=ignorant
[interop]
appendWindowsPath=false
[boot]
command = "/usr/bin/env -i /usr/bin/unshare --pid --mount-proc --fork --propagation private -- sh -c 'exec /sbin/init'"
EOF
# シェルの終了
exit
PowerShell
から wsl -t Alpine
と入力して,Alpine
を終了します.
Windows Terminal から Alpine
を起動して,作成したユーザーになっているのを確認します.
3. OpenRC,Docker の設定
WSL2 init: emerging OpenRC :: ~/wsl.dev — Get your Linux On を参考にしています.wsl.conf
の [boot] の設定もここからです.
- Docker の動作確認
# root ユーザになる
sudo -i # (sudo su -)
# docker の起動
rc-service docker start
rc-status
# runlevel default に登録
rc-update add docker default
rc-update show default
# 不要な仮想コンソールを減らす
vi /etc/inittab # tty3 から tty6 をコメントアウト
# root から抜ける
exit
# シェルの終了
exit
PowerShell
から wsl -t Alpine
と入力して,Alpine
を終了します.
Windows Terminal から Alpine
を起動します.
このままでも,docker container run --rm hello-world
は動作しましたが,/sbin/init
を PID 1
で起動します.
上記サイトのスクリプトだと正常に動作しなかったので,少し変更しています(Alpine
なので).
sudo -i # root ユーザになる
echo '%wheel ALL=(ALL) NOPASSWD: /usr/bin/nsenter' >> /etc/sudoers.d/wheel
vi /etc/profile.d/wsl-init.sh
#!/bin/bash
# Get PID of /sbin/init
sleep 1
pid="$(ps -o pid,args | awk '$2 ~ /\/sbin\/init/ {print $1}')"
# Run WSL service script
if [ "$pid" -ne 1 ]; then
# Export ENV variables
if [ "$USER" != "root" ]; then
[ -f "$HOME/.openrc.env" ] && rm "$HOME/.openrc.env"
export > "$HOME/.openrc.env"
fi
echo "Entering /sbin/init PID: $pid"
exec sudo /usr/bin/nsenter -p -m -t "${pid}" -- su - "$USER"
fi
# Import ENV variables
if [ -f "$HOME/.openrc.env" ]; then
set -a
source "$HOME/.openrc.env"
set +a
rm "$HOME/.openrc.env"
fi
PowerShell
から wsl -t Alpine
と入力して,Alpine
を終了します.
Windows Terminal から Alpine
を起動して,Docker の動作を確認します.
# /sbin/init の PID が 1 になっているのを確認
ps -ef
# docker のサービスが動作が動作しているのを確認
rc-status
# docker の動作確認
docker info
docker container run --rm hello-world
docker image ls
docker image rm hello-world:latest
ただし,docker info
に下記の WARNING が表示されましたが,検索すれば問題ないらしいです.
WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
気になる方は下記のオプションを追加して,カーネルを再構築します.
-*- Enable the block layer --->
[*] Block layer bio throttling support
PowerShell
から wsl -t Alpine
と入力して,Alpine
を終了します.
現在の状態をすぐに復元できるように保存します.
PowerShell
上で作業します.
cd D:\wsl\sources
wsl --export Alpine Alpine_20220623.tar
プロキシ環境
4. Windows Terminal のアイコンを変更
ペンギンさんばかりだと,視認し辛いので,GitHub - TheFern2/windows-terminal-icons: A sane option for icons for windows terminal profile icons から alpine.png
をダウンロードして設定しています.
保存場所はどこでも良いのですが,D:\wsl\Alpine
と同じ場所にします.
5. カーネルの再構築
WARNING が気になるので,カーネルを再構築します.使い捨て環境を Ubuntu 22.04
で構築し,そこで作業します.
- Downloading distributions から Ubuntu 22.04 LTS をダウンロードします.
-
Ubuntu2204-220620.AppxBundle
をUbuntu2204-220620.zip
に変更して展開します(私は,面倒くさいので 7zip でそのまま解凍します ).同様にUbuntu_2204.0.10.0_x64.appx
も解凍します. - 解凍した
Ubuntu_2204.0.10.0_x64
にinstall.tar.gz
があるのでubuntu2204-ms.tar.gz
に変更して,D:\wsl\distors
にコピーします. -
wsl --import Jammy D:\wsl\Jammy .\ubuntu2204-ms.tar.gz
でインポートします. - Windows Terminal から
Jammy
を起動します.
# カレントディレクトリを $HOME に移動
cd
# システムのアップデート
apt update; apt upgrade
apt autoremove
# カーネルのビルドの必要なパッケージの取得
apt install build-essential flex bison libssl-dev libelf-dev libncurses5-dev dwarves
# dwarves: (BTF: .tmp_vmlinux.btf: pahole (pahole) is not available)の対処
# カーネルソースの取得
mkdir -p ~/git/src && cd $_
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
# カーネルの構築
cd WSL2-Linux-Kernel
git tag -l | grep 5.10
uname-r
git switch -d linux-msft-wsl-5.10.102.1 # カーネルのバージョンを合わせる?
export KCONFIG_CONFIG=Microsoft/config-wsl
make menuconfig
make -j$(nproc)
cp ./arch/x86_64/boot/bzImage /mnt/d/wsl/
make menuconfig
で下記のオプションを有効にします.
-*- Enable the block layer --->
[*] Block layer bio throttling support
D:\wsl
に構築したカーネル bzImage
をコピーして, %USERPROFILE%\.wslconfig
でカーネルを指定します.
%USERPROFILE%
の場所は,おそらく C:\Users\ユーザ名
ですが,エクスプローラーのアドレスバーに %USERPROFILE%
と入力するとその場所が開きます.
.wslconfig
を下記の内容で作成します.カーネルの場所は適宜変更します.また,\
は \\
のように重ねます.
[wsl2]
kernel=D:\\wsl\\bzImage
PowerShell
から wsl -t shutdown
ですべての仮想マシンを終了します.
Windows Terminal から Alpine
を起動して,docker info
で WARNING が出ないことを確認します.
# カーネルが更新されているか確認
uname -a -v
# **WARNING** が出ないことを確認
docker info
カーネルをビルドした Jammy
は必要ないので,PowerShell
から wsl --unregister Jammy
で削除します.ただし,フォルダまで削除してくれないので,D:\wsl\Jammy
を削除します.
6. さいごに
現在の ext4.vhdx
は,358 MB でした.
docker container run --rm hello-world
のチェックしかしていないので不具合があるかもしれません. 試して見る方は,ご了承願います.
補足
(2022-06-26) 追記
Tips by Linux distribution にあるように,libgcc
,libstdc++
を入れないと VS Code の Remote - Containers でエラーがでます.
sudo apk add --no-cache libgcc libstdc++
- プロキシ環境の方は
sudo -E
のように sudo に -E を付けます.
sudo -E apk add --no-cache libgcc libstdc++
Discussion
久々に、Alpine を更新したら Docker デーモンが起動しませんでした。
WSL2のAlpine LinuxでDockerを使う - 進捗ダメです によると、2023年7月頃みたいです。
Configure Networking - Alpine Linux にあるように、
/etc/network/interfaces
にを追加して、Alpine を停止(
wsl -t Alpine
) して、再度Alpine
を立ち上げると無事に、Docker デーモンが起動してくれました。