第十三篇:《K8s 安全基础:RBAC、ServiceAccount、Pod Security》

安全是 Kubernetes 生产化部署的核心议题。默认情况下,K8s 集群中的用户和 ServiceAccount 拥有一定的权限,但若不加限制,任何 Pod 都可能访问 API Server,甚至越权操作。本文详细讲解基于角色的访问控制(RBAC)、ServiceAccount 的用途,以及 Pod 安全标准(Pod Security Standards)和 Pod Security Admission(PSA)。通过这些机制,你可以实现细粒度的权限隔离和安全加固。

一、Kubernetes 安全体系概览

Kubernetes 安全分为三个层面:

集群访问安全:认证(Authentication)、授权(Authorization)、准入控制(Admission Control)。

Pod 内部安全:容器运行用户、权限提升、安全上下文。

网络策略:限制 Pod 之间通信(后续文章介绍)。

本文聚焦于认证与授权(RBAC + ServiceAccount)以及 Pod 安全策略(PSA)。

二、认证(Authentication)与授权(Authorization)简介

认证:确认请求者的身份,包括:客户端证书、Bearer Token(ServiceAccount)、用户名/密码(基础认证,已废弃)、OpenID Connect 等。

授权:决定请求者是否有权执行某个操作。K8s 支持多种授权模式:RBAC、ABAC(已过时)、Webhook、Node 授权。

生产环境几乎都使用 RBAC(基于角色的访问控制)。

三、RBAC 核心概念

RBAC 通过四个资源对象实现:

3.1 一个简单的 Role 示例

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]          # 核心 API 组
  resources: ["pods"]      # 资源类型
  verbs: ["get", "list", "watch"]   # 允许的操作

3.2 RoleBinding 绑定到用户

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: alice           # 用户名(由外部认证提供)
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

3.3 ClusterRole 与 ClusterRoleBinding

ClusterRole 可用于跨命名空间管理,例如查看所有 Pod:

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader-cluster
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-all-pods
subjects:
- kind: User
  name: alice
roleRef:
  kind: ClusterRole
  name: pod-reader-cluster
  apiGroup: rbac.authorization.k8s.io

四、ServiceAccount:Pod 的身份标识

ServiceAccount 是 Kubernetes 为 Pod 中的进程提供的身份。Pod 可以使用该身份与 API Server 交互。每个命名空间会默认创建一个名为 default 的 ServiceAccount,并自动挂载 token 到 /var/run/secrets/kubernetes.io/serviceaccount。

4.1 创建自定义 ServiceAccount

bash 复制代码
kubectl create sa my-sa -n my-ns
4.2 在 Pod 中使用 ServiceAccount
yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: my-sa
  containers:
  - name: app
    image: nginx

Pod 运行后,可以通过挂载的 token 调用 API Server(需要相应的 RBAC 授权)。

4.3 为 ServiceAccount 授权

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: my-ns
  name: sa-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: my-ns
  name: sa-reader-binding
subjects:
- kind: ServiceAccount
  name: my-sa
  namespace: my-ns
roleRef:
  kind: Role
  name: sa-reader
  apiGroup: rbac.authorization.k8s.io

4.4 禁止 ServiceAccount 自动挂载

默认情况下,每个 Pod 都会挂载默认 ServiceAccount 的 token。若不希望 Pod 拥有 API 访问权限,可以禁用自动挂载:

yaml 复制代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: no-token-sa
automountServiceAccountToken: false

或在 Pod 级别设置 automountServiceAccountToken: false。

五、Pod 安全标准(Pod Security Standards)

Pod Security Standards 定义了三种安全策略,用于限制 Pod 的行为(如运行用户、特权容器、卷类型等)。

六、Pod Security Admission(PSA)

Pod Security Admission 是 K8s 1.22+ 引入的准入控制器,用于在命名空间级别强制执行 Pod 安全标准。它是 PodSecurityPolicy(已废弃)的替代方案。

6.1 为命名空间设置安全策略

通过给命名空间打标签来声明策略:

bash 复制代码
# 设置默认策略为 baseline,并拒绝违反 restricted 策略的 Pod
kubectl label ns default pod-security.kubernetes.io/enforce=baseline
kubectl label ns default pod-security.kubernetes.io/enforce-version=latest
kubectl label ns default pod-security.kubernetes.io/warn=restricted
kubectl label ns default pod-security.kubernetes.io/warn-version=latest

enforce:违反策略时拒绝 Pod 创建。

audit:记录违反事件但不拒绝。

warn:触发告警信息。

6.2 测试 Pod 是否符合策略

如果一个 Pod 违反了 restricted 策略,但命名空间只设置了 warn=restricted,则创建 Pod 时会显示警告,但 Pod 仍能创建。可以逐步提升策略等级。

6.3 豁免与例外

通过 Pod 的 metadata.annotations 可以临时绕过某些检查:

yaml 复制代码
metadata:
  annotations:
    pod-security.kubernetes.io/exempt: "true"

但生产环境不建议普遍使用。

七、安全上下文(SecurityContext)

SecurityContext 是在 Pod 或容器级别配置安全选项(如运行用户、特权、只读根文件系统等)。

7.1 容器级别配置

yaml 复制代码
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: myapp
    image: myapp
    securityContext:
      runAsUser: 1000
      runAsGroup: 3000
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]
        add: ["NET_ADMIN"]

runAsNonRoot: true:强制容器不以 root 运行。

privileged: false:禁止特权容器。

capabilities:控制 Linux Capabilities,遵循最小权限原则。

7.2 Pod 级别配置

Pod 级别配置会被容器继承(除非容器覆盖):

yaml 复制代码
spec:
  securityContext:
    runAsUser: 1000
    fsGroup: 2000        # 卷文件的属组

八、实战:为部署提供最小权限 ServiceAccount

创建命名空间 secure-ns。

创建 ServiceAccount my-app-sa。

创建 Role 只允许 get、list pods。

绑定该 Role 到 ServiceAccount。

在 Deployment 中使用该 ServiceAccount。

yaml 复制代码
# 创建命名空间
kubectl create ns secure-ns

# 创建 ServiceAccount
kubectl create sa my-app-sa -n secure-ns

# 创建 Role 和 RoleBinding
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: secure-ns
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: secure-ns
  name: my-app-binding
subjects:
- kind: ServiceAccount
  name: my-app-sa
  namespace: secure-ns
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
EOF

# 部署应用
kubectl run test-pod --image=busybox -n secure-ns --overrides='{"spec":{"serviceAccountName":"my-app-sa"}}' --command sleep 3600

进入 Pod 测试 API 访问:

bash 复制代码
kubectl exec -it test-pod -n secure-ns -- sh
# 安装 curl 并访问 API Server
apk add curl
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default/api/v1/namespaces/secure-ns/pods

由于只授权了 get/list pods,无法创建或删除资源。

九、最佳实践

禁用 default ServiceAccount 的自动挂载:为每个命名空间配置 automountServiceAccountToken: false。

使用最小权限原则:只授予必要的 API 操作。

为生产环境命名空间开启 Pod Security Admission:至少设置为 baseline。

避免使用 privileged 容器,除非绝对必要(如网络插件)。

设置容器的 securityContext:runAsNonRoot: true,readOnlyRootFilesystem: true。

定期审计 RBAC 权限:使用工具如 rbac-lookup、kubectl-who-can。

十、小结

RBAC 和 ServiceAccount 构成了 Kubernetes 的授权基础,通过细粒度的角色绑定,可以严格限制 Pod 和用户的操作范围。Pod Security Admission 则保证了 Pod 自身配置的安全性,防止危险配置(如特权容器)进入集群。结合 SecurityContext,你能够建立一个纵深防御的容器环境。

相关推荐
TechWayfarer1 小时前
苏超赛事网站安全防护:WAF、DDoS与仿冒页面如何联动治理
网络·python·安全·flask·ddos
张某布响丸辣1 小时前
Spring AI 极简入门:Java 开发者快速上手 AI 开发
java·人工智能·spring·springai
java1234_小锋1 小时前
请描述 Spring Boot 的启动流程,包括 SpringApplication 的初始化和 run 方法的核心步骤。
java·数据库·spring boot
疯狂成瘾者1 小时前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表
顾凌陵1 小时前
Web安全二阶段综合测试:知识点速查与实战技巧
安全·web安全
lanyxp2 小时前
Sentinel 管不到 SQL 这一层——我写了个 MyBatis SQL 熔断器
java
武子康2 小时前
Java-28 深入浅出 Spring 实现简易Ioc-04 在上节的业务下手动实现AOP
java·后端·mybatis
慧一居士2 小时前
SpringCloud 微服务Feigin 用的完整调用端和被调用的示例
java·spring cloud