Hyper-VでPodman machineを実行する

Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。

本記事はRed Hat Advent Calendar 2023の2日目の記事です。

早いものでもう12月ですが、個人的には今年はPodmanづくしの年でした。 この記事を書いている時点で実はまだPodman祭りの最中で、これからPodmanウェビナーとPodmanハンズオン2回があります。 その合間に息抜きがてらアドベントカレンダーへの参加で記事を書きました。 もちろんPodmanネタですが、今回はWindowsユーザー待望のHyper-Vを使ってPodman machineを実行する方法を解説します。

追記(2024/4/16):containers.confを使った設定方法を追記しました

-目次-


Windows上のPodman machine

WindowsのPodman machineのアーキテクチャー

Linux以外のOS(WindowsとmacOS)上でPodmanを実行するには仮想マシンを使う必要があります。 PodmanではこれをPodman machineと言う機能で実現しています。 LinuxでもPodman machineを使用できますが、ほとんどの場合はLinuxの実行環境を持たないWindowsとmacOS向けです。 Windows版PodmanではこれまではWSL2のみがPodman machineの実行環境として提供されていました。Podman v4.8.0からはHyper-Vが新しい実行環境として追加されました。

Windows版Podman machineのアーキテクチャーを比較すると、WSL2とHyper-VではPodman machineの実行元ホストOSが異なります。 WSL2ではWindowsの機能として組み込まれたWSL2-Linux-Kernelを用いてWindows上で仮想マシンなどの管理オーバーヘッド無しにLinuxのコマンドを透過的に実行できます。 対して、Podman machineのデフォルト実行OSであるFedora CoreOSは完全に独立したOSとしての実行が前提で、それはIgnitionを用いた初期構成を行う必要があるためです。

そのためWSL2版Podman machineはFedora CoreOSではなく通常のFedoraをホストOSとして採用していました。 これにはデメリットがあり、OSが通常版のFedoraのため長期的な運用をする場合には一般的な仮想マシン運用と同様にOSのアップデートなどを手動で行う必要があります。 また、WSL2版のPodman machineを構成方法も既存のLinuxの知見で十分実現ができたとしても*1、Fedora CoreOSのIgnitionを使ったコードによる構成管理の方がスマートです。

Hyper-V版の登場によりようやく本来の形式のPodman machineがWindows上で実行できるようになりました。次項ではHyper-Vを使ったPodman machineの実行方法を解説します。

Hyper-Vを使ったPodman machineの実行

まず、前提条件としてHyper-Vを実行できるWindows環境が必要です。Windows Homeエディションは対象外となります。Podmanは最新のv4.8.0以上をご利用ください。

作業手順は下記の通りです。

  • Podman CLIのインストール
  • Hyper-V機能の有効化
  • Podman machineの作成と実行  

    Podmanのインストール

Windows版PodmanのインストーラーはPodmanの公式サイトまたはPodmanのGitHubリポジトリのリリースページから入手してください。

Podman CLIを公式サイトからダウンロードする
Podman CLIを公式サイトからダウンロードする

Podman CLIのインストーラーを実行してウィザードを進めます。

Podman CLIのインストール
Podman CLIのインストール

Podman CLIのインストール進捗
Podman CLIのインストール進捗

ウィザードが完了すると再起動を求められるのでOSを再起動します。

インストール完了後に再起動を実行する
インストール完了後に再起動を実行する

OS起動後、自動的にPodman CLIインストーラーの画面が立ち上がるので画面を閉じてインストールは完了です。

インストールの完了
インストールの完了

Hyper-V機能の有効化

「スタートメニュー>コントロールパネル>Windowsの機能の有効化または無効化」 を開きます 「Hyper-V」にチェックを入れOKを押します。

Hyper-V機能の有効化
Hyper-V機能の有効化

有効化が完了したらOSを再起動します。

機能の有効化後、再起動を実行する
機能の有効化後、再起動を実行する

Podman machineの作成と実行

ここからはWindowsターミナルで作業を行います(コマンドプロンプトでも構いません)。 Windowsターミナルを実行するときは必ず管理者モードで起動してください。

podman infoコマンドを実行するとproviderがデフォルトでwslになっていることが確認できます。また、Podman CLIのインストール直後にPodmanコマンドを実行するとまだPodman machine(実行エンジン)が起動していないため接続エラーが表示されます。

PS C:\Users\user> podman info
OS: windows/amd64
provider: wsl
version: 4.8.0

Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM
Error: unable to connect to Podman socket: Get "http://d/v4.8.0/libpod/_ping": dial unix /run/podman/podman.sock: connect: A socket operation encountered a dead network.

次にHyper-V版のPodman machineをインストールするための事前設定を行います。 CONTAINERS_MACHINE_PROVIDER環境変数にhypervをセットします。再度podman infoコマンドを実行するとproviderhypervに変更されたことが確認できます。この状態でPodman machineの作成を実行します。

PS C:\Users\user> $env:CONTAINERS_MACHINE_PROVIDER="hyperv"
PS C:\Users\user> podman info
OS: windows/amd64
provider: hyperv
version: 4.8.0
...

(参考)コマンドプロンプトの場合の環境変数のセット方法は下記の通りです。

>set CONTAINERS_MACHINE_PROVIDER=hyperv

環境変数を使用せず、設定を固定化したい場合はcontainers.confに記載します。 containers.confの作成場所は%APPDATA%\containers\containers.confになります。 下記の内容を追記してください。

[machine]
provider="hyperv"

Podman machineの作成はpodman machine initコマンドを実行します。 この処理の中で、Hyper-V向けのFedora CoreOSイメージのダウンロード、展開、初期設定が自動で行われます。初回実行時はインターネットからイメージをダウンロードするので環境によっては時間がかかります。2回目以降はローカルにキャッシュされたイメージがあれば再利用します。

PS C:\Users\user> podman machine init                               
Machine init complete
To start your machine run:

        podman machine start

PS C:\Users\user>

Podman machineの作成が完了したらPodman machineの起動を行います。 podman machine startコマンドを実行します。

PS C:\Users\user> podman machine start
Starting machine "podman-machine-default"
Machine "podman-machine-default" started successfully

Podmanの初回起動時にWindowsセキュリティのポップアップが表示されるのでこれを許可します。

Windowsセキュリティのポップアップを許可する
Windowsセキュリティのポップアップを許可する

ここからはPodmanコマンドが自由に実行できるようになります。 podman versionコマンドの実行結果はこちら。

PS C:\Users\user> podman version
Client:       Podman Engine
Version:      4.8.0
API Version:  4.8.0
Go Version:   go1.20.5
Git Commit:   c4dfcf14874479e34b3f312f089fc5840e306258
Built:        Tue Nov 28 03:37:20 2023
OS/Arch:      windows/amd64

Server:       Podman Engine
Version:      4.7.2
API Version:  4.7.2
Go Version:   go1.21.1
Built:        Tue Oct 31 23:32:01 2023
OS/Arch:      linux/amd64

Podman hello worldの実行

PS C:\Users\user> podman run --rm quay.io/podman/hello
Trying to pull quay.io/podman/hello:latest...
Getting image source signatures
Copying blob sha256:d08b40be68780d583e8c127f10228743e3e1beb520f987c0e32f4ef0c0ce8020
Copying config sha256:e2b3db5d4fdf670b56dd7138d53b5974f2893a965f7d37486fbb9fcbf5e91d9d
Writing manifest to image destination
!... Hello Podman World ...!

         .--"--.
       / -     - \
      / (O)   (O) \
   ~~~| -=(,Y,)=- |
    .---. /`  \   |~~
 ~/  o  o \~~~~.----. ~~
  | =(X)= |~  / (O (O) \
   ~~~~~~~  ~| =(Y_)=-  |
  ~~~~    ~~~|   U      |~~

Project:   https://github.com/containers/podman
Website:   https://podman.io
Documents: https://docs.podman.io
Twitter:   @Podman_io

Podman machineの作成後はHyper-Vマネージャー上で仮想マシンの状態が確認できます。 「Windowsツール > Hyer-Vマネージャー」を実行します。

Hyper-Vマネージャーの実行
Hyper-Vマネージャーの実行

Hyper-V版Podman machineのポートフォワード

コンテナでポート公開を行うとPodman machineが自動でポートフォワードの設定を行いコンテナと通信ができます。この時、内部ではgvproxyコマンドが自動的にポートフォワードを行います。

PS C:\Users\user> podman run -d --name nginx -p 8080:80 docker.io/library/nginx
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob 
...
b4c66afa83782df8ea85bcd8631fc7e81e37721dfba97ff1a6e7382d9476885a
PS C:\Users\user>
PS C:\Users\user> curl http://localhost:8080


StatusCode        : 200
StatusDescription : OK
Content           : <!DOCTYPE html>
                    <html>
                    <head>
                    <title>Welcome to nginx!</title>
...

ポート公開の初回実行時はgvproxyに対してWindowsセキュリティのポップアップが表示されるのでこれを許可します。

&#x60;gvproxy&#x60;のWindowsセキュリティのポップアップを許可する
`gvproxy`のWindowsセキュリティのポップアップを許可する

gvproxyを使ったポートフォワードのアーキテクチャーは下記の通りになります。

Hyper-V版Podman machineのポートフォワードのアーキテクチャー

なお、Podman v4.7.0でWindows向けのポートフォワード機能の修正が行われ、WSL2ではgvproxyの代わりにwslrelayが使われるようになりました。*2

Tips

Hyper-V版のPodman machineを使う上でのポイントをいくつかまとめました。

  • Podman machineの作成時は必ずターミナルを管理者モードで起動する
    • 一般ユーザーで実行した場合は正常にPodman machineの作成が行えません
  • Podman machineの起動はpodman machine startコマンドを使用する
    • Hyper-Vマネージャー上で起動した場合は正常にPodman machineが使用できません
    • 停止はHyper-Vマネージャーで行っても問題ありません
  • Podman machineの初回起動後は仮想スイッチの変更は可能ですが、非推奨
    • 仮想スイッチを外部公開に切り替えるとポート公開を使用する時にgvproxyが正常に作動せず、コンテナが起動できません
    • 仮想マシンにホストネットワークと同じIPアドレスをアサインしたい要望がある場合は、Podman machineを使わずにFedoraなどを使う方が良いでしょう
  • コンシューマー向けのHyper-VではGPUパススルーが使えない
    • PodmanでGPUを使う用途がある場合はWSL2版を使いましょう

まとめ

  • Podman v4.8.0からHyper-V上でPodman machineを使うことができます。
  • CONTAINERS_MACHINE_PROVIDERhypervにセットしてpodman machine initを行うことでHyper-Vをバックエンドに使ったPodman machineが作成されます
  • Podman machineの起動後はWSL2版と同様にPodmanコマンドの実行やポートフォワードが使用できます。

実際に使うユーザー目線ではPodmanを実行するバックエンドの技術はWSL2でもHyper-Vでもどちらでも構わないといったところですが、使用目的に応じて選択肢が増えたのでこれからも色々試してみてそれぞれの利点を深掘りしていこうと思います。

[宣伝] Podmanの技術書 Podman Advanced Pod-01:DockerからPodmanへの移行

Podmanの技術書を書いて個人出版しました。Amazon Kindleストアと技術書典で電子書籍として購入できます。

Podman Advanced Pod-01:DockerからPodmanへの移行

Podmanイン・アクションには書いていないDockerからの移行方法やPodman machine、Podman Desktopの詳細な解説をしています。Podmanイン・アクションの次の一冊としてご活用ください。

*1:https://github.com/containers/podman/blob/main/pkg/machine/wsl/machine.go

*2:Implement automatic port reassignment on Windows by n1hility · Pull Request #19557 · containers/podman https://github.com/containers/podman/pull/19557

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。