背景

在统一发布平台中,Jenkins 通过 GitLab OAuth Plugin 实现单点登录,并结合 Matrix Authorization Strategy Plugin 在 Folder 级别启用 Enable project-based security,实现项目矩阵授权。

在实际使用中,发现一个明显的问题:

GitLab 子群组(subgroup)无法作为授权主体使用

具体表现为:

  • GitLab 中存在如下群组结构:
group1
└── subgroup1
  • 在 Jenkins Folder → 权限配置中添加群组:
group1/subgroup1
  • Jenkins 校验时报错:
java.lang.NullPointerException: Cannot invoke "org.gitlab4j.api.models.Group.getName()" because "this.gitlabGroup" is null

添加子群组报错:

image-20260121161110286.png

- 阅读剩余部分 -

建设目标

构建一个 统一、规范、安全、可扩展 的发布平台,满足以下目标:

  • 支持多项目并行使用,项目之间权限严格隔离
  • 通过 GitLab 单点登录,避免用户双重维护
  • 权限最小化,授权清晰
  • 项目自治,减少平台管理员日常介入成本
  • 支持项目规模扩展(用户 200+、项目数持续增长)

总体架构

核心组件

组件作用
GitLab用户身份源、组管理、代码仓库
Jenkins统一发布平台
Jenkins插件:GitLab Authentication plugin实现 GitLab SSO 登录
Jenkins插件:Matrix Authorization Strategy Plugin实现细粒度授权(全局 / 文件夹 / Job)
Jenkins插件:Folder Plugin按项目文件夹隔离,方便权限管理

认证与用户管理设计

GitLab 单点登录(SSO)

  • Jenkins 不本地维护任何用户
  • 所有用户通过 GitLab OAuth 登录 Jenkins
  • Jenkins 用户名 = GitLab username(保持唯一性)

- 阅读剩余部分 -

关键词:libfaketime、时间模拟

在测试时间相关逻辑(证书过期、订单超时、定时任务、跨年问题)时,很多人第一反应是:能不能只改一个程序/进程的时间,而不影响宿主机?

结论很明确:

不能直接改。

在容器/Pod 环境中也存在同样的需求,甚至需求更强烈,因为 Kubernetes 中,宿主机往往不会只运行一个业务程序,修改系统时间所造成的影响可能是无法预估的。

Linux 内核只有一份系统时间,容器共享内核,不存在所谓的 Time Namespace

于是,libfaketime 成为了容器环境中最常被提及的“替代方案”。本文将结合主流编程语言获取时间的 Demo 来验证 libfaketime 的实际效果:

  • libfaketime 能做什么、不能做什么
  • 为什么有的语言生效、有的完全无效
  • Java 为什么必须额外配置

libfaketime 是什么,它解决了什么问题

libfaketime 并不是修改系统时间,而是:

通过 LD_PRELOAD 劫持部分 libc 的时间函数,让进程“认为”时间发生了变化

- 阅读剩余部分 -

背景

在使用 gotty 这类基于 WebSocket 的 Web Terminal 工具时,遇到一个问题:

  • 浏览器打开页面后,WebSocket 连接一切正常
  • 切换到其他浏览器标签页(Tab),停留一段时间
  • 再切回原 Tab,发现 WebSocket 已断开

gotty 日志:

2026/01/13 01:06:16 New client connected: 10.42.2.8:41704, connections: 1/0
2026/01/13 01:12:18 Connection closed by client: 10.42.2.8:41704, connections: 0/0

更有意思的是:

  • 本地调试(localhost / 内网)几乎不会复现
  • 通过公网访问时,问题稳定出现

浏览器切换 Tab 的影响

第一反应是怀疑浏览器行为。通过简单验证可以确认:

  • 浏览器会对后台页面进行 JS 执行节流 / 暂停(可以通过浏览器的开发者工具,查看WebSocket的数据交互)
  • setInterval / setTimeout 的触发频率被大幅拉长,甚至完全暂停(取决于浏览器的行为)

如果 WebSocket 的心跳依赖前端 JS 定时器,那么在后台 Tab 场景下:

心跳不再发送,连接会逐渐变成“空闲连接”

- 阅读剩余部分 -

背景

近期在一套 Kubernetes 集群中,发现一个非常反常的现象

  • 在节点上执行 netstat / ss 命令异常缓慢,甚至需要几分钟才能返回结果
  • 节点本身负载并不高,CPU、内存看起来都比较正常

由于 netstat/ss 本质上只是读取内核和 /proc 信息,这种“卡死级别”的慢速,往往意味着 系统层面存在异常规模的数据结构

这篇文章记录了从一个看似普通的 netstat 慢问题,一步步定位到 Calico socket FD 泄漏 Bug,并最终通过升级版本彻底解决的完整过程。


从 netstat/ss 变慢开始

最初的直接表现是:

time netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:10010         0.0.0.0:*               LISTEN      1530975/cri-dockerd 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1165/sshd: /usr/sbi 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      164980/nginx: worke 
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd           
tcp        0      0 127.0.0.1:9099          0.0.0.0:*               LISTEN      1171111/calico-node 
tcp        0      0 0.0.0.0:20048           0.0.0.0:*               LISTEN      2503623/rpc.mountd  
tcp        0      0 0.0.0.0:2049            0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:10256         0.0.0.0:*               LISTEN      623016/kube-proxy   
tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      1531381/kubelet     
tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      623016/kube-proxy   
tcp        0      0 0.0.0.0:57325           0.0.0.0:*               LISTEN      2500368/rpc.statd
tcp        0      0 0.0.0.0:46433           0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      1165/sshd: /usr/sbi 
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd           
tcp6       0      0 :::20048                :::*                    LISTEN      2503623/rpc.mountd  
tcp6       0      0 :::2049                 :::*                    LISTEN      -                   
tcp6       0      0 :::2380                 :::*                    LISTEN      619966/etcd         
tcp6       0      0 :::2379                 :::*                    LISTEN      619966/etcd         
tcp6       0      0 :::40007                :::*                    LISTEN      -                   
tcp6       0      0 :::6443                 :::*                    LISTEN      621032/kube-apiserv 
tcp6       0      0 :::9369                 :::*                    LISTEN      2484838/pushprox-cl 
tcp6       0      0 :::9796                 :::*                    LISTEN      2485357/node_export 
tcp6       0      0 :::10250                :::*                    LISTEN      1531381/kubelet     
tcp6       0      0 :::10259                :::*                    LISTEN      621666/kube-schedul 
tcp6       0      0 :::10257                :::*                    LISTEN      621333/kube-control 
tcp6       0      0 :::48607                :::*                    LISTEN      2500368/rpc.statd   

real    3m21.534s
user    3m9.634s
sys     0m11.357s

可见执行非常慢。

- 阅读剩余部分 -