跳到主要内容
版本:3.7.0

自定义挂载、非特权容器部署

概述

Kubernetes 中,DaemonSet 是一种特殊的资源对象,用于确保集群中每个节点(Node)上都运行一个且仅一个 Pod 实例。 通过 DaemonSet 部署 SmartAgent,可自动在集群的所有节点完成部署,无需手动逐个节点安装。

本文提供三种挂载与权限策略,适配不同业务安全需求:

  • 挂载范围从最大到最小逐步缩减,安全性则逐步提升。
  • 三种模式均支持非特权容器(可通过 privileged 及 capabilities 设置控制)。

部署准备

请参阅 Kubernetes 部署(DaemonSet) 获取部署所需的所有文件。


挂载模式选择

  • 宿主机根目录以只读挂载,减少对宿主机文件系统的破坏风险
  • 仅安装目录、运行目录等必要路径为读写挂载
  • 容器运行时通过“简易裁剪”剔除不必要的系统目录(如 bootinitrdrootvmlinuz
  • 适用场景:一般生产环境,功能/安全平衡
注意
  • 安装目录和运行目录必须分别挂载,并且各级目录权限 ≥ 755
  • 在切换运行时目录或安装目录时,请将原有目录以读写挂载的方式挂载到容器中。
  • 如需非 root 账号运行,必须读写挂载 /etc 目录,否则会降级为 root 用户运行
kubernetes.yaml 关键片段
spec:
template:
spec:
hostPID: true # 用于识别宿主机上的进程列表,进入宿主机的 PID 命名空间
hostNetwork: true # 用于采集宿主机网络信息,进入宿主机的网络命名空间
volumes:
# 安装目录, 如需自定义,需与 SMARTAGENT_INSTALL_PATH 连用
- name: host-install-path
hostPath:
path: /opt
type: DirectoryOrCreate
# 【可选】 自定义运行目录,需与 SMARTAGENT_RUNTIME_PATH 连用
# 请勿和安装目录使用同一目录
#- name: custom-runtime-path
# hostPath:
# path: /data/lib/bonree
# type: DirectoryOrCreate
# 【不可删除】即使使用自定义运行目录,默认的运行目录挂载也不可删除
- name: host-runtime-path
hostPath:
path: /var/lib/bonree
type: DirectoryOrCreate
- name: host-crio-containers
hostPath:
path: /usr/share/containers
- name: host-etc
hostPath:
path: /etc
- name: host-root
hostPath:
path: /
- name: container-tmp-dir
emptyDir: {}
- name: container-mnt
emptyDir: {}
containers:
- name: bonree-smartagent
securityContext:
#【1.1】开始支持只读容器
readOnlyRootFilesystem: true
privileged: true
env:
#【可选】安装目录路径(默认 /opt)。可根据实际部署需求自定义。
# 注意:该路径需与宿主机路径一致,并挂载为可读写;且所有目录层级权限须不低于 755。
- name: SMARTAGENT_INSTALL_PATH
value: "/opt"
#【可选】【1.1】自定义运行数据目录(默认 /var/lib),支持指定自定义路径。
# 注意:该路径需与宿主机路径一致,并挂载为可读写;且所有目录层级权限须不低于 755。
#- name: SMARTAGENT_RUNTIME_PATH
# value: "/data/lib"
volumeMounts:
# 安装目录, 如需自定义,需与 SMARTAGENT_INSTALL_PATH 连用
- name: host-install-path
mountPath: /mnt/root/opt
readOnly: false
# 【可选】 自定义运行目录,需与 SMARTAGENT_RUNTIME_PATH 连用
# 请勿和安装目录使用同一目录
#- name: custom-runtime-path
# mountPath: /mnt/root/data/lib/bonree
# readOnly: false
- name: host-crio-containers
mountPath: /mnt/root/usr/share/containers
readOnly: false
# 【可选】只读根挂载场景下,需读写挂载 /etc,用于创建非root用户运行smartagent服务进程。
# 如不挂载读写/etc,则需指定宿主机上已存在的用户,否则将退化为使用 root 用户运行
- name: host-etc
mountPath: /mnt/root/etc
readOnly: false
# 【不可删除】即使使用自定义运行目录,默认的运行目录挂载也不可删除
- name: host-runtime-path
mountPath: /mnt/root/var/lib/bonree
readOnly: false
- name: host-root
mountPath: /mnt/root
readOnly: true
- name: container-tmp-dir
mountPath: /tmp/apm
readOnly: false
- name: container-mnt
mountPath: /mnt
readOnly: false

非特权容器部署

无论容器是否以特权模式运行,SmartAgent 在启动时都会主动收缩探针服务进程的权限范围,并使用指定用户运行探针进程,仅保留运行所需的最小 Linux Capabilities 权限集合,以最大程度提升安全性。

在部署 YAML 配置时,您也可以通过 securityContext.capabilities 参数预先收紧容器的初始权限集合,从而在容器启动阶段就实现更严格的安全控制。

从 SmartAgent 镜像版本 1.1SmartAgent 版本 9.7.0 开始,支持按功能模块拆分所需的 Capabilities,并能根据容器实际具备的权限自动启用相应功能。

kubernetes.yaml 配置文件片段
          env:
#【可选】容器运行时,是否禁止二次裁剪挂载,默认为 false
# 当容器无 SYS_ADMIN 特权时,不支持进行进一步缩减宿主机挂载,需配置该参数为 true
#- name: SMARTAGENT_NO_REMOUNT_ROOT
# value: "false"
securityContext:
privileged: false
# 非 root 运行模式:必须设置 allowPrivilegeEscalation=true,用于保留应用运行所需的最小特权集。
# 如果设置为 false,则仅支持 root 模式运行,
# 且需显式设置启动参数:--non-root-mode false 以 root 身份运行探针服务。
allowPrivilegeEscalation: true
#【1.1】开始支持只读容器
readOnlyRootFilesystem: true
capabilities:
drop: [ "ALL" ] # 先移除所有默认权限
add:
- "CHOWN"
- "DAC_OVERRIDE"
- "DAC_READ_SEARCH"
- "FOWNER"
- "FSETID"
- "SYS_RESOURCE"
- "SYS_CHROOT"
- "SYS_ADMIN" # 从9.7.0 开始可选去除 不使用该特权时,需同时设置环境变量 SMARTAGENT_NO_REMOUNT_ROOT: true
- "SYSLOG" # 从9.7.0 开始可选去除
- "NET_ADMIN" # 从9.7.0 开始可选去除
- "NET_RAW" # 从9.7.0 开始可选去除
- "NET_BROADCAST" # 从9.7.0 开始可选去除
- "KILL" # 从9.7.0 开始可选去除(不影响任意功能)
- "SETFCAP" # 从9.7.0 开始可选去除
- "SETGID" # 从9.7.0 开始可选去除
- "SETUID" # 从9.7.0 开始可选去除
- "SYS_PTRACE" # 从9.7.0 开始可选去除

使用非特权容器的影响

默认情况下镜像包含完整能力集合,但在非特权模式下运行时,部分功能可能会受到限制。

在启用非特权容器运行后,由于权限受限,将导致以下影响:

  • 无法访问内核日志 /dev/kmsg,因此将无法监控并上报部分主机级故障事件,包括:
  • PodOOMKilling:Pod 因内存超限被系统 OOM Killer 杀死;
  • OOMKilling:系统触发 OOM,杀死进程;
  • TaskHung:内核检测到进程长时间阻塞;
  • ReadonlyFilesystem:文件系统被重新挂载为只读。

特权位说明

CAP_SETUID、CAP_SETGID
  • 用途:用于使用 setresuid() 函数切换为非 root 用户运行探针进程。
  • 使用频次:一次性
  • 是否必须
  • 无特权时影响:将以 root 运行探针进程。
CAP_SETFCAP
  • 用途:在探针初始化阶段用于为组件赋予最小所需权限,进一步缩小权限范围。通过使用 libcap.socap_set_flag() 设置。
  • 使用频次:一次性
  • 是否必须
  • 无特权时影响:组件权限无法细化,退化为使用 root 运行探针进程。以下功能不可用:
    • APM 探针自动注入
CAP_SYS_PTRACE
  • 用途:用于通过 /proc 提取进程信息,监控新容器创建、日志采集、profiling 时使用。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • 容器相关属性及指标采集
    • APM 探针自动注入
    • 网络性能分析
    • eBPF 剖析
    • 主机故障事件采集
    • 应用日志自动发现
CAP_DAC_OVERRIDE、CAP_FOWNER、CAP_DAC_READ_SEARCH
  • 用途:绕过文件权限,访问日志、系统文件、容器信息文件等。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • 应用自动发现
    • 容器信息采集
    • 容器指标采集
    • APM 探针自动注入
    • 网络性能分析
    • eBPF 剖析
    • 主机故障事件采集
CAP_CHOWN、CAP_FSETID
  • 用途:设置探针文件权限。
  • 使用频次:一次性
  • 是否必须
  • 无特权时影响:切换运行用户等情况下,会导致探针相关文件落盘失败,运行异常等。
CAP_SYS_CHROOT
  • 用途:容器启动过程中,chroot 至裁剪后的虚拟宿主机根目录,运行探针。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • SmartAgent 容器无法启动(由于无法 chroot 至容器内构造的虚拟宿主机根路径运行探针)
CAP_SYS_RESOURCE
  • 用途:控制 agent 或探针资源占用、去除 BPF 限制。如通过 setrlimit() 函数。
  • 使用频次:一次性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • 网络性能分析
    • eBPF 剖析
    • 主机故障事件采集
CAP_NET_ADMIN、CAP_NET_RAW、CAP_NET_BROADCAST
  • 用途:eBPF 网络探针启用时需要。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • 网络性能分析
    • eBPF 剖析
    • 主机故障事件采集
CAP_SYSLOG
  • 用途:访问 /dev/kmsg 获取内核调用栈。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响:以下功能不可用:
    • eBPF 剖析
CAP_SYS_ADMIN
  • 用途:用于使用 setns() 切换至目标容器的网络空间进行采集网卡信息。用于使用 mount() 挂载探针至目标容器中。用于 eBPF 探针使用 bpf 相关函数。
  • 使用频次:持续性
  • 是否必须
  • 无特权时影响
    • 不支持APM探针自动注入、网络性能分析、eBPF剖析、主机故障事件采集。
      • 关于 APM 探针自动注入,可使用 SmartAgent Operator 中的仅监控应用模式代替。
    • 不支持最小宿主挂载模式中的二次裁剪(仅支持 yaml 中配置只读挂载),且需要增加环境变量: SMARTAGENT_NO_REMOUNT_ROOT: true,方可正常启动容器。
    • 不支持 Kubernetes 属性增强(由于无权限执行mount,导致Kubernetes serviceaccount token无法进行转移挂载,故相关功能受限:如logsagent根据annotations、labels过滤采集日志、pod ip、service name属性提取。
    • 不支持 configmap 修改配置文件