Kubernetes指南
Linux性能优化实战eBPF 核心技术与实战SDN指南个人博客
中文
中文
  • 序言
  • 基础入门
    • Kubernetes 简介
    • Kubernetes 基本概念
    • Kubernetes 101
    • Kubernetes 201
    • Kubernetes 集群
  • 核心原理
    • 核心原理
    • 架构原理
    • 设计理念
    • 核心组件
      • etcd
      • kube-apiserver
      • kube-scheduler
      • kube-controller-manager
      • kubelet
      • kube-proxy
      • kube-dns
      • Federation
      • kubeadm
      • hyperkube
      • kubectl
    • 资源对象
      • Autoscaling
      • ConfigMap
      • CronJob
      • CustomResourceDefinition
      • DaemonSet
      • Deployment
      • Gateway API
      • Ingress
      • Job
      • LocalVolume
      • Namespace
      • NetworkPolicy
      • Node
      • PersistentVolume
      • Pod
      • PodPreset
      • ReplicaSet
      • Resource Quota
      • Secret
      • SecurityContext
      • Service
      • ServiceAccount
      • StatefulSet
      • Volume
  • 部署配置
    • 部署指南
    • kubectl 安装
    • 单机部署
    • 特性开关
    • 最佳配置
    • 版本支持
    • 集群部署
      • kubeadm
      • kops
      • Kubespray
      • Azure
      • Windows
      • LinuxKit
      • kubeasz
    • 附加组件
      • Addon-manager
      • DNS
      • Dashboard
      • 监控
      • 日志
      • Metrics
      • GPU
      • Cluster Autoscaler
      • ip-masq-agent
    • Kubernetes-The-Hard-Way
      • 准备部署环境
      • 安装必要工具
      • 创建计算资源
      • 配置创建证书
      • 配置生成配置
      • 配置生成密钥
      • 部署 Etcd 群集
      • 部署控制节点
      • 部署计算节点
      • 配置 Kubectl
      • 配置网络路由
      • 部署 DNS 扩展
      • 烟雾测试
      • 删除集群
  • 插件扩展
    • API 扩展
      • Aggregation
      • CustomResourceDefinition
    • 访问控制
      • 认证
      • RBAC 授权
      • 准入控制
    • Scheduler 扩展
    • 网络插件
      • CNI
      • Flannel
      • Calico
      • Weave
      • Cilium
      • OVN
      • Contiv
      • SR-IOV
      • Romana
      • OpenContrail
      • Kuryr
    • 运行时插件 CRI
      • CRI-tools
      • Frakti
    • 存储插件
      • 容器存储接口 CSI
      • FlexVolume
      • glusterfs
    • 网络策略
    • Ingress Controller
      • Ingress + Letsencrypt
      • minikube Ingress
      • Traefik Ingress
      • Keepalived-VIP
    • Cloud Provider 扩展
    • Device 插件
  • 服务治理
    • 服务治理
      • 一般准则
      • 滚动升级
      • Helm
      • Operator
      • Service Mesh
      • Linkerd
      • Linkerd2
    • Istio
      • 安装
      • 流量管理
      • 安全管理
      • 策略管理
      • 度量管理
      • 排错
      • 社区
    • Devops
      • Draft
      • Jenkins X
      • Spinnaker
      • Kompose
      • Skaffold
      • Argo
      • Flux GitOps
  • 实践案例
    • 实践概览
    • 资源控制
    • 集群高可用
    • 应用高可用
    • 调试
    • 端口映射
    • 端口转发
    • 用户管理
    • GPU
    • HugePage
    • 安全
    • 审计
    • 备份恢复
    • 证书轮换
    • 大规模集群
    • 大数据与机器学习
      • Spark
      • Tensorflow
    • Serverless
  • 排错指南
    • 排错概览
    • 集群排错
    • Pod 排错
    • 网络排错
    • PV 排错
      • AzureDisk
      • AzureFile
    • Windows 排错
    • 云平台排错
      • Azure
    • 排错工具
  • 社区贡献
    • 开发指南
    • 单元测试和集成测试
    • 社区贡献
  • 附录
    • 生态圈
    • 学习资源
    • 国内镜像
    • 如何贡献
    • 参考文档
由 GitBook 提供支持
在本页
  • Container-level Security Context
  • Pod-level Security Context
  • Supplemental Groups Policy(补充组策略)
  • 背景:容器镜像中的隐式组成员身份
  • supplementalGroupsPolicy 字段
  • 示例:使用 Strict 策略
  • CRI 运行时要求
  • Beta 版本的行为变化
  • Pod 状态中的进程身份信息
  • User Namespaces(用户命名空间)
  • 启用用户命名空间
  • 安全优势
  • 系统要求
  • 兼容性说明
  • 示例配置
  • Pod Security Policies(PSP)
  • API 版本对照表
  • 支持的控制项
  • 示例
  • SELinux
  • 开启与关闭 SELinux
  • 示例
  • 参考文档
  1. 核心原理
  2. 资源对象

SecurityContext

上一页Secret下一页Service

最后更新于7天前

Security Context 的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。

Kubernetes 提供了三种配置 Security Context 的方法:

  • Container-level Security Context:仅应用到指定的容器

  • Pod-level Security Context:应用到 Pod 内所有容器以及 Volume

  • Pod Security Policies(PSP):应用到集群内部所有 Pod 以及 Volume

Container-level Security Context

仅应用到指定的容器上,并且不会影响 Volume。比如设置容器运行在特权模式:

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
    - name: hello-world-container
      # The container definition
      # ...
      securityContext:
        privileged: true

Pod-level Security Context

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
  # specification of the pod's containers
  # ...
  securityContext:
    fsGroup: 1234
    supplementalGroups: [5678]
    seLinuxOptions:
      level: "s0:c123,c456"

Supplemental Groups Policy(补充组策略)

Kubernetes v1.31 引入了 supplementalGroupsPolicy 字段作为 alpha 特性,并在 v1.33 中升级为 beta 版本(默认启用)。该特性提供了对容器补充组更精细的控制,特别是在访问卷时能够加强安全态势。

背景:容器镜像中的隐式组成员身份

默认情况下,Kubernetes 会将 Pod 中指定的组信息与容器镜像中 /etc/group 文件定义的组信息进行合并。这种隐式合并可能带来安全风险,因为:

  • 策略引擎无法检测或验证这些隐式 GID(它们不在 Pod 清单中)

  • 可能导致意外的访问控制问题,特别是在访问卷时

supplementalGroupsPolicy 字段

该字段允许控制 Kubernetes 如何计算 Pod 内容器进程的补充组。可用的策略包括:

  • Merge(默认):容器主用户在 /etc/group 中定义的组成员身份将被合并。这是向后兼容的默认行为。

  • Strict:仅将 fsGroup、supplementalGroups 或 runAsGroup 中指定的组 ID 作为补充组附加到容器进程。忽略容器主用户在 /etc/group 中定义的组成员身份。

示例:使用 Strict 策略

apiVersion: v1
kind: Pod
metadata:
  name: strict-supplementalgroups-policy
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    supplementalGroups: [4000]
    supplementalGroupsPolicy: Strict
  containers:
  - name: ctr
    image: registry.k8s.io/e2e-test-images/agnhost:2.45
    command: [ "sh", "-c", "sleep 1h" ]
    securityContext:
      allowPrivilegeEscalation: false

使用 Strict 策略时,容器中 id 命令的输出将只包含明确指定的组:

uid=1000 gid=3000 groups=3000,4000

CRI 运行时要求

supplementalGroupsPolicy: Strict 需要支持此功能的 CRI 运行时:

  • containerd: v2.0 或更高版本

  • CRI-O: v1.31 或更高版本

可以通过节点的 .status.features.supplementalGroupsPolicy 字段查看是否支持:

apiVersion: v1
kind: Node
...
status:
  features:
    supplementalGroupsPolicy: true

Beta 版本的行为变化

在 alpha 版本中,当具有 supplementalGroupsPolicy: Strict 的 Pod 被调度到不支持该功能的节点时,策略会静默回退到 Merge。

在 v1.33 beta 版本中,kubelet 会拒绝其节点无法确保指定策略的 Pod。被拒绝时会看到警告事件:

apiVersion: v1
kind: Event
...
type: Warning
reason: SupplementalGroupsPolicyNotSupported
message: "SupplementalGroupsPolicy=Strict is not supported in this node"

Pod 状态中的进程身份信息

该特性还通过 .status.containerStatuses[].user.linux 字段暴露附加到容器第一个进程的进程身份:

status:
  containerStatuses:
  - name: ctr
    user:
      linux:
        gid: 3000
        supplementalGroups:
        - 3000
        - 4000
        uid: 1000

User Namespaces(用户命名空间)

User Namespaces(用户命名空间)是 Kubernetes v1.33 中默认启用的重要安全特性。它通过隔离容器内的用户和组 ID 与主机系统的用户和组 ID,提供了额外的安全隔离层。

启用用户命名空间

从 Kubernetes v1.33 开始,用户命名空间功能默认启用,Pod 可以通过设置 hostUsers: false 来选择性使用:

apiVersion: v1
kind: Pod
metadata:
  name: userns-pod
spec:
  hostUsers: false  # 启用用户命名空间
  containers:
  - name: shell
    image: debian
    command: ["sleep", "infinity"]
    securityContext:
      runAsUser: 0  # 容器内以 root 身份运行,但映射到主机的非特权用户

安全优势

用户命名空间提供以下重要安全改进:

  1. 权限隔离:容器内的 root 用户(UID 0)被映射到主机上的非特权用户,大大降低容器逃逸的风险

  2. 横向移动防护:即使攻击者获得了容器内的 root 权限,也无法访问主机系统或其他容器

  3. 文件系统隔离:通过 idmap 挂载提供文件系统级别的用户 ID 隔离

系统要求

使用用户命名空间需要满足以下条件:

  • 操作系统:仅支持 Linux 系统

  • 内核版本:推荐 Linux 5.19+,最佳体验需要 6.3+

  • 容器运行时:containerd 2.0+ 或 CRI-O

  • 文件系统:必须支持 idmap 挂载

兼容性说明

虽然大多数应用程序无需修改即可使用用户命名空间,但需要注意以下限制:

  • 某些特权操作可能不被支持

  • NFS 卷当前不支持用户命名空间

  • 部分旧版本的容器镜像可能需要调整

示例配置

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  hostUsers: false
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 2000
  containers:
  - name: app
    image: myapp:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL

Pod Security Policies(PSP)

Pod Security Policies(PSP)是集群级的 Pod 安全策略,自动为集群内的 Pod 和 Volume 设置 Security Context。

使用 PSP 需要 API Server 开启 extensions/v1beta1/podsecuritypolicy,并且配置 PodSecurityPolicy admission 控制器。

API 版本对照表

Kubernetes 版本
Extension 版本

v1.5-v1.15

extensions/v1beta1

v1.10+

policy/v1beta1

v1.21

deprecated

支持的控制项

控制项
说明

privileged

运行特权容器

defaultAddCapabilities

可添加到容器的 Capabilities

requiredDropCapabilities

会从容器中删除的 Capabilities

allowedCapabilities

允许使用的 Capabilities 列表

volumes

控制容器可以使用哪些 volume

hostNetwork

允许使用 host 网络

hostPorts

允许的 host 端口列表

hostPID

使用 host PID namespace

hostIPC

使用 host IPC namespace

hostUsers

使用 host user namespace(设为 false 启用用户命名空间隔离)

seLinux

SELinux Context

runAsUser

user ID

supplementalGroups

允许的补充用户组

supplementalGroupsPolicy

补充组策略(Merge 或 Strict)

fsGroup

volume FSGroup

readOnlyRootFilesystem

只读根文件系统

allowedHostPaths

允许 hostPath 插件使用的路径列表

allowedFlexVolumes

允许使用的 flexVolume 插件列表

allowPrivilegeEscalation

defaultAllowPrivilegeEscalation

默认是否允许特权升级

示例

限制容器的 host 端口范围为 8000-8080:

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: permissive
spec:
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  hostPorts:
  - min: 8000
    max: 8080
  volumes:
  - '*'

限制只允许使用 lvm 和 cifs 等 flexVolume 插件:

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: allow-flex-volumes
spec:
  fsGroup:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
    - flexVolume
  allowedFlexVolumes:
    - driver: example/lvm
    - driver: example/cifs

SELinux

SELinux (Security-Enhanced Linux) 是一种强制访问控制(mandatory access control)的实现。它的作法是以最小权限原则(principle of least privilege)为基础,在 Linux 核心中使用 Linux 安全模块(Linux Security Modules)。SELinux 主要由美国国家安全局开发,并于 2000 年 12 月 22 日发行给开放源代码的开发社区。

可以通过 runcon 来为进程设置安全策略,ls 和 ps 的 - Z 参数可以查看文件或进程的安全策略。

开启与关闭 SELinux

修改 / etc/selinux/config 文件方法:

  • 开启:SELINUX=enforcing

  • 关闭:SELINUX=disabled

通过命令临时修改:

  • 开启:setenforce 1

  • 关闭:setenforce 0

查询 SELinux 状态:

$ getenforce

示例

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  containers:
  - image: gcr.io/google_containers/busybox:1.24
    name: test-container
    command:
    - sleep
    - "6000"
    volumeMounts:
    - mountPath: /mounted_volume
      name: test-volume
  restartPolicy: Never
  hostPID: false
  hostIPC: false
  securityContext:
    seLinuxOptions:
      level: "s0:c2,c3"
  volumes:
  - name: test-volume
    emptyDir: {}

这会自动给 docker 容器生成如下的 HostConfig.Binds:

/var/lib/kubelet/pods/f734678c-95de-11e6-89b0-42010a8c0002/volumes/kubernetes.io~empty-dir/test-volume:/mounted_volume:Z
/var/lib/kubelet/pods/f734678c-95de-11e6-89b0-42010a8c0002/volumes/kubernetes.io~secret/default-token-88xxa:/var/run/secrets/kubernetes.io/serviceaccount:ro,Z
/var/lib/kubelet/pods/f734678c-95de-11e6-89b0-42010a8c0002/etc-hosts:/etc/hosts

对应的 volume 也都会正确设置 SELinux:

$ ls -Z /var/lib/kubelet/pods/f734678c-95de-11e6-89b0-42010a8c0002/volumes
drwxr-xr-x. root root unconfined_u:object_r:svirt_sandbox_file_t:s0:c2,c3 kubernetes.io~empty-dir
drwxr-xr-x. root root unconfined_u:object_r:svirt_sandbox_file_t:s0:c2,c3 kubernetes.io~secret

参考文档

应用到 Pod 内所有容器,并且还会影响 Volume(包括 fsGroup 和 selinuxOptions)。

由于 中从代码库中删除。PodSecurityPolicy API 不够灵活、认证模型不够完善且配置更新繁琐等缺陷,PodSecurityPolicy 已在 v1.21 正式,并将在 v1.25 中从代码库中删除。已经使用 PodSecurityPolicy 的用户推荐迁移到 。

允许容器进程设置

Container-level Security Context
Pod-level Security Context
弃用
Open Policy Agent
Kubernetes Pod Security Policies
no_new_privs