Podman
Podman 是 Docker 的替代品,提供了类似的接口。它支持无根 (rootless) 容器,并为 docker-compose 提供了一个垫片服务。
安装
Podman 依赖 netavark 软件包作为 rootful 容器的默认网络后端(参见 podman-network(1))。Netavark 依赖 aardvark-dns 来解析同一网络中容器之间的名称。对替代网络后端(CNI, cni-plugins)的支持已被弃用。
如果您想替换 Docker,可以安装 podman-docker 以模仿 docker 二进制文件及相关手册页。
与 Docker 不同,Podman 不需要后台守护进程,但确实存在一个为 cockpit 等服务提供 API 的守护进程,通过 cockpit-podman 提供。
有关构建容器的高级用法,请参阅基于 Buildah 的 podman-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"]
用户命名空间模式
默认情况下,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文件中用户的范围。参见 #无根 (Rootless) Podman 获取必要的配置。
--userns 标志还有其他有效值,详情请参见 podman-run(1)。用户命名空间模式也可以在系统级或用户级的 containers.conf(5) 文件中配置。
无根 (Rootless) Podman
CONFIG_USER_NS_UNPRIVILEGED),这具有一些严重的安全隐患,详见 Security#沙盒化应用程序。默认情况下,只有 root 被允许运行容器(在内核术语中为命名空间)。运行无根 Podman 可以提高安全性,因为攻击者无法获得系统的 root 权限,同时也允许多个非特权用户在同一台机器上运行容器。另请参见 podman(1) § Rootless mode 和官方的 无根指南(可能已过期)。
启用 kernel.unprivileged_userns_clone
首先,通过运行以下命令检查 kernel.unprivileged_userns_clone 的值:
$ sysctl kernel.unprivileged_userns_clone
如果当前设置为 0,请通过 sysctl 或 内核参数将其设置为 1 以启用。
设置 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) 命令或手动修改文件来为他们创建条目。
以下命令使 用户名 用户和组能够运行 Podman 容器(或其他类型的容器)。它为指定的用户和组分配了一定范围的 UID 和 GID。
# usermod --add-subuids 100000-165535 --add-subgids 100000-165535 username
用户 用户名 的上述范围可能已被其他用户占用,因为它定义了系统上第一个用户的默认范围。如有疑问,请先查阅 /etc/subuid 和 /etc/subgid 文件以查找已预留的范围。
- 许多镜像需要 65536 个 UID/GID 进行映射(尤其是基础 busybox 和 alpine 镜像)。建议为每个用户分配至少这么多 UID/GID,以最大限度地兼容 Docker。
- 配置文件列出的是起始值和计数,而不是 usermod 命令中使用的起始值和结束值。参见 subuid(5)。
针对由 homed 管理的用户的变通方法
Homed 似乎不会为其用户分配 gid 和 uid 条目。要手动执行此操作,请运行
# usermod --add-subuids 524288-589823 --add-subgids 524288-589823 username
或者只需以 root 身份编辑以下配置文件并添加这些行:
/etc/subuid
username:524288:65536
/etc/subgid
username:524288:65536
这将 uid 和 gid 范围 524288-589823 分配给 用户名。如果这些范围已被其他用户占用,您需要相应地移动/调整范围。
您可能需要重新启动才能使更改生效。
- 这仅是一个变通方案,Podman 似乎并不官方支持 homed。
- 这是 systemd-homed 的一个已知问题。
- 使用 Docker 似乎可以工作(将用户添加到
docker组,但有其自身的安全隐患)。
传播 subuid 和 subgid 的更改
无根 Podman 使用一个暂停进程来保持非特权命名空间处于活动状态。当暂停进程运行时,这会阻止 /etc/subuid 和 /etc/subgid 文件的任何更改传播到无根容器。为了使这些更改能够生效,必须运行:
$ podman system migrate
在此之后,上述文件中指定的用户/组将能够启动并运行 Podman 容器。
启用原生无根覆盖文件系统 (Native rootless overlays)
此前,在无根环境中进行 FUSE 覆盖挂载时,必须使用 fuse-overlayfs 软件包。然而,现代版本的 Podman 和 Linux 内核支持 原生 无根覆盖层,这能带来更好的性能。
--userns auto,其中每次调用都可能使用不同的 UID/GID 映射。详情请参见 Podman 性能指南。要从 fuse-overlayfs 迁移,请运行以下命令(不幸的是,这将删除所有已拉取的镜像):
$ podman system reset
同时确保 Podman 使用 overlay 驱动程序,且 mount_program 参数未在 containers-storage.conf(5) 中定义。遵循 Docker#启用原生 overlay diff 引擎 中的说明。
要验证是否启用了原生无根覆盖层,请运行:
$ podman info | grep -i overlay
它应该显示 graphDriverName: overlay 和 Native Overlay Diff: "true"。
网络
Podman 依赖 passt,它提供 pasta 作为默认的无根网络后端。
另一种无根网络后端是 slirp4netns,它是 Podman 5 之前版本的默认后端。
两者之间的主要区别在 Podman 5.0 破坏性变更详解 中有所概述。
- Pasta 默认不执行网络地址转换 (NAT),而是将主接口的 IP 地址复制到容器命名空间中。
这一变更的后果在官方的 无根 Podman 的缺陷 中有详细说明。
- 由于 pasta 复制了主接口的 IP 地址,从容器到该 IP 的连接无法工作。这意味着除非您拥有多个接口,否则无法在不显式传递 pasta 网络配置(在
containers.conf或运行时)的情况下建立容器间连接。
在“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 选择默认的无根网络工具,它可以设置为 pasta 或 slirp4netns。因此,如果您遇到错误,总是可以像这样恢复到 slirp4netns(前提是已安装):
containers.conf
[network] default_rootless_network_cmd = "slirp4netns"
双栈 IPv4/IPv6
Podman 创建的默认网络仅支持 IPv4 网络 [3]。
您可以使用以下命令创建一个支持双栈 IPv4/IPv6 的新网络:
$ podman network create --ipv6 podman_dual_stack
要将默认的无根网络更改为此网络,请设置 netns:
/etc/containers/containers.conf
[containers] netns = "podman_dual_stack"
存储
关于如何以及在何处存储容器镜像和实例的配置在 /etc/containers/storage.conf 中进行。
$XDG_CONFIG_HOME/containers/storage.conf 中添加对存储设置的覆盖。默认的 overlay 驱动程序经过了充分测试,并在支持它的文件系统(Btrfs、XFS、ZFS...)上支持 reflink 复制 [4] [5]。
有关可用替代方案和其他配置选项的更多信息,请参见 containers-storage.conf(5) § STORAGE_TABLE。
外来架构
Podman 能够使用 Wikipedia:binfmt_misc 系统运行为与宿主机不同的 CPU 架构构建的镜像。
要启用它,请安装 qemu-user-static 和 qemu-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-compose 或 podman-compose)的轻量封装。如果两者都已安装,docker-compose 优先。您可以使用 PODMAN_COMPOSE_PROVIDER 环境变量覆盖此行为。
如果您想使用 docker-compose,需要 启用 podman.socket 用户单元,并为该用户设置 docker 套接字环境变量:
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
使用 podman-compose 时不需要这样做,因为它会直接使用 podman。
- 如果您在 docker 中启用了 buildkit,则集成将无法工作。您需要通过设置
DOCKER_BUILDKIT=0环境变量来禁用 buildkit。 - podman-compose 存在兼容性问题,详见 [6]。
NVIDIA GPU
NVIDIA Container Toolkit 为 NVIDIA GPU 提供容器运行时。安装 nvidia-container-toolkit 软件包。它包含一个 pacman 钩子,可为您的 GPU 生成 CDI 规范并将其保存在 /etc/cdi/nvidia.yaml 中。
测试设置:
$ podman run --rm --gpus all archlinux nvidia-smi -L
带有重启策略的容器
要自动启动带有重启策略的容器,请 启用 podman-restart.service。
运行时
Podman 允许您使用不同的容器运行时,它们应该在很大程度上提供相同的功能和保证。
- runc:以前的默认运行时。
- crun:新的默认运行时。通常更可取,因为它比
runc更快。 - krun:一种特殊的 crun 运行时模式,它使用基于 KVM 的 krunvm 微型虚拟机来执行容器。与全功能 VM 相比,这些微型 VM 在几毫秒内启动并使用不同的内核。与在宿主机内核上运行的常规容器相比,这应该能提供更好的安全性。
- youkiAUR:用 Rust 编写的内存安全运行时。
要在替代运行时中启动单个命令,可以使用 --runtime,如下所示:
$ podman run --rm --runtime=krun archlinux uname -a
要永久更改,可以将其放入 containers.conf:
containers.conf
[engine] runtime = "krun"
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、.build 和 .pod 的 Quadlet 文件。将使用 systemd.generator(7) 生成相应的 .service 文件。Quadlet 文件在引导时或通过运行 daemon-reload 手动读取。
Quadlet 文件也可以使用 podlet 从 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
然后,daemon-reload 并 启动 syncthing-lsio.service。有关在没有打开会话的情况下启动无根容器的信息,请参见 systemd/User#systemd 用户实例的自动启动。
如果您想在引导时启动容器,请确保您的 网络管理器支持并已配置为 在网络上线后运行服务。
- 带有
[Install]部分的 Quadlet 文件生成的服务会自动 启用(生成器在/run/user/$UID/systemd/generator/目录中创建符号链接,参见 [8])。 - Quadlet 将通过向 systemd 单元添加
After=和Wants=属性,对network-online.target(作为 root)或podman-user-wait-network-online.service(作为用户)添加隐式依赖。这是为了确保在需要拉取镜像且容器启动时网络是可达的。详见 podman-systemd.unit(5) § Implicit network dependencies。
Container 部分的有效选项列在 podman-systemd.unit(5) § Container units [Container] 下。PodmanArgs= 可用于添加没有相应文件选项的其他 Podman 参数。
请参阅 podman-systemd.unit(5) § EXAMPLES 以获取更多示例,包括 Pod、Volume、Network 和 Image 单元。
镜像
/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 的系统)上运行时可能会出现错误和性能问题。示例请参见 [9]、[10] 和 [11]。
CentOS Stream
以下命令从 Quay 拉取最新的 CentOS Stream 镜像:
# podman pull quay.io/centos/centos
请参阅 Quay 页面获取每个 CentOS 版本的可用标签的完整列表。
Debian
以下命令从 Docker Hub 拉取最新的 Debian 镜像:
# podman pull docker.io/debian
请参阅 Docker Hub 页面获取可用标签的完整列表,包括每个 Debian 版本的标准版和精简版。
故障排除
向进程添加暂停
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 容器会停止。为防止这种情况,请为运行容器的用户 启用 lingering。
您还可以按照 podman-auto-update(1) § EXAMPLES 中的描述创建用户 systemd 单元。
无根模式下 commit 报错
Error committing the finished image: error adding layer with blob "sha256:02823fca9b5444c196f1f406aa235213254af9909fca270f462e32793e2260d8": Error processing tar file(exit status 1) permitted operation
检查存储驱动程序在 存储配置中是否为 overlay。
无根模式下创建带有桥接网络的容器时报错
如果您正在使用 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
未找到镜像
默认情况下,仓库列表未填充,因为软件包中的文件来自上游。这意味着默认情况下,尝试拉取任何镜像而不指定仓库会导致类似于以下的错误:
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 配置。
另一种不太方便但与未配置短名称的系统具有更高兼容性的替代方案是,在 Containerfile 或 Dockerfile 中使用完整的仓库路径。
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 denied 或 Authentication 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 Registry 服务器:
# 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
- 将
<dockerHubUsername>添加为 Docker Hub 仓库 Collaborators 选项卡中的协作者。
警告[0000] "/" 不是共享挂载,这可能导致无根容器出现问题或挂载缺失
以无根方式运行的 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 网络
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 规则阻塞。特别是,INPUT 或 FORWARD iptables 过滤链中的默认 DROP 策略和/或正在运行的防火墙(ufw, firewalld)在某些情况下会影响容器。如果您认为可能是这种情况,请检查您的配置(例如使用 iptables -L -n -v 或 nft list ruleset)。
注意,在 docker-compose.yml 发生更改后,使用 podman compose down 销毁环境时,创建的网络(来自 networks: 部分)可能不会被销毁。如果您的意图是销毁它们,请确保它们已被销毁(如有必要,使用 podman network ls 和 podman network rm)。
DNS 与名称解析
名称解析由 Podman 的子系统(例如 aardvark-dns)处理,它们提供外部 DNS(通常通过宿主机的 DNS 解析器)和容器名称解析(例如 webserver.dns.podman 与 database.dns.podman 通信)。
在上面的示例中,容器由 Podman 通过 /etc/resolv.conf 自动配置,以询问管道宿主机侧端口 53 上运行的 DNS 解析器。
container# cat /etc/resolv.conf
search dns.podman nameserver 10.89.0.1
检查您是否没有在宿主机上端口 53 上运行其他 DNS 解析器(例如 systemd-resolved 或 Unbound),因为它可能会干扰 Podman 名称解析。如果是这种情况,您可以将 Podman 在宿主机上使用的端口更改为任何其他可用端口,Podman 应该会自动将容器请求从容器转发到宿主机上的正确端口。
host# # cat /etc/containers/containers.conf
... dns_bind_port = 20053
内核不支持 overlay fs: 'overlay' 不支持该 <文件系统>
重新启动您的系统,如 General troubleshooting#内核升级后无法使用某些外设 中所述。