tech.guitarrapc.cóm

Technical updates

Ubuntu 22.04 と WSL

Ubuntu 20.04 on WSLは非常に安定しており、また便利で好んで利用しています。 さて、Ubuntu 22.04がリリースされ、WSLにも来ました。

そこで今回、今のUbuntu 20.04 on WSLな環境をUbuntu 22.04にするにあたり対応したことをメモしておきます。

tl;dr;

  • Ubuntu 22.04をWSLで動かすならWSL2一択になりそう
  • Ubuntu 22.04 on WSL1はBSoDが頻発しneedrestartの制御が効かないためあきらめた
  • WSL2はVPN周りで困るので今後向き合っていくことになりそう

Ubuntu 22.04 での大きな変更点

needrestart パッケージの導入

needrestartパッケージの導入は、Ubuntu 20.04まではなかった変更で直面することになります。

https://gihyo.jp/admin/serial/01/Ubuntu-recipe/0718gihyo.jp

特に私はAnsibleでWSLのUbuntu環境を構成しているので、aptパッケージの実行のたびにエラーは困ります。 あと、WSLなのでホストOSの再起動もそれなりにすることもあり、結構いらない感じがあります。

ということで、適当に/etc/needrestart/conf.d/99_ansible.confなどをこしらえて、警告表示を無効にしています。

Ubuntu でアップグレードした場合の警告表示を無効化する | らくがきちょう v3 https://sig9.org/archives/4580

# use stdin to select restart service
$nrconf{ui} = 'NeedRestart::UI::stdio';
# control restart service
$nrconf{kernelhints} = '0';
$nrconf{ucodehints} = 0;
$nrconf{restart} = 'a';

これをAnsibleでのapt処理の前段で設定するとokです。

- name: "needrestart - check OS is using needrestart"
  become: yes
  stat:
    path: /usr/sbin/needrestart
  register: needrestart_exists

- name: "needrestart - place custom conf.d"
  become: yes
  copy:
    dest: /etc/needrestart/conf.d/99_ansible.conf
    content: |
      # use stdin to select restart service
      $nrconf{ui} = 'NeedRestart::UI::stdio';
      # control restart service
      $nrconf{kernelhints} = '0';
      $nrconf{ucodehints} = 0;
      $nrconf{restart} = 'a';
  when: needrestart_exists.stat.exists

再インストールにはホストWindowsの再起動が必要

これまでのWSLでのUbuntu再インストールは、アンインストール後にストアから再インストールが可能でした。 Ubuntu 22.04では、アンインストール後にWindowsを再起動するまでストアから再インストールできなくなっているようです。 試行錯誤がちょっとめんどくさくなりました。

アンインストール

アンインストール後のストアからの再インストールがダウンロードで止まる
アンインストール後のストアからのインストールが失敗する

Ubuntu 22.04 をWSL2 に構成する

大きな変更以外は調整不要です。 Ubuntu 20.04までのAnsibleでの構成は22.04でも問題なく機能するでしょう。

例えば私は次のようなコマンドで構成しています。

mkdir -p ~/github/guitarrapc && cd ~/github/guitarrapc
git clone https://github.com/guitarrapc/local-provisioner
cd ~/github/guitarrapc/local-provisioner/envs/ubuntu_wsl2

# ansible の導入
. ./prerequisites.sh
ansible-playbook -i hosts site.yml -K

リポジトリはこちらです。

github.com

docker WSL2 にインストールする場合

Docker for Windowsではなく、Ubuntu 22.04にdockerをインストールする場合、iptableを古いのを指定しないと動かないのは変わっていません。

$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
$ sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
$ sudo update-alternatives --config iptables

There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

  Selection    Path                       Priority   Status
------------------------------------------------------------
  0            /usr/sbin/iptables-nft      20        auto mode
* 1            /usr/sbin/iptables-legacy   10        manual mode
  2            /usr/sbin/iptables-nft      20        manual mode

設定してからdockerを開始するとうまく動きます。

$ sudo service docker start

Ubuntu 22.04 をWSL1 に構成する (断念)

手元で再現する問題が2点あり、いずれも解消が難しそうなので断念しました。

  1. needrestartの制御がneedrestart.confでも効かずAnsibleでの構成でaptパッケージごとにエラーが生じる
  2. Ubuntu 22.04でパッケージ構成時にBSoDが頻発する

needrestartをpurgeしてもダメなので何かやり方が間違えている気がするものの、BSoDは解消できないのでちょっと難しそうです。 BSoDは、今のところdotnet SDKの導入時に起こっています。

# ref: https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/sdk-current
# ref: https://github.com/ocha/ansible-role-dotnet-core
- name: "dotnet - make sure HTTPS is supported by apt"
  become: yes
  apt:
    name: apt-transport-https
    state: present
    update_cache: yes

- name: "dotnet - import Microsoft apt key"
  become: yes
  shell: wget https://packages.microsoft.com/config/ubuntu/{{ ansible_distribution_version }}/packages-microsoft-prod.deb -O /tmp/packages-microsoft-prod.deb
  changed_when: false

- name: "dotnet - add repo for Ubuntu"
  become: yes
  shell: dpkg -i /tmp/packages-microsoft-prod.deb
  changed_when: false

- name: "dotnet - install dotnet sdk ({{ args.version }})"
  become: yes
  package:
    name: "dotnet-sdk-{{ args.version }}"
    state: present
    update_cache: true

おまけ: WSL2 と VPN の問題

よく知られている問題なので、これをやっていきましょう。

qiita.com

Workaround for WSL2 network broken on VPN · GitHub