跳到主要内容

Podman 在 Windows中使用

PODMAN logo

==================

Podman在Windows上的使用主要依赖于Windows Subsystem for Linux(WSL),这使得在Windows环境下也能运行Linux容器。Podman为Windows提供了一个原生的命令行界面(CLI),并嵌入了一个用于启动容器的Linux系统作为Podman机器。这个机器通过podman machine命令进行管理。在Windows上,每个Podman机器都由一个虚拟化的WSLv2发行版支持。Podman命令可以直接从Windows PowerShell(或CMD)提示符中运行,与在WSL环境中运行的podman服务进行远程通信。另外,如果你更喜欢Linux提示符和Linux工具,也可以直接从WSL实例中访问Podman。除了命令行访问外,Podman还监听Docker API客户端,支持直接使用基于Docker的工具和从您选择的语言进行编程访问。

前提条件

由于Podman使用WSL,因此需要Windows 10或Windows 11的较新版本。在x64上,WSL需要内部版本18362或更高版本,而arm64系统则需要19041或更高版本。在内部,WSL使用虚拟化,因此系统必须支持并启用硬件虚拟化。如果在虚拟机上运行Windows,则必须具有支持嵌套虚拟化的虚拟机。

此外,建议使用现代的“Windows Terminal”,它提供了比标准PowerShell和CMD提示符更优越的用户体验,以及WSL提示符(如果需要)。可以通过Windows Store搜索或运行以下winget命令来安装它:

winget install Microsoft.WindowsTerminal

安装步骤

  1. 启用WSL和虚拟机平台:在Windows中,选择“程序和功能”,然后选择“启用或关闭Windows功能”。勾选“适用于Linux的Windows子系统”和“虚拟机平台”两个选项。
  2. 安装WSL:以管理员模式启动PowerShell,并设置WSL版本为2,然后更新WSL核心,并安装WSL。完成后需要设置用户名和密码。
  3. 安装Podman:从GitHub下载Podman的Windows安装程序(如podman.exe或msi文件),并按照默认设置进行安装。安装完成后,可以通过在命令行中输入podman -v来检查版本号,以确认安装成功。
  4. 初始化Podman机器:在cmd中输入以下命令来初始化Podman机器:podman machine init。这将自动在WSL环境中设置并启动一个Podman机器。
  5. 使用Podman:一旦Podman机器初始化并启动,就可以使用Podman命令来管理容器了。Podman提供了与Docker客户端相同的命令集,因此熟悉Docker的用户可以很容易地上手。

请注意,Podman服务主要在Linux平台上运行,但Podman的远程REST API客户端存在于Mac和Windows平台上,可以通过ssh与运行在Linux机器或VM上的Podman服务进行通信。

总的来说,Podman为Windows用户提供了一个方便的方式来管理和运行Linux容器,特别是在那些需要同时使用Linux工具和应用程序的场景中。

安装Podman


安装Windows Podman客户端的开始步骤是下载Podman Windows安装程序。Windows安装程序是随每个Podman发行版一起构建的,可以从官方的GitHub发行页面下载。请确保下载4.1或更高版本以获取本指南中讨论的功能。

安装Podman 4.1.0

下载完成后,只需运行EXE文件,并重新启动一个新的终端。此后,podman.exe将出现在你的PATH中,你将能够运行podman machine init命令来创建你的第一台机器。

podman machine init

自动WSL安装

如果你的系统上没有安装WSL,第一次机器初始化命令将提示一个对话框以开始自动安装。如果接受,此过程将安装必要的Windows组件,重启系统,并在登录后重新启动终端窗口中的机器创建过程。请等待一两分钟以便重新启动发生,因为Windows在执行启动项之前有一个延迟。另外,你也可以拒绝自动安装并手动安装WSL,但这将需要额外的下载和设置时间。

机器初始化过程

安装WSL后,初始化命令将安装Fedora的最小安装版本,并将其定制为运行podman。

示例:

podman machine init
正在解压压缩文件
正在将操作系统导入到WSL(在新安装的WSL上可能需要5分钟以上时间)...
正在安装软件包(这将需要一些时间)...
完成!
正在配置系统...
正在生成ed25519公钥/私钥对。
您的标识已保存在 podman-machine-default
您的公钥已保存在 podman-machine-default.pub
密钥指纹是:
SHA256:RGTGg2Q/LX7ijN+mzu8+BzcS3cEWP6Hir6pYllJtceA root@WINPC
机器初始化完成
要启动您的机器,请运行:
        podman machine start

启动机器

在机器初始化过程完成后,就可以根据需要启动和停止机器了:

podman machine start  
正在启动机器 "podman-machine-default"  

这台机器当前配置为无根模式。如果您的容器需要根权限(例如端口 < 1024),或者如果您遇到与非Podman客户端的兼容性问题,您可以使用以下命令进行切换:

podman machine set --rootful

API转发监听在:npipe:////./pipe/docker_engine

Docker API客户端默认使用这个地址。您不需要设置DOCKER_HOST。
机器 "podman-machine-default" 已成功启动

第一个Podman命令


从这一刻开始,Podman命令的操作与在Linux上的操作类似。

为了快速展示一个工作示例,您可以使用一个较小的镜像,在PowerShell上运行Linux的date命令。

podman run ubi8-micro date  

时间 202255 日星期四 21:56:42

请注意,ubi8-micro 是一个轻量级的Universal Base Image,专为容器化应用程序设计,这里用作示例。如果您的系统中没有这个镜像,Podman会尝试从远程仓库中拉取它。如果您想要运行其他的镜像或命令,只需将ubi8-microdate替换为相应的镜像名和命令即可。

端口转发

端口转发也按预期工作;端口将绑定到localhost(127.0.0.1)。注意:当以无根模式运行(默认设置)时,您必须使用大于1023的端口。有关更多详细信息,请参阅“Rootful和Rootless”部分。

要启动httpd,您可以运行:

podman run --rm -d -p 8080:80 --name httpd docker.io/library/httpd
f708641300564a6caf90c145e64cd852e76f77f6a41699478bb83a162dceada9

在PowerShell提示符下,对localhost执行curl命令将返回成功的HTTP响应:

curl http://localhost:8080/ -UseBasicParsing

StatusCode : 200
StatusDescription : OK
Content : <html><body><h1>It works!</h1></body></html>

与Linux一样,要停止,请运行:

podman stop httpd

使用API转发

API转发允许Docker API工具和客户端像使用Docker一样使用Podman。只要没有其他服务在监听Docker API管道,就不需要特殊设置。

.\docker.exe run -it fedora echo "Hello Podman!"
Hello Podman!

否则,在启动机器后,您将收到一个可以设置的环境变量通知,以便工具指向Podman。或者,您可以关闭冲突的服务和Podman,然后最后运行podman machine start以重新启动,这应该会抓取Docker API地址。

另一个进程正在监听默认的Docker API管道地址。您仍然可以通过在终端会话中使用以下PowerShell命令设置DOCKER HOST来连接Docker API客户端:

请注意,由于Podman和Docker在API级别上有所不同,尽管大多数常用命令都可以正常工作,但某些命令可能无法按预期工作。此外,某些Docker特定的配置和特性在Podman中可能不可用。

如果您发现Docker客户端工具与Podman不兼容,您可能需要考虑使用Podman的本地命令行界面,或者查找专门与Podman兼容的替代客户端工具。

对于需要Docker Compose的场景,Podman也提供了一个名为podman-compose的工具,它基于Docker Compose,但适用于Podman。

在使用API转发时,请确保您了解所使用的工具和Podman之间的兼容性问题,并准备好根据需要调整或寻找替代方案。 如果另一个进程正在使用默认的Docker API管道地址,您需要设置DOCKER_HOST环境变量,以便Docker客户端工具指向Podman的API管道。在PowerShell中,您可以使用以下命令来设置这个环境变量:

$Env:DOCKER_HOST = 'npipe:////./pipe/podman-machine-default'

在经典的CMD提示符下,您可以使用以下命令:

set DOCKER_HOST=npipe:////./pipe/podman-machine-default

请注意,npipe:////./pipe/podman-machine-default是Podman机器在Windows上启动时的默认管道名称。如果您有多个Podman机器或者使用了不同的机器名称,请确保将podman-machine-default替换为正确的机器名称。

如果您不想或不能关闭正在使用Docker API的另一个进程,您可以设置DOCKER_HOST环境变量,然后重试您的Docker命令。Podman应该能够像Docker一样响应这些命令。

如果您选择关闭冲突的服务并重新启动Podman机器,您可以通过以下步骤操作:

  1. 停止或关闭正在使用Docker API的服务。
  2. 使用podman machine stop命令停止Podman机器(如果它正在运行)。
  3. 使用podman machine start命令重新启动Podman机器。

重启后,Podman应该能够自动获取Docker API的地址,您可能就不需要手动设置DOCKER_HOST环境变量了。

一旦设置了DOCKER_HOST环境变量或解决了API地址冲突,您就可以使用Docker客户端工具与Podman进行交互了。例如,您可以使用docker.exe来检查Podman的版本:

$Env:DOCKER_HOST = 'npipe:////./pipe/podman-machine-default'
PS C:\Users\User> .\docker.exe version --format '{{(index .Server.Components 0).Name}}'
Podman Engine

这条命令会输出Podman Engine,表明您正在与Podman引擎通信,尽管您使用的是Docker的客户端工具。请注意,尽管Docker和Podman在API层面有许多相似之处,但它们仍然是不同的项目,因此可能不是所有Docker命令和特性都能在Podman中完全正常工作。

Rootful与Rootless

在嵌入的WSL Linux发行版上,Podman可以作为root用户(Rootful)运行,也可以作为非特权用户(Rootless)运行。为了与Linux上的Podman保持行为一致性,rootless是默认设置。请注意:Rootful和Rootless容器是相互独立和隔离的。针对其中一个容器执行的Podman命令(例如podman ps)不会代表另一个容器的结果或状态。

虽然大多数容器在rootless设置下可以正常运行,但您可能会发现某些容器只能使用root权限才能正常工作。如果是这种情况,您可以通过停止机器并使用set命令来将机器切换到rootful模式:

podman machine stop
podman machine set --rootful

要恢复rootless执行,将rootful设置为false:

podman machine stop
podman machine set --rootful=false

另一种可能需要使用rootful执行的情况是绑定小于1024的端口。但是,为了与系统端口服务(如MySQL)的默认值提高兼容性,Podman的未来版本可能会将这个值降低到一个更小的数字。

在rootless模式下,由于权限限制,某些操作可能无法执行,例如绑定到低端口或访问某些系统资源。而rootful模式则不受这些限制,但这也带来了潜在的安全风险,因为以root权限运行容器可能会暴露敏感信息或允许不受限制的系统访问。

因此,在选择使用Rootful还是Rootless时,需要权衡安全性和功能性。如果容器需要root权限才能正常工作,或者需要绑定到低端口,那么您可能需要使用Rootful模式。但是,请确保您了解潜在的安全风险,并采取适当的安全措施来保护您的系统。

此外,如果您正在使用Podman的Windows集成,请注意,Windows的安全模型与Linux不同,因此某些操作可能需要额外的配置或步骤。务必参考Podman的官方文档和Windows Subsystem for Linux(WSL)的文档以获取更多详细信息和指导。

卷挂载

Podman v4.1的新功能之一是能够从Windows路径将卷挂载到Linux容器中。这支持几种不同的表示法,包括:

Windows风格的路径:

podman run --rm -v c:\Users\User\myfolder:/myfolder ubi8-micro ls /myfolder

Unix风格的Windows路径:

podman run --rm -v /c/Users/User/myfolder:/myfolder ubi8-micro ls /myfolder

WSL文件系统本地的Linux路径:

podman run --rm -v /var/myfolder:/myfolder ubi-micro ls /myfolder

无论是在Windows提示符还是WSL Linux shell中,上述所有约定都有效。但是,当在Linux上使用Windows路径时,请适当地引用或转义参数中的Windows路径部分。

列出Podman机器

要列出可用的Podman机器实例及其当前资源使用情况,请使用podman machine ls命令:

podman machine ls
名称 虚拟机类型 创建时间 最后上线时间 CPU数量 内存大小 磁盘大小
podman-machine-default wsl 2小时前 当前运行中 4 331.1MB 768MB

由于WSL在多个发行版之间共享相同的虚拟机和Linux内核,因此CPU和内存值表示跨运行系统的共享总资源。与此相反,磁盘值是独立的,表示每个发行版的存储量。

请注意,podman machine ls显示的CPU和内存信息可能不包括其他正在运行的WSL发行版所使用的资源。这些信息主要关注Podman机器本身,但整个WSL环境的资源使用情况可能更高。磁盘大小信息则是针对每个WSL发行版独立的,可以帮助您了解每个发行版占用的存储空间。

访问 Podman Linux 环境

在 Windows 环境下使用 podman.exe 客户端提供了无缝的原生体验,支持使用本地的桌面工具和 API。但是,在某些场景下,您可能希望访问 Linux 环境:

  • 更新嵌入的 Fedora 实例上的最新稳定软件包
  • 直接使用 Linux 开发工具
  • 使用依赖于 EXT4 文件系统性能或行为语义的工作流

访问嵌入的 WSL 发行版有三种机制:

  1. 使用 podman machine ssh 进行 SSH 访问
  2. 在 Windows PowerShell 提示符上执行 WSL 命令
  3. 使用 Windows Terminal 集成

使用 SSH

SSH 访问提供了与 Podman 在 Mac 上的类似体验。它会根据您机器的 rootful/rootless 配置立即将您放入适当的用户(前者为 root,后者为 'user')。可以使用 --username 选项来覆盖为特定用户。

使用 SSH 的一个示例任务是更新您的 Linux 环境以拉取最新的操作系统错误修复:

podman machine ssh sudo dnf upgrade -y

这条命令将通过 SSH 连接到 Podman 机器,并以 root 用户身份执行 dnf upgrade -y 命令,从而更新系统软件包。这将确保您的 Linux 环境具有最新的安全补丁和功能更新。请注意,执行此命令可能需要一些时间,具体取决于您的系统配置和网络连接速度。

使用 WSL 命令

wsl 命令提供了直接访问 Linux 系统的功能,但首先会以 root 用户身份进入 shell。这是由于 WSL 的设计限制,运行 systemd(Linux 的系统服务)需要使用特权进程命名空间。

除非您没有安装其他 WSL 发行版,否则建议使用 -d 选项并指定您的 Podman 机器名称(默认为 podman-machine-default):

wsl -d podman-machine-default

您会自动进入一个嵌套的进程命名空间,其中 systemd 正在运行。如果需要访问父级命名空间,请按 ctrl-d 或键入 exit。这也意味着要注销,您需要退出两次。

podman --version
podman version 4.1.0

要以非特权用户(无 root 权限的 Podman)身份访问命令,您首先需要键入 su user。或者,您可以在 wsl 命令前加上特殊的 enterns 来使用:

wsl -d podman-machine-default enterns su user
[user@WINPC /]$ id
uid=1000(user) gid=1000(user) groups=1000(user),10(wheel)

同样,以 root 用户身份运行命令而不进入提示符也应该以 enterns 为前缀。

wsl -d podman-machine-default enterns systemctl status

使用 wsl -u 以特定用户身份访问 WSL 实例或使用不带 enterns 的内联命令是不推荐的,因为命令将在错误的命名空间中执行。

使用 Windows Terminal 集成

以 root 用户身份进入 WSL 只需要两步操作。只需点击下拉标签,选择“podman-machine-default”,您就可以直接以 root 用户身份进入。

在 Windows Terminal 中使用 WSL

与之前一样,要切换到非特权用户以执行无 root 权限的 Podman 命令,请键入 su user

[root@WINPC /]# su user
[user@WINPC /]$ podman info --format '{{.Store.RunRoot}}'
/run/user/1000/containers

停止 Podman 机器

要停止正在运行的 Podman 机器,请使用 podman machine stop 命令:

podman machine stop
Machine "podman-machine-default" stopped successfully

删除 Podman 机器

要删除机器,请使用 podman machine rm 命令:

podman machine rm

以下文件将被删除:

C:\Users\User\.ssh\podman-machine-default
C:\Users\User\.ssh\podman-machine-default.pub
C:\Users\User\.local\share\containers\podman\machine\wsl\podman-machine-default_fedora-35-x86_64.tar
C:\Users\User\.config\containers\podman\machine\wsl\podman-machine-default.json
C:\Users\User\.local\share\containers\podman\machine\wsl\wsldist\podman-machine-default

您确定要继续吗? [y/N] y

请注意,在删除 Podman 机器之前,系统会询问您是否确定要删除,并且会列出将被删除的文件。确保您确实想要删除该机器以及与之相关的所有数据,然后再继续。删除操作是不可逆的,一旦执行,相关数据将无法恢复。

故障排除

从 WSL 自动安装失败中恢复

如果自动安装失败,并且重试不成功,您可以尝试重置 WSL 系统状态,并使用 wsl --install 命令执行手动 WSL 安装。请按照以下步骤操作:

  1. 以管理员身份启动 PowerShell
Start-Process powershell -Verb RunAs
  1. 禁用 WSL 功能
dism.exe /online /disable-feature /featurename:Microsoft-Windows-Subsystem-Linux /norestart
dism.exe /online /disable-feature /featurename:VirtualMachinePlatform /norestart
  1. 重新启动计算机

  2. 运行手动 WSL 安装

wsl --install
  1. 继续执行 podman machine init

安装证书颁发机构

============

安装 CA 证书的说明可以在这里找到。

请注意,确保在尝试手动安装 WSL 之前,您已经按照前面的步骤禁用了相关功能,并且重新启动了计算机。这有助于确保安装过程不受先前尝试的影响。此外,如果在安装或使用过程中遇到任何问题,建议查阅 Podman 的官方文档或寻求社区支持以获取进一步的帮助。