读懂这一篇,集群节点不下线(16)

  • 对于 dbus1 来说 , cookie 是 32 位的 , 这个值在经过 systemd 三五个月频繁创建删除 Unit 之后 , 是肯定会溢出的;

  • 而 dbus2 的 cookie 是 64 位的 , 可能到了时间的尽头它也不会溢出 。

另外一个原因是 , 我们并不能简单的让 cookie 折返 , 来解决溢出问题 。 因为这有可能导致 systemd 使用同一个 cookie 来加封不同的消息 , 这样的结果将是灾难性的 。

最终的修复方法是 , 使用 32 位 cookie 来同样处理 dbus1 和 dbus2 两种情形 。 同时在 cookie 达到 0xfffffff 之后的下一个 cookie 返回 0x80000000 , 用最高位来标记 cookie 已经处于溢出状态 。 检查到 cookie 处于这种状态时 , 我们需要检查是否下一个 cookie 正在被其他 message 使用 , 来避免 cookie 冲突 。

后记

这个问题根本原因肯定在 systemd , 但是 runC 的函数 UseSystemd 使用不那么美丽的方法 , 去测试 systemd 的功能 , 这个函数在整个容器生命周期管理过程中 , 被频繁地触发 , 让这个低概率问题的发生成为了可能 。 systemd 的修复已经被红帽接受 , 预期不久的将来 , 我们可以通过升级 systemd , 从根本上解决这个问题 。

推荐阅读