Podman 在 Windows中使用
==================
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
安装步骤
- 启用WSL和虚拟机平台:在Windows中,选择“程序和功能”,然后选择“启用或关闭Windows功能”。勾选“适用于Linux的Windows子系统”和“虚拟机平台”两个选项。
- 安装WSL:以管理员模式启动PowerShell,并设置WSL版本为2,然后更新WSL核心,并安装WSL。完成后需要设置用户名和密码。
- 安装Podman:从GitHub下载Podman的Windows安装程序(如podman.exe或msi文件),并按照默认设置进行安装。安装完成后,可以通过在命令行中输入
podman -v
来检查版本号,以确认安装成功。 - 初始化Podman机器:在cmd中输入以下命令来初始化Podman机器:
podman machine init
。这将自动在WSL环境中设置并启动一个Podman机器。 - 使用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或更高版本以获取本指南中讨论的功能。
下载完成后,只需运行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
时间 2022 年 5 月 5 日星期四 21:56:42
请注意,ubi8-micro
是一个轻量级的Universal Base Image,专为容器化应用程序设计,这里用作示例。如果您的系统中没有这个镜像,Podman会尝试从远程仓库中拉取它。如果您想要运行其他的镜像或命令,只需将ubi8-micro
和date
替换为相应的镜像名和命令即可。
端口转发
端口转发也按预期工作;端口将绑定到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机器,您可以通过以下步骤操作:
- 停止或关闭正在使用Docker API的服务。
- 使用
podman machine stop
命令停止Podman机器(如果它正在运行)。 - 使用
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 发行版有三种机制:
- 使用
podman machine ssh
进行 SSH 访问 - 在 Windows PowerShell 提示符上执行 WSL 命令
- 使用 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 用户身份进入。
与之前一样,要切换到非特权用户以执行无 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 安装。请按照以下步骤操作:
- 以管理员身份启动 PowerShell
Start-Process powershell -Verb RunAs
- 禁用 WSL 功能
dism.exe /online /disable-feature /featurename:Microsoft-Windows-Subsystem-Linux /norestart
dism.exe /online /disable-feature /featurename:VirtualMachinePlatform /norestart
重新启动计算机
运行手动 WSL 安装
wsl --install
- 继续执行 podman machine init
安装证书颁发机构
============
安装 CA 证书的说明可以在这里找到。
请注意,确保在尝试手动安装 WSL 之前,您已经按照前面的步骤禁用了相关功能,并且重新启动了计算机。这有助于确保安装过程不受先前尝试的影响。此外,如果在安装或使用过程中遇到任何问题,建议查阅 Podman 的官方文档或寻求社区支持以获取进一步的帮助。