Podman

来自 ArchWiki

Podman 是 Docker 的替代品,提供类似的界面。它支持无根容器和用于 docker-compose 的 shim 服务。

安装

安装 podman 软件包。

Podman 依赖 netavark 软件包作为有根容器的默认网络后端(参见 podman-network(1))。Netavark 依赖 aardvark-dns 以在同一网络中的容器之间进行名称解析。对替代网络后端(CNI,cni-plugins)的支持已被弃用。

如果您想替换 Docker,可以安装 podman-docker 来模拟 docker 二进制文件以及 man 手册页。

Docker 不同,Podman 不需要守护进程,但有一个守护进程通过 cockpit-podmancockpit 等服务提供 API。

有关构建容器的高级用法,请参阅基于 Buildahpodman-build(1)

配置

用于配置容器行为的配置文件位于 /usr/share/containers/。您必须先将必要的文件复制到 /etc/containers 才能编辑。要配置 Podman 使用的网络桥接接口,请参阅 /etc/cni/net.d/87-podman.conflist

镜像仓库

默认情况下,Arch Linux 中未配置任何容器镜像仓库 [1]。这意味着像 podman search httpd 这样的非限定搜索将不起作用。要使 Podman 的行为类似于 Docker,请配置 containers-registries.conf(5)

/etc/containers/registries.conf.d/10-unqualified-search-registries.conf
unqualified-search-registries = ["docker.io"]

此文章或章节的准确性存在争议。

原因: 链接的列表由 containers-common 安装在 /etc/containers/registries.conf.d/00-shortnames.conf 中。(在 Talk:Podman 中讨论)
提示: 为了使非限定搜索对于知名镜像更安全,请考虑将 短名称列表https://github.com/containers/shortnames 集成到您的配置中,例如 通过将其复制到 /etc/containers/registries.conf.d/shortnames.conf

用户命名空间模式

默认情况下,Podman 容器中的进程与调用者在同一用户命名空间中运行,即容器未通过 user_namespaces(7) 功能隔离。这是 --userns=host 的行为,请参见 podman-run(1)

--userns=auto 标志会自动为容器创建一个唯一的用户命名空间,使用空的 UID 和 GID 范围

  • 对于 root 启动的容器,--userns=auto 标志要求在 /etc/subuid/etc/subgid 文件中指定用户名 containers,并具有未使用的 ID 范围。例如:containers:2147483647:2147483648
  • 对于其他用户启动的容器,将使用 /etc/subuid/etc/subgid 文件中的用户范围。有关必要的配置,请参见 #无根 Podman

--userns 标志还有其他有效值,详细信息请参见 podman-run(1)。用户命名空间模式也可以在 containers.conf(5) 文件中按系统或按用户配置。

无根 Podman

警告: 无根 Podman 依赖于非特权用户命名空间使用(CONFIG_USER_NS_UNPRIVILEGED),这有一些严重的安全隐患,详细信息请参见 安全性#沙盒化应用程序

默认情况下,只有 root 允许运行容器(或内核术语中的命名空间)。运行无根 Podman 可以提高安全性,因为攻击者将不会拥有您系统的 root 权限,并且还允许多个非特权用户在同一台机器上运行容器。另请参见 podman(1) § 无根模式 和官方 无根教程(可能已过时)。

启用 kernel.unprivileged_userns_clone

首先,通过运行以下命令检查 kernel.unprivileged_userns_clone 的值

$ sysctl kernel.unprivileged_userns_clone

如果当前设置为 0,请通过 sysctl内核参数 将其设置为 1 来启用它。

注意: linux-hardened 默认将 kernel.unprivileged_userns_clone 设置为 0

设置 subuid 和 subgid

为了让用户运行无根 Podman,每个想要使用它的用户都必须存在 subuid(5)subgid(5) 配置条目。默认情况下,使用 useradd(8) 创建的新的 用户 具有这些条目。

为 shadow 4.11.1-3 之前创建的用户迁移

默认情况下,在 shadow 4.11.1-3 之前创建的用户在 /etc/subuid/etc/subgid 中没有条目。可以使用 usermod(8) 命令或手动修改文件来为他们创建条目。

以下命令启用 username 用户和组运行 Podman 容器(或那种情况下的其他类型的容器)。它为给定的用户和组分配给定的 UID 和 GID 范围。

# usermod --add-subuids 100000-165535 --add-subgids 100000-165535 username

用户 username 的上述范围可能已被另一个用户占用,因为它定义了系统上第一个用户的默认范围。如有疑问,请先查阅 /etc/subuid/etc/subgid 文件以查找已保留的范围。

注意: 许多镜像需要 65536 个 UID/GID 进行映射(特别是基本 busyboxalpine 镜像)。建议您为每个用户分配至少那么多 UID/GID,以最大限度地提高与 Docker 的兼容性。
homed 管理用户的变通方法

Homed 似乎没有为其用户分配 giduid 条目。要手动执行此操作,请运行

# usermod --add-subuids 524288-589823 --add-subgids 524288-589823 username

或者,只需以 root 身份编辑以下配置文件并添加以下行

/etc/subuid
username:524288:65536
/etc/subgid
username:524288:65536

这会将 uidgid 范围 524288-589823 分配给 username 用户。如果这些范围已被其他用户占用,则您需要相应地移动/调整范围。

您可能需要重启才能反映更改。

注意
传播 subuid 和 subgid 的更改

无根 Podman 使用暂停进程来保持非特权命名空间处于活动状态。这会阻止 /etc/subuid/etc/subgid 文件的任何更改传播到正在运行暂停进程的无根容器。为了传播这些更改,需要运行

$ podman system migrate

在此之后,上述文件中指定的用户/组能够启动和运行 Podman 容器。

启用原生无根 Overlay

以前,在无根环境中使用 FUSE overlay 挂载需要使用 fuse-overlayfs 软件包。但是,现代版本的 Podman 和 Linux 内核 支持 原生 无根 overlay,这会产生更好的性能。

注意: 当启动具有修改后的 UID/GID 映射的无根容器,并且尚未使用指定的容器镜像和 UID/GID 映射创建容器时,使用原生 overlay 会导致性能损失,与 fuse-overlayfs 相比,因为必须在磁盘上更新容器的所有文件的 UID/GID。这尤其影响 --userns auto,其中每次调用都可能使用不同的 UID/GID 映射。有关详细信息,请参见 Podman 性能指南

要从 fuse-overlayfs 迁移,请运行以下命令(不幸的是,它将删除所有拉取的镜像)

$ podman system reset

还要确保 Podman 使用 overlay 驱动程序,并且未在 containers-storage.conf(5) 中定义 mount_program 参数。请按照 Docker#启用原生 overlay diff 引擎 中的说明进行操作。

要验证是否启用了原生无根 overlay,请运行

$ podman info | grep -i overlay

它应显示 graphDriverName: overlayNative Overlay Diff: "true"

网络

Podman 依赖 passt,它提供 pasta 作为默认的无根网络后端。

另一种无根网络后端是 slirp4netns,它是 Podman 5 之前的默认后端。

两者之间的主要区别在 Podman 5.0 详细的重大更改 中概述

Pasta 默认不执行网络地址转换 (NAT),并将主接口的 IP 地址复制到容器命名空间中。

上游的 无根 Podman 的缺点 中解释了此更改的后果

由于 pasta 复制了主接口的 IP 地址,因此从容器到该 IP 的连接不起作用。这意味着,除非您有多个接口,否则如果不显式传递 pasta 网络配置(在 containers.conf 中或在运行时),就无法建立容器间连接。
提示: 容器到主机的通信问题在 Podman 5.3 中得到修复。[2]

“Podman 5.0 重大更改”博客文章中给出了一个模仿 slirp4netns 行为的示例

containers.conf
[network]
pasta_options = ["-a", "10.0.2.0", "-n", "24", "-g", "10.0.2.2", "--dns-forward", "10.0.2.3"]

此外,默认的无根网络工具可以在 containers.conf[network] 部分中使用 default_rootless_network_cmd 进行选择,可以将其设置为 pastaslirp4netns。因此,如果您遇到错误,您可以随时像这样恢复到 slirp4netns(前提是已安装)

containers.conf
[network]
default_rootless_network_cmd = "slirp4netns"

存储

容器镜像和实例的存储方式和位置的配置在 /etc/containers/storage.conf 中进行。

注意: 当使用 #无根 Podman 时,可以按用户将存储设置的覆盖添加到 $XDG_CONFIG_HOME/containers/storage.conf

默认的 overlay 驱动程序经过充分测试,并且在支持它的文件系统(BtrfsXFSZFS...)上支持 reflink 复制 [3] [4]

有关可用替代方案和其他配置选项的更多信息,请参见 containers-storage.conf(5) § STORAGE_TABLE

非本地架构

Podman 能够使用 Wikipedia:binfmt_misc 系统运行为与主机不同的 CPU 架构构建的镜像。

要启用它,请安装 qemu-user-staticqemu-user-static-binfmt

systemd 附带 systemd-binfmt.service 服务,该服务应启用新规则。

验证 binfmt 规则是否已添加

$ ls /proc/sys/fs/binfmt_misc
DOSWin        qemu-cris        qemu-ppc      qemu-sh4eb        status
qemu-aarch64  qemu-m68k        qemu-ppc64    qemu-sparc        
qemu-alpha    qemu-microblaze  qemu-riscv64  qemu-sparc32plus  
qemu-arm      qemu-mips        qemu-s390x    qemu-sparc64      
qemu-armeb    qemu-mipsel      qemu-sh4      register

Podman 现在应该能够运行非本地架构镜像。大多数命令在传递 --arch 选项时使用非本地架构。

示例

# podman run --arch arm64 'docker.io/alpine:latest' arch
aarch64

Docker Compose

Podman 有一个 compose 子命令,它是 compose 提供程序的薄包装器,可以是 docker-composepodman-compose。如果两者都已安装,docker-compose 优先。您可以使用 PODMAN_COMPOSE_PROVIDER 环境变量覆盖此设置。

如果您想使用 docker-compose,您将需要为该用户 启用 podman.socket 用户单元 并设置 docker 套接字环境变量

$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock

当使用 podman-compose 时,不需要这样做,因为它将直接使用 podman

注意

NVIDIA GPU

NVIDIA 容器工具包 为 NVIDIA GPU 提供容器运行时。安装 nvidia-container-toolkit 软件包。它包含一个 pacman hook,用于为您的 GPU 生成 CDI 规范并将其保存在 /etc/cdi/nvidia.yaml 中。

测试设置

$ podman run --rm --gpus all archlinux nvidia-smi -L
注意: NVIDIA CDI hook 不适用于 --userns nomap--userns auto podman run 参数。[5]

具有重启策略的容器

要自动启动具有重启策略的容器,启用 podman-restart.service

Quadlet

Quadlet 允许使用 systemd 管理 Podman 容器。

对于无根 Podman,将 Quadlet 文件放置在以下目录之一

  • $XDG_CONFIG_HOME/containers/systemd/~/.config/containers/systemd/
  • /etc/containers/systemd/users/UID,适用于与 UID 匹配的用户
  • /etc/containers/systemd/users/,适用于所有用户

对于具有 root 权限的 Podman,目录为 /etc/containers/systemd/

Podman 将读取扩展名为 .container.volume.network.kube.image.pod 的 Quadlet 文件。将使用 systemd.generator(7) 生成相应的 .service 文件。Quadlet 文件在启动期间或通过手动运行 daemon-reload 读取。

Quadlet 文件也可以使用 podletAUR 从 Podman 命令生成。

例如,这是一个将从 LinuxServer.io 运行 Syncthing 容器的命令

$ podman run \
    --rm \
    --replace \
    --label io.containers.autoupdate=registry \
    --name syncthing \
    --hostname=syncthing \
    --uidmap 1000:0:1 \
    --uidmap 0:1:1000 \
    --uidmap 1001:1001:64536 \
    --env PUID=1000 \
    --env PGID=1000 \
    --env TZ=Etc/UTC \
    --publish 127.0.0.1:8384:8384/tcp \
    --publish 22000:22000/tcp \
    --volume /path/to/syncthing/config:/config \
    --volume /path/to/data1:/data1 \
    lscr.io/linuxserver/syncthing:latest

要将其作为 systemd 服务进行管理,请创建以下 Quadlet 文件

~/.config/containers/systemd/syncthing-lsio.container
[Unit]
Description=Syncthing container

# Containers can depend on one another using systemd dependencies, but with a ".service" suffix.
# For example, to make another container wait until this one starts, add "After=syncthing-lsio.service"
# to its [Unit] section.

[Container]
ContainerName=syncthing
Image=lscr.io/linuxserver/syncthing:latest

# Enable auto-update container
AutoUpdate=registry

Volume=/path/to/syncthing/config:/config
Volume=/path/to/data1:/data1

HostName=syncthing
PublishPort=127.0.0.1:8384:8384/tcp
PublishPort=22000:22000/tcp

Environment=PUID=1000
Environment=PGID=1000
Environment=TZ=Etc/UTC

# UID mapping is needed to run linuxserver.io container as rootless podman.
# This will map UID=1000 inside the container to intermediate UID=0.
# For rootless podman intermediate UID=0 will be mapped to the UID of current user.
UIDMap=1000:0:1
UIDMap=0:1:1000
UIDMap=1001:1001:64536

[Service]
Restart=on-failure

# Extend Timeout to allow time to pull the image
TimeoutStartSec=300

# The [Install] section allows enabling the generated service.
[Install]
WantedBy=default.target

我们可以通过以下方式验证 Quadlet 文件

$ /usr/lib/podman/quadlet -dryrun -user

然后,重新加载启动/启用 syncthing-lsio.service。请参阅 systemd/User#自动启动 systemd 用户实例 以在没有任何打开会话的情况下启动无根容器。

如果您想在启动时启动容器,请确保您的 网络管理器 支持并配置为 在网络启动后运行服务

注意: Quadlet 将通过向 systemd 单元添加 After=Wants= 属性,隐式地依赖于 network-online.target(作为 root 用户)或 podman-user-wait-network-online.service(作为用户)。这是为了确保如果需要拉取镜像,并且在容器启动时网络是可访问的。有关详细信息,请参见 podman-systemd.unit(5) § 隐式网络依赖项

Container 部分的有效选项在 podman-systemd.unit(5) § 容器单元 [Container] 下列出。PodmanArgs= 可用于添加其他没有相应文件选项的 Podman 参数。

有关更多示例,包括 PodVolumeNetworkImage 单元,请参见 podman-systemd.unit(5) § 示例

镜像

注意: 您可以从镜像中省略注册表前缀,因为 Podman 将在 /etc/containers/registries.conf 中的 unqualified-search-registries 中定义的所有注册表中按定义的顺序自动搜索镜像。以下镜像将始终包含前缀,以允许在配置中不包含 docker.io 的情况。

Arch Linux

以下命令从 Docker Hub 拉取 Arch Linux x86_64 镜像。

# podman pull docker.io/archlinux

有关可用标签的完整列表,包括带和不带构建工具的版本,请参见 Docker Hub 页面。

另请参见 README.md

Alpine Linux

Alpine Linux 是小型容器镜像的流行选择,特别是对于编译为静态二进制文件的软件。以下命令从 Docker Hub 拉取最新的 Alpine Linux 镜像

# podman pull docker.io/alpine

Alpine Linux 使用 musl libc 实现,而不是大多数 Linux 发行版使用的 glibc libc 实现。由于 Arch Linux 使用 glibc,因此 Arch Linux 主机和 Alpine Linux 容器之间存在许多功能差异,这些差异会影响软件的性能和正确性。这些差异的列表记录在 https://wiki.musl-libc.org/functional-differences-from-glibc.html 中。

请注意,在 Arch Linux(或任何其他使用 glibc 的系统)上动态链接的软件在 Alpine Linux(或任何其他使用不同 libc 的系统)上运行时,可能会出现错误和性能问题。有关示例,请参见 [6][7][8]

CentOS

以下命令从 Docker Hub 拉取最新的 CentOS 镜像

# podman pull docker.io/centos

有关每个 CentOS 版本的可用标签的完整列表,请参见 Docker Hub 页面。

Debian

以下命令从 Docker Hub 拉取最新的 Debian 镜像

# podman pull docker.io/debian

有关可用标签的完整列表,包括每个 Debian 版本的标准版和 slim 版,请参见 Docker Hub 页面。

故障排除

向进程添加暂停

WARN[0000] Failed to add pause process to systemd sandbox cgroup: Process org.freedesktop.systemd1 exited with status 1 

可以使用以下方法解决:https://github.com/containers/crun/issues/704

# echo +cpu +cpuset +io +memory +pids > /sys/fs/cgroup/cgroup.subtree_control

容器在 Shell 退出时终止

从机器注销后,某些用户的 Podman 容器会停止。要防止这种情况,请为运行容器的用户启用用户持久

您还可以按照 podman-auto-update(1) § 示例 中的描述创建用户 systemd 单元。

在无根模式下提交时出错

Error committing the finished image: error adding layer with blob "sha256:02823fca9b5444c196f1f406aa235213254af9909fca270f462e32793e2260d8": Error processing tar file(exit status 1) permitted operation

检查存储驱动程序是否为 存储配置 中的 overlay。

在无根模式下创建带有桥接网络的容器时出错

此文章或章节已过时。

原因: CNI 网络后端已被弃用。这是 Netavark 后端的问题吗?(在 Talk:Podman 中讨论)

如果您正在使用 AppArmor,则在启用 dnsname 插件的情况下使用桥接网络创建容器时,可能会遇到问题

$ podman network create foo
/home/user/.config/cni/net.d/foo.conflist
$ podman run --rm -it --network=foo docker.io/library/alpine:latest ip addr
Error: command rootless-cni-infra [alloc 89398a9315256cb1938075c377275d29c2b6ebdd75a96b5c26051a89541eb928 foo festive_hofstadter    ] in container 1f4344bbd1087c892a18bacc35f4fdafbb61106c146952426488bc940a751efe failed with status 1, stdout="", stderr="exit status 3\n"

可以通过将以下行添加到 /etc/apparmor.d/local/usr.sbin.dnsmasq 来解决此问题

owner /run/user/[0-9]*/containers/cni/dnsname/*/dnsmasq.conf r,
owner /run/user/[0-9]*/containers/cni/dnsname/*/addnhosts r,
owner /run/user/[0-9]*/containers/cni/dnsname/*/pidfile rw,

然后重新加载 AppArmor 配置文件

# apparmor_parser -R /etc/apparmor.d/usr.sbin.dnsmasq
# apparmor_parser /etc/apparmor.d/usr.sbin.dnsmasq

未找到镜像

此文章或章节是与 #镜像仓库 合并的候选对象。

备注: 现在该主题应在配置部分中介绍。(在 Talk:Podman 中讨论)

默认情况下,注册表列表未填充,因为软件包中的文件来自上游。这意味着默认情况下,尝试拉取任何未指定注册表的镜像将导致类似于以下的错误

Error: short-name "archlinux" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

一个初始配置可能是以下内容

/etc/containers/registries.conf.d/00-unqualified-search-registries.conf
unqualified-search-registries = ["docker.io"]
/etc/containers/registries.conf.d/01-registries.conf
[[registry]]
location = "docker.io"

这等效于默认的 docker 配置。

另一种不太方便的替代方法,但与未配置短名称的系统具有更高的兼容性,是在 ContainerfileDockerfile 中使用完整的注册表路径。

Containerfile
FROM docker.io/archlinux/archlinux

权限被拒绝:OCI 权限被拒绝

$ podman exec openvas_openvas_1 bash
Error: crun: writing file `/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/user.slice/libpod-b3e8048a9b91e43c214b4d850ac7132155a684d6502e12e22ceb6f73848d117a.scope/container/cgroup.procs`: Permission denied: OCI permission denied

可以解决:BBS#253966

$ env DBUS_SESSION_BUS_ADDRESS= podman ...
$ env DBUS_SESSION_BUS_ADDRESS= podman-compose ...

推送镜像到 Docker Hub:访问被拒绝/需要身份验证

当使用 podman push 将容器镜像推送到 Docker Hub 时,可能会发生以下错误:Requested access to the resource is deniedAuthentication required。以下提示可以帮助修复潜在问题

  • 标记本地镜像
    # podman tag <localImage> docker.io/<dockerHubUsername>/<dockerHubRepository>:<Tag>
  • 推送标记的镜像
    # podman push docker.io/<dockerHubUsername>/<dockerHubRepository>:<Tag> docker://docker.io/<dockerHubUsername>/<dockerHubRepository>:<Tag>
  • 登录到 docker.io、Docker Hub 仓库和 Docker Hub 注册表服务器
# podman login -u <DockerHubUsername> -p <DockerHubPassword> registry-1.docker.io
# podman login -u <DockerHubUsername> -p <DockerHubPassword> docker.io/<dockerHubUsername>/<dockerHubRepository>
# podman login -u <DockerHubUsername> -p <DockerHubPassword> docker.io
  • 在登录之前从所有注册表注销,例如,
    # podman logout --all
  • 在仓库的 Docker Hub Collaborators 选项卡中添加 <dockerHubUsername> 作为协作者

WARN[0000] "/" 不是共享挂载,这可能会导致 rootless 容器出现问题或丢失挂载

以 rootless 身份运行的 Buildah/Podman 期望绑定挂载是共享的,请检查它是否设置为私有

$ findmnt -o PROPAGATION /
PROPAGATION
private

在这种情况下,请参阅 mount(8) § Shared_subtree_operations临时将挂载设置为共享,使用

# mount --make-shared /

永久设置它,请编辑 /etc/fstab 并将shared 选项添加到所需的挂载点,然后重启。 它将产生如下条目

/etc/fstab
# <device>                                <dir> <type> <options> <dump> <fsck>
UUID=0a3407de-014b-458b-b5c1-848e92a327a3 /     ext4   defaults,shared   0      1

容器内部的网络问题

IP 网络

此文章或章节的准确性存在争议。

原因: 这是一个关于容器网络受主机防火墙影响的声明的过于冗长的介绍。 Netavark 使用 iptables 创建自己的防火墙规则,因此 iptables 链中的默认 DROP 策略不是问题。(在 Talk:Podman 中讨论)

默认情况下,Podman 容器通过它们自己的虚拟网络接口与主机桥接。

例如,在容器内部,虚拟接口 eth0@if6 的 IP 地址为 10.89.0.3(IP 地址在您的系统上可能不同!)

container# ip addr
...
2: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    ...
    inet 10.89.0.3/24 brd 10.89.0.255 scope global eth0
       valid_lft forever preferred_lft forever

在主机上,来自容器的数据包从主机端的另一个虚拟接口(此处命名为 podman1)传出,就像通过 IP 地址 10.89.0.1 路由一样。

host# ip addr
...
4: podman1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    ...
    inet 10.89.0.1/24 brd 10.89.0.255 scope global podman1

尽管是虚拟 IP 地址,数据包仍然通过内核的数据包过滤系统路由,因此可能会被 iptables/nftables 规则阻止。 特别是,INPUTFORWARD iptables 过滤器链中的默认 DROP 策略和/或运行的防火墙(ufw, firewalld)在某些情况下会影响容器。 如果您认为可能是这种情况,请检查您的配置(例如使用 iptables -L -n -vnft list ruleset)。

在更改 docker-compose.yml 后,请注意,创建的网络(来自 networks: 部分)在使用 podman compose down 销毁环境时可能不会被销毁。 如果这是您的意图,请确保(如有必要,使用 podman network lspodman network rm 检查并删除它们)。

DNS 和名称解析

名称解析由 Podman 的子系统处理(例如 aardvark-dns),它提供外部 DNS(通常通过主机的 DNS 解析器)和容器名称解析(例如,webserver.dns.podmandatabase.dns.podman 通信)。

在上面的示例中,容器由 Podman 通过 /etc/resolv.conf 自动配置,以向管道主机端端口 53 上运行的 DNS 解析器发出请求

container# cat /etc/resolv.conf
search dns.podman
nameserver 10.89.0.1

检查您是否在主机上的端口 53 上运行了另一个 DNS 解析器(例如 Systemd-resolvedUnbound),因为它可能会干扰 Podman 名称解析。 如果是这种情况,您可以将 Podman 在主机上使用的端口更改为任何其他可用端口,Podman 应该会自动将来自容器的容器请求转发到主机上的正确端口

host# # cat /etc/containers/containers.conf
...
dns_bind_port = 20053

内核不支持 overlay fs: 不支持在 <filesystem> 上使用 'overlay'

重新启动您的系统,如 General troubleshooting#Cannot use some peripherals after kernel upgrade 中所述。

另请参阅