首页 / Kubernetes (k8s) 入门教程 / 安全上下文(securityContext)

Kubernetes (k8s) 入门教程

安全上下文(securityContext)

本教程共 65 篇 · 第 16 篇 · 更新于 2026-08-14 · 约 11 分钟阅读

KubernetessecurityContext安全上下文capabilities非root容器安全

本节目标:学完你能给 Pod 或容器配安全上下文,让它默认以非 root 用户运行,并收掉不必要的 Linux 权能,缩小被攻破后的破坏面。

容器里程序默认常是 root 用户。一旦被攻破,攻击者在容器里就是 root,危害大得多。安全上下文(securityContext)就是给容器”降权”的开关。

16-1 安全上下文是什么

securityContext 定义 Pod 或容器的特权与访问控制。它管的事包括:以哪个用户/组运行、能不能用特权模式、有哪些 Linux 权能、根文件系统是否只读、系统调用是否被过滤。

它的作用范围有两层:写在 Pod 上,对所有容器生效;写在某个容器上,只管那个容器。容器级的设置会覆盖 Pod 级的同名项。

Note

满足 Pod 安全标准,越往上越严:Baseline 档最基本的动作是”禁用特权容器”;Restricted 档才强制”以非 root 运行”(详见第 46 章)。

16-2 以什么用户运行

最常见的一组字段是用户和组。

runAsUser:容器里进程的 UID。设成 1000 之类非 0 值,就是非 root。

runAsGroup:进程所属的 GID。

runAsNonRoot:设为 true 时,如果镜像强行用 root(UID 0)启动,kubelet 直接拒绝运行。这是道硬保险。

fsGroup:Pod 里卷的属组,让容器能以这个组读写挂载的存储。

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    runAsNonRoot: true
    fsGroup: 2000

这段意思是:容器进程以 UID 1000、GID 3000 跑,且绝不能是 root。

Tip

镜像本身要支持非 root。有些镜像写死了 root 路径(比如监听 80 以下端口),强行降权会起不来。改端口或调镜像才是正解。

16-3 Linux 权能 capabilities

root 之所以强,是因为它默认带着一整套”权能(capabilities)“。安全上下文可以精确地加减这些权能。

capabilities.add:给容器加某个权能,比如 NET_ADMIN 才能配网络。

capabilities.drop:去掉某个权能。安全上更推荐”默认全 drop,按需 add”。

privileged:设为 true 等于把所有权能、所有设备都给容器,等同于节点上的 root。极危险,非系统级程序别开。

securityContext:
  capabilities:
    drop:
    - ALL
    add:
    - NET_BIND_SERVICE

NET_BIND_SERVICE 让非 root 也能绑 1024 以下的端口。去掉其余全部权能,攻击面大幅缩小。

16-4 再收几道门

还有几个字段值得一设。

readOnlyRootFilesystem:根文件系统只读。设为 true 后,容器无法往系统目录写东西,挡掉很多篡改手法。需要写文件请挂卷。

allowPrivilegeEscalation:是否允许提权。设为 false 会开启 no_new_privs 内核标志,禁止程序通过 setuid 升到 root。特权容器或带 CAP_SYS_ADMIN 时它强制为 true。

seccompProfile:过滤系统调用。用 RuntimeDefault 就能挡掉一大票危险 syscall,性价比很高。

securityContext:
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  seccompProfile:
    type: RuntimeDefault
Warning

privileged: true 千万别随手开。它等于把节点的一部分控制权交给容器,生产环境基本只在 CNI、存储插件这类系统组件才用。

16-5 一份较安全的清单

把上面合起来,一个”够安全”的 Pod 长这样:

apiVersion: v1
kind: Pod
metadata:
  name: secure-demo
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:1.0
    securityContext:
      runAsUser: 1000
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL

16-6 常见坑

一是容器起不来,报 permission denied。多半是降权后程序要写系统目录、绑低端口。要么挂卷,要么加 NET_BIND_SERVICE

二是 runAsNonRoot 和镜像写死 root 打架。镜像里 USER root 的话,记得改镜像或设 runAsUser 覆盖。

三是只在 Pod 级设了,以为容器也生效。其实某些字段(如 privileged)只在容器级有意义。

Note

securityContext 是”减权限”,Pod 安全标准(PSA)是”集群级强制”。后者在第 46 章讲,它能在你忘了配的时候兜底。

Pod 本身讲得差不多了。接下来进入工作负载:怎么让 Pod 自动多副本、自愈、滚动更新。第 17 章先讲最朴素的 ReplicaSet。