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 まではなかった変更で直面することになります。

gihyo.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