ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【Kubernetes从入门到精通】第54篇:ServiceAccount——Pod的“身份证“,但它正在变得“短命“

【Kubernetes从入门到精通】第54篇:ServiceAccount——Pod的“身份证“,但它正在变得“短命“ 上一篇【第53篇】RBAC——基于角色的访问控制完全指南下一篇【第55篇】SecurityContext——容器安全配置的三件套摘要上篇我们给CI/CD建了个ServiceAccount(SA)。但SA到底是怎么和Pod绑定的Pod又是怎么拿着身份证去调API Server的简单说每个Pod默认都有一个ServiceAccountK8s会自动把一个Token文件挂进Pod的/var/run/secrets/kubernetes.io/serviceaccount/目录。Pod里的应用读这个Token就能以这个SA的身份去访问API Server。但这里有个巨大的安全演进K8s v1.22之前这个Token是永久有效的——泄露了就永久泄露v1.22之后改成了Bound ServiceAccount Token绑定了身份、有有效期、可被吊销。这是K8s安全史上最被低估的一次升级。这篇文章讲清SA的自动挂载机制、Token的演进史、怎么禁用自动挂载减少攻击面以及PSA怎么接替老PSP。一、SA是什么Pod怎么用它1.1 自动挂载机制【Pod 的身份证是怎么挂进去的】 创建Pod时如果不指定 serviceAccountName: │ ▼ K8s 自动给它分配 default ServiceAccount (该ns下的) │ ▼ ServiceAccount准入控制器 (内置Admission插件) 自动把 SA 的 Token 挂进 Pod: │ ▼ Pod 里出现: /var/run/secrets/kubernetes.io/serviceaccount/ ├── token ← 身份证明(Bearer Token) ├── ca.crt ← API Server的CA证书 └── namespace ← 当前namespace名 │ ▼ Pod里的应用读 token以SA身份调 API Server1.2 看一眼实际的挂载# 进任意Pod看挂载kubectlexec-itmy-pod --ls/var/run/secrets/kubernetes.io/serviceaccount/# ca.crt namespace token# 看Pod用了哪个SAkubectl get pod my-pod-ojsonpath{.spec.serviceAccountName}# default# 指定自定义SAkubectl run my-app--imagenginx--serviceaccountdeployer要点默认每个Pod都用所在ns的defaultSA。这意味着——如果你的defaultSA被赋予了权限那这个ns里所有Pod都能用这些权限很多安全事故的根源就是default SA权限过大。正确做法是给不同应用建独立SA并遵循最小权限。二、Token的演进——从永生到短命2.1 这是K8s安全史的重要一跃【ServiceAccount Token 的演进】 旧版 (v1.22之前): Secret-based Token ┌─────────────────────────────────────────┐ │ • Token存在Secret里永不过期 │ │ • 泄露了 永久可用(除非轮换Secret) │ │ • 删除SAToken还在(Secret里) │ │ • 攻击者拿到一个Pod的token就能长期潜伏 │ └─────────────────────────────────────────┘ 新版 (v1.22): Bound ServiceAccount Token ┌─────────────────────────────────────────┐ │ • Token是动态生成的有exp过期时间(默认1h) │ │ • 绑定到具体的SA Pod/Secret对象 │ │ • 可被主动吊销(删除对象即失效) │ │ • 自动轮换(快过期时API Server发新的) │ └─────────────────────────────────────────┘维度旧Token(Secret)新Token(Bound)有效期永久默认1小时可配存储Secret对象Projected Volume动态注入吊销难(需轮换Secret)易(删对象即失效)绑定对象仅SASA 具体Pod/Secret要点这个演进是安全性质的跃迁。旧Token像一把永久钥匙丢了就完了新Token像临时门禁卡一小时过期、还能远程注销。如果你还在用v1.21或更早强烈建议升级——光这一项就能堵住一大类横向移动攻击。三、禁用自动挂载——缩小攻击面3.1 不是每个Pod都需要调API很多Pod比如纯前端、纯计算根本不需要访问API Server。给它挂token纯属送攻击面。# 方式1: Pod级别禁用自动挂载apiVersion:v1kind:Podmetadata:name:no-api-podspec:automountServiceAccountToken:false# 不挂tokencontainers:-name:appimage:nginx# 方式2: ServiceAccount级别禁用(影响所有用这个SA的Pod)apiVersion:v1kind:ServiceAccountmetadata:name:no-api-saautomountServiceAccountToken:false# 验证Pod里应该没有token目录kubectlexec-itno-api-pod --\ls/var/run/secrets/kubernetes.io/serviceaccount/21# ls: cannot access ... : No such file or directory# ↑ 干净这个Pod没有API Server身份攻击者拿下了它也调不了API3.2 需要token但想自定义有效期# 用 Projected Volume 自定义token参数apiVersion:v1kind:Podmetadata:name:custom-token-podspec:containers:-name:appimage:nginxvolumeMounts:-name:sa-tokenmountPath:/var/run/secrets/tokensvolumes:-name:sa-tokenprojected:sources:-serviceAccountToken:path:tokenexpirationSeconds:7200# 2小时过期(覆盖默认1h)audience:api# token受众四、PSA接替PSP——Pod安全的正规军4.1 PSP已死Pod Security PolicyPSP是老式的Pod安全机制但设计得太难用要配一大堆绑定还容易把自己锁外面K8s 1.21正式废弃、1.25彻底删除。取而代之的是Pod Security Admission (PSA)——直接内置在API Server里零额外组件。【PSP (已死) vs PSA (现役)】 PSP: • 独立API资源要配Policy 绑定 • 复杂到劝退容易误锁集群 • 1.25删除 PSA: • 内置准入控制器不用装 • 用namespace的label控制三种模式 • 三档标准: Privileged / Baseline / Restricted4.2 PSA的三种模式# 给namespace打label启用PSA# 三个级别: privileged(放开) / baseline(中等) / restricted(最严)# enforce强制(违反直接拒绝), audit只记日志, warn只警告kubectl label ns prod\pod-security.kubernetes.io/enforcerestricted\pod-security.kubernetes.io/auditrestricted\pod-security.kubernetes.io/warnrestricted# 效果在prod里创建特权容器(Privileged: true)会被直接拒绝kubectl run priv--imagenginx--privileged-nprod# Error: ... violates PodSecurity restricted:latest模式行为用途enforce违反直接拒绝生产强制audit记审计日志不拦截评估影响warn返回警告不拦截迁移过渡本篇小结ServiceAccount是Pod的身份证默认自动挂token进/var/run/secrets/...。K8s v1.22的关键演进——Token从永久Secret变为绑定身份、有有效期、可吊销的短命Token安全性质的飞跃。最佳实践不需要访问API的Pod用automountServiceAccountToken: false关掉挂载缩小攻击面。老旧的PSP已删除PSA用namespace label 三档标准privileged/baseline/restricted 三模式enforce/audit/warn接棒平滑又省心。下一篇讲SecurityContext——容器自身的降权三件套。上一篇【第53篇】RBAC——基于角色的访问控制完全指南下一篇【第55篇】SecurityContext——容器安全配置的三件套
返回列表