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

📅 2026/6/16 9:16:04
第十三篇:《K8s 安全基础:RBAC、ServiceAccount、Pod Security》
安全是 Kubernetes 生产化部署的核心议题。默认情况下K8s 集群中的用户和 ServiceAccount 拥有一定的权限但若不加限制任何 Pod 都可能访问 API Server甚至越权操作。本文详细讲解基于角色的访问控制RBAC、ServiceAccount 的用途以及 Pod 安全标准Pod Security Standards和 Pod Security AdmissionPSA。通过这些机制你可以实现细粒度的权限隔离和安全加固。一、Kubernetes 安全体系概览Kubernetes 安全分为三个层面集群访问安全认证Authentication、授权Authorization、准入控制Admission Control。Pod 内部安全容器运行用户、权限提升、安全上下文。网络策略限制 Pod 之间通信后续文章介绍。本文聚焦于认证与授权RBAC ServiceAccount以及 Pod 安全策略PSA。二、认证Authentication与授权Authorization简介认证确认请求者的身份包括客户端证书、Bearer TokenServiceAccount、用户名/密码基础认证已废弃、OpenID Connect 等。授权决定请求者是否有权执行某个操作。K8s 支持多种授权模式RBAC、ABAC已过时、Webhook、Node 授权。生产环境几乎都使用 RBAC基于角色的访问控制。三、RBAC 核心概念RBAC 通过四个资源对象实现3.1 一个简单的 Role 示例apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:defaultname:pod-readerrules:-apiGroups:[]# 核心 API 组resources:[pods]# 资源类型verbs:[get,list,watch]# 允许的操作3.2 RoleBinding 绑定到用户apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:read-podsnamespace:defaultsubjects:-kind:Username:alice# 用户名由外部认证提供apiGroup:rbac.authorization.k8s.ioroleRef:kind:Rolename:pod-readerapiGroup:rbac.authorization.k8s.io3.3 ClusterRole 与 ClusterRoleBindingClusterRole 可用于跨命名空间管理例如查看所有 PodapiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:pod-reader-clusterrules:-apiGroups:[]resources:[pods]verbs:[get,list,watch]---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRoleBindingmetadata:name:read-all-podssubjects:-kind:Username:aliceroleRef:kind:ClusterRolename:pod-reader-clusterapiGroup:rbac.authorization.k8s.io四、ServiceAccountPod 的身份标识ServiceAccount 是 Kubernetes 为 Pod 中的进程提供的身份。Pod 可以使用该身份与 API Server 交互。每个命名空间会默认创建一个名为 default 的 ServiceAccount并自动挂载 token 到 /var/run/secrets/kubernetes.io/serviceaccount。4.1 创建自定义 ServiceAccountkubectl create sa my-sa-nmy-ns4.2在 Pod 中使用 ServiceAccount yaml apiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: my-sa containers: - name: app image: nginxPod 运行后可以通过挂载的 token 调用 API Server需要相应的 RBAC 授权。4.3 为 ServiceAccount 授权apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:my-nsname:sa-readerrules:-apiGroups:[]resources:[pods]verbs:[get,list]---apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:namespace:my-nsname:sa-reader-bindingsubjects:-kind:ServiceAccountname:my-sanamespace:my-nsroleRef:kind:Rolename:sa-readerapiGroup:rbac.authorization.k8s.io4.4 禁止 ServiceAccount 自动挂载默认情况下每个 Pod 都会挂载默认 ServiceAccount 的 token。若不希望 Pod 拥有 API 访问权限可以禁用自动挂载apiVersion:v1kind:ServiceAccountmetadata:name:no-token-saautomountServiceAccountToken:false或在 Pod 级别设置 automountServiceAccountToken: false。五、Pod 安全标准Pod Security StandardsPod Security Standards 定义了三种安全策略用于限制 Pod 的行为如运行用户、特权容器、卷类型等。六、Pod Security AdmissionPSAPod Security Admission 是 K8s 1.22 引入的准入控制器用于在命名空间级别强制执行 Pod 安全标准。它是 PodSecurityPolicy已废弃的替代方案。6.1 为命名空间设置安全策略通过给命名空间打标签来声明策略# 设置默认策略为 baseline并拒绝违反 restricted 策略的 Podkubectl label ns default pod-security.kubernetes.io/enforcebaseline kubectl label ns default pod-security.kubernetes.io/enforce-versionlatest kubectl label ns default pod-security.kubernetes.io/warnrestricted kubectl label ns default pod-security.kubernetes.io/warn-versionlatestenforce违反策略时拒绝 Pod 创建。audit记录违反事件但不拒绝。warn触发告警信息。6.2 测试 Pod 是否符合策略如果一个 Pod 违反了 restricted 策略但命名空间只设置了 warnrestricted则创建 Pod 时会显示警告但 Pod 仍能创建。可以逐步提升策略等级。6.3 豁免与例外通过 Pod 的 metadata.annotations 可以临时绕过某些检查metadata:annotations:pod-security.kubernetes.io/exempt:true但生产环境不建议普遍使用。七、安全上下文SecurityContextSecurityContext 是在 Pod 或容器级别配置安全选项如运行用户、特权、只读根文件系统等。7.1 容器级别配置apiVersion:v1kind:Podspec:containers:-name:myappimage:myappsecurityContext:runAsUser:1000runAsGroup:3000readOnlyRootFilesystem:trueallowPrivilegeEscalation:falsecapabilities:drop:[ALL]add:[NET_ADMIN]runAsNonRoot: true强制容器不以 root 运行。privileged: false禁止特权容器。capabilities控制 Linux Capabilities遵循最小权限原则。7.2 Pod 级别配置Pod 级别配置会被容器继承除非容器覆盖spec:securityContext:runAsUser:1000fsGroup:2000# 卷文件的属组八、实战为部署提供最小权限 ServiceAccount创建命名空间 secure-ns。创建 ServiceAccount my-app-sa。创建 Role 只允许 get、list pods。绑定该 Role 到 ServiceAccount。在 Deployment 中使用该 ServiceAccount。# 创建命名空间kubectl create ns secure-ns# 创建 ServiceAccountkubectl create sa my-app-sa-n secure-ns# 创建 Role 和 RoleBindingcat EOF|kubectl apply-f-apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:secure-nsname:pod-readerrules:-apiGroups:[]resources:[pods]verbs:[get,list]---apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:namespace:secure-nsname:my-app-bindingsubjects:-kind:ServiceAccountname:my-app-sanamespace:secure-nsroleRef:kind:Rolename:pod-readerapiGroup:rbac.authorization.k8s.io EOF# 部署应用kubectl run test-pod--imagebusybox-n secure-ns--overrides{spec:{serviceAccountName:my-app-sa}}--command sleep 3600进入 Pod 测试 API 访问kubectlexec-ittest-pod-nsecure-ns --sh# 安装 curl 并访问 API ServerapkaddcurlTOKEN$(cat/var/run/secrets/kubernetes.io/serviceaccount/token)curl-k-HAuthorization: Bearer$TOKENhttps://kubernetes.default/api/v1/namespaces/secure-ns/pods由于只授权了 get/list pods无法创建或删除资源。九、最佳实践禁用 default ServiceAccount 的自动挂载为每个命名空间配置 automountServiceAccountToken: false。使用最小权限原则只授予必要的 API 操作。为生产环境命名空间开启 Pod Security Admission至少设置为 baseline。避免使用 privileged 容器除非绝对必要如网络插件。设置容器的 securityContextrunAsNonRoot: truereadOnlyRootFilesystem: true。定期审计 RBAC 权限使用工具如 rbac-lookup、kubectl-who-can。十、小结RBAC 和 ServiceAccount 构成了 Kubernetes 的授权基础通过细粒度的角色绑定可以严格限制 Pod 和用户的操作范围。Pod Security Admission 则保证了 Pod 自身配置的安全性防止危险配置如特权容器进入集群。结合 SecurityContext你能够建立一个纵深防御的容器环境。