一个Pod缺少capabilities带来的小问题

前段时间,有团队的同学在边缘服务器上遇到问题,最终定位和Linux Capabilities有关,定位过程并不复杂,回顾过往算是第二次遇到类似问题,所以还是打算记录下来。

问题背景

业务有部署在客户侧的边缘服务器,我们会将服务通过云端控制下发到边缘服务器上,这些下沉的业务服务均以容器化的方式进行部署和管理。

在一个业务场景中,会在客户侧的边缘服务器插入一个硬件外设,业务服务初始化时调用厂商脚本安装外设驱动,但是在测试的过程中发现驱动安装一直失败,提示如下异常:

由于厂商脚本底层SDK未提供源码,无法通过源码进行问题定位,所以研发同学在这个问题上花了不少时间。

问题分析

从报错信息来看,问题点很好判断,脚本内会进行insmod/rmmod操作失败,提示的异常是Operation not permitted

看到这里,可能首先想到的就是权限不够,但是初步排查即使以root用户身份执行该脚本,也提示相同的异常信息,所以我们当时就想到应该是容器本身不具备某些资源或者权限。

但是这就让研发同学比较抓瞎,没有源码也不好判断具体缺少哪个行为或者权限。

这就到了掐指一算的环节了。

因为涉及到权限、资源层面的使用,大部分都需要通过系统调用进行操作,抛出的Operation not permitted大概率也是系统调用本身返回了无权限,因此只要看哪一个系统调用返回异常就可以了。

那就是时候掏出strace了。

最终发现是delete_module返回了Operation not permitted,追踪一下源码,很快可以找到问题根因。

执行delete_module需要判断是否具备CAP_SYS_MODULE能力,如果不具备则返回-EPERM,提示Operation not permitted

那么要解决这个问题,我们需要了解两个东西:

(1)CAP_SYS_MODULE是什么? --- Linux Capabilities (2)如何让容器具备这个能力? --- Pod Security Context

Linux Capabilities

为了能够进行权限检查,传统的UNIX将进程分为特权进程和非特权进程,其中特权进程可以绕过所有内核权限检查直接执行对应的操作,而非特权进程则需要根据进程认证和权限信息进行判断。

从Linux 2.2开始将超级用户的特权拆分成不同的单元,这些权能单元就是Linux Capabilities

官方文档
capabilities(7) - Linux manual page

CAP_SYS_MODULE就是Linux Capabilities中的一种,包含模块加载和卸载相关的权限能力。

Capabilities分配

既然将特权拆分成不同的Capabilities模块,那么就可以按需进行Capabilities分配,配置方式包含线程权能集(Thread Capabilities Sets)和文件权能集(File Capabilities),而两种权能集各有其分配计算方式、继承规则,最终共同作用决定是否具备权限进行操作。

其中,文件权能集从Linux 2.6.24开始支持。

  • Thread Capabilities Sets

每个进程都以下的几种权能集合,每个集合包含0到多个不同的权能。

类型 说明
Permitted 进程可获取的权限
Inheritable 从父进程继承传递给子进程的权限
Effective 进程的有效权限,内核基于该集合进行权限检查 (可以理解为最终真正生效的权限集)
Bounding 进程允许拥有的最大权限集 (Since Linux 2.6.25,在此之前是一个系统级属性限制所有线程)
Ambient 当前生效的权限,应用于非特权程序的当前进程或子进程

其中,通过fork()创建的子进程继承父进程的权能集。

  • File Capabilities

从Linux 2.6.24后,内核支持为一个可执行文件设置权能集,保存在security.capability中。

类型 说明
Permitted 当文件执行时,自动添加给进程的权能集
Inheritable 该集合与线程Inheritable集做与&操作,以确定进程哪些权能可被继承
Effective 非集合,仅是一个bit位。为1时进程Permitted集才可添加到进程Effective集中
  • 权能计算方式

有了进程和文件权能集,那么实际执行一个新的程序时,也有其对应的权限计算方式。

Pod Security Context

安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置,其中就包含Linux权能,能为进程赋予 root 用户的部分特权而非全部特权。

Kubernetes 为 Pod 或容器配置安全上下文

可针对Pod或容器层面进行配置,容器层面的官方配置示例如下:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-4
spec:
  containers:
  - name: sec-ctx-4
    image: xxxx:1.0
    securityContext:
      capabilities:
        add: ["NET_ADMIN", "SYS_TIME"]

因此,结合我们的场景,只需要给容器增加对应的权能即可。

解决方案

要解决这个问题,只需要给对应的容器增加SYS_MODULE权能即可。

yaml 复制代码
....
spec:
  containers:
  - name: xxxx
    image: xxxx:1.0
    securityContext:
      capabilities:
        add: ["SYS_MODULE"]
....

这里注意,源码中的权能名是CAP_SYS_MODULE,但是实际在securityContext的时候对应权能名位SYS_MODULE

问题总结

综上所述,实际为容器不具备对应的权能,导致硬件外设驱动安装失败,只要加上SYS_MODULE权能即可。

但是实际上,驱动安装这个行为也并不适合在容器中完成,应该在服务器初始化阶段进行安装,将基础环境初始化与服务部署两个行为解耦开。

相关推荐
阳光是sunny7 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
灯澜忆梦7 小时前
GO_并发编程---定时器
开发语言·后端·golang
阳光是sunny7 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
皮皮林5518 小时前
开源实力派,给本地 AI 装上深度调研能力,一张 3090 跑到 95.7 分!
后端
努力的小雨8 小时前
把 Windows 桌面图标做成一个会自己运转的小世界
后端
武子康9 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
IT_陈寒11 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学11 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈11 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端