golang 的 timer 在调整系统时间下的行为
目录
文章简介:golang 的 timer 在调整系统时间下的行为
在测试 k3s 重启自动续签证书时,发现手动调整机器时间后,calico Unauthorized,pod 因无法创建 network sandbox 无法启动,且可以看到 calico-node -monitor-token
没有执行。
calico-node -monitor-token
是 calico 后台刷新证书的程序,,每次刷新都会 time.After max(nextExpiration/4, 5s*4)。但是实测下来,直接手工调整时间后,calico 并没有主动重新申请 token,这里涉及到 time.After 的工作机制。
linux 时间有 CLOCK_REALTIME_COARSE
(墙上时钟) 和 CLOCK_MONOTONIC_COARSE
(单调时钟),这两种时钟详细解释见 这里。
从 golang 中找到的代码看到 time.After 调用栈见:
|
|
可以看到 golang 中的 timer.Timer 使用的是 CLOCK_MONOTONIC_COARSE 也即单调时钟,date 命令调整时间并不会体现在这里获得到的时间,所以调整时间并不会让 calico 按照墙上时钟快速触发。
问题确认即可快速确认方案,如果为了规避时间问题,可以只重启 k3s 即可,如果期望可以快速使用 date 调整时间 calico 快速恢复,可以考虑重启 calico-node 进程重新生成 kubeconf。
golang issue 12914 中讨论了 nanotime 第三方无法调用,以及当前的进展。当前如果希望获得 单调时钟,可以参考 这个