第十三篇:《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,你能够建立一个纵深防御的容器环境。

相关推荐
动恰客流统计23 分钟前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
Ivanqhz1 小时前
Rust &‘static str浅析
java·前端·javascript·rust
张忠琳1 小时前
【NVIDIA】NVIDIA Container Toolkit v1.19.1--07-NVCDI模块:CDI Spec生成引擎深度分析之七
云原生·容器·架构·kubernetes·nvidia
沉迷学习 日益消瘦3 小时前
01-Kubernetes 入门:概念与安装
云原生·容器·kubernetes
weixin_419658314 小时前
Docker 搭建 Jenkins 服务
java·docker·jenkins
captain3764 小时前
多线程线程安全问题
java·java-ee
CoderYanger5 小时前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
灵极海5 小时前
LangChain4j RAG 实战完整指南:从入门到踩坑
java·langchain
yaoxin5211235 小时前
476. Java 反射 - 调用方法
java·开发语言
智慧地球(AI·Earth)5 小时前
MAX-API v1.0.5-preview.2:安全加固、计费一致性与限流隔离
安全·max api·差额计费修复