Windows11のWSL2へPodman(podman-machine-default)を導入したものの、podman pullでno such hostのエラーが出てしまう
当サイトではアフィリエイト広告を利用しています
Windows11のWSL2において、Podman(Distroはpodman-default-machine)を導入したのですが、podman pullを行った際にno such hostのエラーが出てしまいました。
原因としては複数ネットワークを繋ぎ変える際のネームサーバーの設定問題でした。
導入手順と解決手順を合わせて記録しておきます。
環境
- OS: Windows11
- Distro on WSL2: podman-machine-default
- Podman: 4.5.1
PodmanのWSL2へのインストール手順
WSL2を有効にした後、Winget経由でPodmanのインストールを行います。
基本的には公式の手順に従うのですが、それだけだと不足する内容があったので私の行った手順をまとめておきます。
WSL2の有効化
設定→アプリ→オプション機能→Windowsのその他の機能→「Linux用Windowsサブシステム」と「仮想マシンプラットフォームにチェック」を行い、その後再起動します。
管理者権限のPowerでwsl --install
を行うとUbuntuのDistroも同時にインストールされてしまうので、Distro不要なら上記手順を使うと良いかと思います。
WingetでPodmanのインストール
Powerを管理者権限で開いてwingetを実行します。
# 要管理者権限
$ winget install -e --id RedHat.Podman
WSL2へPodman用Distroインストール
WSL2へPodman実行用のDistroであるpodman-machine-defaultをインストールしようとしましたが、カーネルコンポーネントが不足すると表示されました。
$ podman machine init
Downloading VM image: fedora-podman-amd64-v37.0.50.tar.xz: done
Extracting compressed file
Importing operating system into WSL (this may take a few minutes on a new WSL install)...
WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
Error: the WSL import of guest OS failed: exit status 0xffffffff
MicroSoft公式より、カーネル更新プログラム パッケージをダウンロードしてインストールします(要管理者権限)。
再度podman machine init
を実行し、無事にインストールできました。
$ podman machine init
Extracting compressed file
Importing operating system into WSL (this may take a few minutes on a new WSL install)...
Configuring system...
Generating public/private ed25519 key pair.
Your identification has been saved in podman-machine-default
Your public key has been saved in podman-machine-default.pub
The key fingerprint is:
The key's randomart image is:
Machine init complete
To start your machine run:
podman machine start
導入されたdistroを確認してみます。
# Distro確認
$ wsl --list
Linux 用 Windows サブシステム ディストリビューション:
podman-machine-default (既定)
この時点ですでにVMが起動していましたが、再度起動してみて起動時の情報を確認してみます。
$ podman machine stop
$ podman machine start
Starting machine "podman-machine-default"
This machine is currently configured in rootless mode. If your containers
require root permissions (e.g. ports < 1024), or if you run into compatibility
issues with non-podman clients, you can switch using the following command:
podman machine set --rootful
API forwarding listening on: npipe:////./pipe/docker_engine
Docker API clients default to this address. You do not need to set DOCKER_HOST.
Machine "podman-machine-default" started successfully
これでPodman自体の導入はできました。
Podmanの動作確認
試しにhttpサーバーを起動してみます。こちらは無事にHTTPサーバーへのアクセスが出来る事が確認できました。
# コンテナを起動
$ podman run --rm -d -p 8080:80 --name httpd docker.io/library/httpd
# localhost:8080でHTTPサーバーの動作確認できた。
# コンテナを停止
$ podman stop httpd
問題発生
Podmanをインストールしたネットワーク環境と別のネットワーク環境に接続した際に、podman pull
を行うと次のようなエラーが出てしまいました。
$ podman pull busybox
Resolved "busybox" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/busybox:latest...
Error: copying system image from manifest list: parsing image configuration: Get "https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/52/5242710cbd55829f6c44b34ff249913bb7cee748889e7e6925285a29f126aa78/data?verify=1689320530-6VflZBDzdhIUa2Zuud23yde7Ayc%3D": dial tcp: lookup production.cloudflare.docker.com: no such host
どうも名前解決が正常に行えないように見えます。色々試して見た結果、解決することが出来た手順を以下にまとめます。
resolv.confの確認
WSL2上のpodman-machine-default
にアクセスするにはpodman machine ssh
とすればログインできます。
/etc/resolv.conf
を確認すると以下のようになっていました。
$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver xxx.xxx.xxx.xxx
このnameserverのIPアドレスがどのネットワーク環境に接続しても変わっておらず、Podman導入時のネットワーク環境でしか正常なネームサーバーとなっていないようでした。
nameserverの値が変わらないのであればGoogle Public DNSなどを記述することでどのネットワーク環境でも名前解決が行えそうです。
ただ、この値を書き換えただけではmachineの再起動時に設定が元に戻ってしまうので、これを永続化する必要があります。
WSLの設定でresolv.confの自動生成を停止する
WSL2上のDistroは/etc/wsl.conf
にWSLの設定が記載されています。ここでresolv.conf
の自動生成を無効にします。
$ cat /etc/wsl.conf
[user]
default=user
$ sudo vi /etc/wsl.conf
[user]
default=user
[network]
generateResolvConf = false
resolv.confの書き換え
次にresolv.confを書き換えます。このファイルはシンボリックリンクなので解除して改めて記述します。
なおunlinkコマンドは実態はrmであるので、リンク元を削除しないように注意です。
$ ls /etc/resolv.conf -al
lrwxrwxrwx 1 root root 39 Jul 18 09:25 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
$ sudo unlink /etc/resolv.conf
resolv.confを以下のように設定します。8.8.8.8はGoogle Public DNSで、8.8.4.4はその代替DNSとなっています。
$ sudo vi /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
ただ、この設定を行っただけではDistroの再起動時に今度はDistro側にresolv.confが上書きされてしまいますので、上書き不可とする設定を行います。
chattrで変更不可属性を付与してやるとよさそうでした。podman-machine-defaultはchattrが入ってないので合わせてインストールしておきます。
$ sudo dnf install e2fsprogs
$ lsattr /etc/resolv.conf
--------------e------- /etc/resolv.conf
$ sudo chattr +i /etc/resolv.conf
$ lsattr /etc/resolv.conf
----i---------e------- /etc/resolv.conf
これでpodman machineを再起動してもresolv.confが上書きされなくなりました。
chattrはext2/ext3/ext4ファイルシステムで利用できる拡張属性の変更コマンドですが、NTFSのWindowwsで動くWSL2でも模擬できているようです。
手順まとめ
- WSL側で
resolv.conf
の自動生成を止める - Podman-mahine-defaultで
/etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
のシンボリックリンクを解除する - 手動で
/etc/resolv.conf
をGooglePublicDNS宛に記述する e2fsprogs
をインストールし、resolv.conf
に変更不可属性を付与する
$ sudo vi /etc/wsl.conf
[user]
default=user
[network]
generateResolvConf = false
$ sudo unlink /etc/resolv.conf
$ sudo vi /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ sudo dnf install e2fsprogs
$ sudo chattr +i /etc/resolv.conf
設定変更後
上記のように名前解決の設定を変更した後、無事に異なるネットワーク環境でpodman pull
で名前解決が出来ることが確認できました。
WSL2では名前解決系の問題が出ることがたまにあるようで、Podman以外でも必要になる設定かもしれませんので忘れないようにしておきたいところです。