新的 Netavark firewalld 重新加载服务

Podman 的一个长期存在的问题是,您的 rootful 容器在一段时间后可能会失去网络连接。对于许多用户来说,导致此类问题的原因并不明显。Netavark 配置 NAT 和端口转发防火墙规则。当另一个进程删除我们的防火墙规则时,容器将失去连接。其中一个这样的进程是 firewalld,当执行 firewall-cmd –reload 时,它会删除所有防火墙规则,然后只添加 firewalld 已知的规则,导致 Podman 容器没有连接。有趣的是,这个命令甚至可能不需要用户执行。有些应用程序会在更新时运行此命令,例如,dnf update 可能会导致 firewalld 重新加载,这使得用户更难知道发生了什么。注意:从 firewalld 2.0 开始,它可能不再刷新所有规则,而只刷新 firewalld 特定的规则。

恢复规则的一种解决方案是简单地重启容器,因为所有必要的规则都会在容器启动时添加。然而,这是不可取的,因为一些容器应用程序可能需要很长时间才能停止和/或启动。为了解决这个问题,Podman 很早以前就添加了 podman network reload 命令。此命令会删除然后重新添加网络配置。它最近运行良好,但仍然存在一个大问题:该命令需要在规则丢失后明确执行。因此,它不会帮助那些不知道规则何时丢失的用户。

通过 netavark v1.9.0,我们添加了一个新的 systemd 服务,名为 netavark-firewalld-reload.service,它应该一劳永逸地解决这个问题。此服务运行一个小型 netavark 命令,该命令在 dbus 上监听 firewalld 重新加载事件。每当 firewalld 重新加载并清除了 netavark 防火墙规则时,就会发出此事件。如果收到事件,服务将重新添加所有 netavark 防火墙规则。

新的 systemd 服务设计成只有当 firewalld 本身也在运行时才运行,以避免在不需要时消耗资源。以下示例展示了如何启用此服务。

首先我们启用服务,注意启用并不一定意味着开机启动。对于我们的单元,我们为 firewalld 添加了一个 wants,这意味着服务只在 firewalld 启动时启动。这确保了在不使用或禁用 firewalld 的系统上,它不会不必要地运行。当 firewalld 停止时,服务也会停止。

$ sudo systemctl enable netavark-firewalld-reload.service
Created symlink /etc/systemd/system/firewalld.service.wants/netavark-firewalld-reload.service → /usr/lib/systemd/system/netavark-firewalld-reload.service.

现在重启 firewalld,看看我们的服务是否也会随之启动。或者,直接启动我们的服务或重启,前提是 firewalld 已启用。

$ sudo systemctl restart firewalld.service
$ sudo systemctl status netavark-firewalld-reload.service 
● netavark-firewalld-reload.service - Listen for the firewalld reload event and reapply all netavark firewall rules.
     Loaded: loaded (/usr/lib/systemd/system/netavark-firewalld-reload.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Mon 2023-11-13 18:00:17 CET; 22s ago
   Main PID: 72763 (netavark)
      Tasks: 3 (limit: 38149)
     Memory: 15.4M
        CPU: 9ms
     CGroup: /system.slice/netavark-firewalld-reload.service
             └─72763 /usr/libexec/podman/netavark firewalld-reload

Nov 13 18:00:17 pholzing-fedora systemd[1]: Started netavark-firewalld-reload.service - Listen for the firewalld reload event and reapply all netavark firewall rules..

让我们启动一个简单的 Web 服务器,看看它是否工作。

$ sudo podman run -dt -p 8080:80 docker.io/library/nginx
52f2c11810d78f69287874e2469d4caec99176b583e378732cee4623cbd09476
$ curl -s 127.0.0.1:8080 | head -n4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
$ sudo firewall-cmd --reload 
success
$ curl -s 127.0.0.1:8080 | head -n4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

如果没有该服务,在 firewalld 重新加载命令之后的 curl 命令将一直挂起。这表明 netavark-firewalld-reload.service 确实按预期工作。

请注意,这是 netavark 特有的功能,如果您仍然使用旧的 CNI 后端,它将不起作用。
尝试新的服务,如果您遇到任何问题,请在 netavark github 仓库 上报告问题。

对“新的 Netavark firewalld 重新加载服务”的一条回复

  1. Annonymous Avatar

    nftables(firewalld 的底层基础设施)中解决了原子性问题。

回复 匿名取消回复

订阅

输入您的电子邮件地址以接收来自本网站的电子邮件更新。

返回

您的消息已发送

警告
警告
警告。

分类


搜索