CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Kubernetes 入门/课时/RBAC 与安全基础
RawBlame
课时目录12 节

Kubernetes 入门

  1. 01Kubernetes 是什么
  2. 02核心概念与架构
  3. 03本地集群与 kubectl
  4. 04Pod
  5. 05Deployment 与滚动更新
  6. 06Service 与网络
  7. 07ConfigMap 与 Secret
  8. 08存储卷
  9. 09Ingress 入口
  10. 10资源配额与 HPA
  11. 11RBAC 与安全基础
  12. 12综合练习:部署 backend

RBAC 与安全基础

ServiceAccount、Role、最小权限。

30 分钟

RBAC 与安全基础

这一课你将能做到

  1. 说清 RBAC 四件套(ServiceAccount/Role/Binding 及其 Cluster 版本)如何组合出权限,并实际创建一套「CI 专用最小权限」
  2. 用 kubectl auth can-i 与 --as 模拟(impersonation)验证任意身份的权限
  3. 让一个容器以非 root 运行(securityContext),并说出镜像、密钥、网络三道防线的入门清单

为什么要学

集群里「谁能删 Deployment」「Pod 能不能读所有 Secret」直接决定爆炸半径。本站如果多人维护、CI 要自动发布,绝不能人人都绑 cluster-admin——一次误 apply 到错误 namespace、一次 CI 凭证泄漏,都可能是删库级事故。

RBAC(Role-Based Access Control) 是 K8s 内置的授权模型:主体(人/机器)通过绑定获得角色,角色定义「对哪些资源能做哪些动作」。在 RBAC 之上,容器自身还有第二道防线:运行身份(别用 root)、镜像来源(别用来路不明的镜像)、网络边界(默认全通的 Pod 网络)。这些是面试安全题的主战场,更是将来带团队时的基本功。

先建立图像

主体(Subject)              权限(规则)                粘合
User / Group               ┌ Role          ┐
  (人:证书/OIDC)          │ verbs ×       │ ── RoleBinding ──→ 授权(命名空间内)
ServiceAccount             │ resources     │
  (Pod/CI 机器账号)        └ ClusterRole  ┘ ── ClusterRoleBinding → 授权(全集群)
范围权限对象绑定对象典型用途
命名空间内RoleRoleBinding业务团队的日常运维
全集群ClusterRoleClusterRoleBinding平台管理员、监控采集

人话:Role 写「能干什么」,Binding 写「谁能干」。有 Role 没 Binding = 没权限,这是新手第一个混淆点。

跟着做

步骤 1:先自查「我现在是谁、能干什么」

kubectl config current-context
kubectl auth can-i create deployments --namespace default
kubectl auth can-i get secrets --namespace default
kubectl auth can-i "*" "*" --all-namespaces

本地 minikube 里第三条大概率是 yes(你即管理员)——学习环境正常,生产环境这必须是极少数人。

步骤 2:创建 CI 专用 ServiceAccount

sa-ci.yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-bot
  namespace: default

人话:ServiceAccount 是「给程序用的账号」。Pod 默认挂 default SA;CI 流水线、运维机器人应各配专用 SA——账号能审计、能单独吊销。

kubectl apply -f sa-ci.yaml

步骤 3:写最小权限 Role 并绑定

rbac-ci.yaml(ci-bot 只能管理 default 命名空间的工作负载,不能读 Secret、不能删命名空间):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deploy-manager
  namespace: default
rules:
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods", "pods/log", "services"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-bot-deploy-manager
  namespace: default
subjects:
  - kind: ServiceAccount
    name: ci-bot
    namespace: default
roleRef:
  kind: Role
  name: deploy-manager
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-ci.yaml

注意 apiGroups: [""] 的空串表示核心组(Pod/Service 等);Deployment 在 apps 组——写错组名是最常见的「有 Role 却不生效」原因。

步骤 4:用模拟(impersonation)验证权限边界

管理员可以「扮演」任意身份做验证——这是排查 RBAC 的利器:

kubectl get pods --as=system:serviceaccount:default:ci-bot          # yes
kubectl create deployment t --image=nginx:1.27-alpine \
  --as=system:serviceaccount:default:ci-bot                          # yes
kubectl get secrets --as=system:serviceaccount:default:ci-bot       # Forbidden
kubectl delete namespace kube-system \
  --as=system:serviceaccount:default:ci-bot                          # Forbidden

两个 yes、两个 Forbidden = 权限边界与设计完全一致。CI 的 kubeconfig 就用这个 SA 的凭证,泄漏时吊销它的 Binding 即可,不影响任何人。

kubectl delete deployment t

步骤 5:让容器拒绝 root 运行

先故意制造失败——给 nginx 加 runAsNonRoot: true(而官方 nginx 镜像默认以 root 跑):

# pod-root.yaml
apiVersion: v1
kind: Pod
metadata:
  name: root-test
spec:
  containers:
    - name: web
      image: nginx:1.27-alpine
  securityContext:
    runAsNonRoot: true
kubectl apply -f pod-root.yaml
kubectl get pod root-test        # STATUS: CreateContainerConfigError
kubectl describe pod root-test   # Events: container has runAsNonRoot and image will run as root

换用官方非特权镜像(监听 8080)再试:

# pod-nonroot.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nonroot-test
spec:
  containers:
    - name: web
      image: nginxinc/nginx-unprivileged:1.27-alpine
      securityContext:
        runAsNonRoot: true
        allowPrivilegeEscalation: false
kubectl apply -f pod-nonroot.yaml
kubectl get pod nonroot-test     # Running
kubectl delete pod root-test nonroot-test

规则总结:securityContext 在 Pod 级管所有容器,也可在 container 级单独覆盖;「镜像本身用非 root 用户」+「runAsNonRoot」双管齐下才是可落地的方案。

步骤 6:网络边界概念(NetworkPolicy)

许多集群默认 Pod 之间随便连——被攻破一个 Pod 就能横向扫描全集群。NetworkPolicy 可以收紧:

# 概念示例:backend 只允许被 platform 访问(需 CNI 支持才生效)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-allow-platform
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: platform
      ports:
        - port: 8080

本课不要求真跑通(minikube 默认 CNI 不执行策略),记住两个事实即可:① 未配策略 = 全通;② 策略生效依赖 CNI(Calico/Cilium 等)。

讲清楚要点

  1. 授权看的是 Binding 不是 Role:Role 只是权限模板,RoleBinding 才把「谁」和「能干什么」连起来;检查权限永远从 Binding 入手。
  2. ClusterRole 级对象慎用:给 CI 或新人绑 ClusterRoleBinding 到 cluster-admin 是经典事故源;能命名空间内解决的绝不全局。
  3. Secret 可读即泄密:get secrets 权限要单独严控——读到一个 Secret 就等于拿到它的全部内容,与「能进 Pod」不是一回事。
  4. 容器默认常以 root 运行:显式 securityContext + 镜像内置非 root 用户 + 关闭提权,把逃逸成本抬高一个量级。
  5. 镜像供应链仍是安全一环:本站镜像来自 CI,基础镜像要可信、要扫描(Trivy 等)、要固定 tag/digest;K8s 不管镜像怎么来的。
  6. RBAC 不替代应用层安全:Spring Security 的认证授权、MySQL 的账号权限各自独立——K8s 权限再小,应用自己的弱口令照样出事。

你可能会懵的地方

  • User 和 ServiceAccount 差别? User 是集群外的人/系统(通过证书、OIDC 等认证,K8s 本身不存 User 对象);ServiceAccount 是集群内对象,给 Pod 与程序用。运维人和开发用 User,CI 和应用用 SA。

  • can-i 返回 yes 就代表安全吗? 不。它只证明「当前身份有权限」,不证明「这个权限应该存在」。定期用 can-i 扫一遍 CI 与服务账号,是权限收敛的日常动作。

  • Pod Security Admission 是什么? 集群级策略(privileged/baseline/restricted 三档),强制命名空间里的 Pod 满足安全基线(非 root、禁特权等)。入门先手动做好 securityContext,团队大了再上 PSA。

  • K8s RBAC 和云 IAM 什么关系? 两层不同体系:云 IAM 管「谁能操作云资源/登录集群」,K8s RBAC 管「进了集群后能操作哪些对象」。节点 IAM 角色过宽同样危险,别只盯集群内。

  • 为什么默认网络全通? K8s 把「如何连」交给 CNI 插件,把「谁能连」交给 NetworkPolicy——都需要显式声明。安全从来不是默认赠送的。

错法对照

错法问题正解
所有成员共用 cluster-admin一次误操作全集群买单按职责拆 Role + Binding
应用 Pod 挂 default SA 且能读全 ns Secret被攻破即横向移动专用 SA + 最小 Role
基础镜像随手 pull 不扫描带着已知漏洞上线CI 集成镜像扫描 + 固定版本
容器以 root 跑逃逸面大runAsNonRoot + 非 root 镜像
以为 Namespace 就能隔离风险网络/权限并未隔离Namespace + RBAC + NetworkPolicy

卡点急救

  1. 操作报 Forbidden:按四要素自查——身份(current-context / SA)、apiGroup、resource、verb 是否都在 Role 规则里,Binding 的 subjects/roleRef 是否指向正确;用 --as 逐步缩小是哪一项不匹配。
  2. Pod 卡 CreateContainerConfigError 提示 runAsNonRoot:镜像默认用户是 root——换非特权镜像,或在 Dockerfile 里 USER 指定 UID(数字 UID 比用户名可靠),或在 securityContext 显式 runAsUser。
  3. CI 部署突然 401/403:SA 的凭证过期或 Binding 被改/删——用 kubectl get rolebinding -o yaml 核对,再用 can-i --as 复现 CI 的身份定位差异。

面试常问

  • 解释 K8s RBAC 的核心对象。 四件套:Role(命名空间内权限规则:apiGroups × resources × verbs);ClusterRole(集群级规则,也可被 RoleBinding 引用以复用);RoleBinding(把主体绑到 Role,作用于命名空间);ClusterRoleBinding(绑定到 ClusterRole,作用于全集群)。主体三种:User、Group、ServiceAccount。判定流程:请求 → 认证 → 鉴权(遍历该主体所有 Binding 聚合出的规则,allow 之和,默认拒绝)。

  • User 和 ServiceAccount 的区别?CI 该用哪种? User 面向集群外的人(证书/OIDC 认证,无对应 API 对象);ServiceAccount 是集群内 API 对象,面向 Pod 与程序,有可管理的凭证与 Token。CI 用专用 ServiceAccount + 命名空间级最小 Role:权限可审计、可单独吊销、不依赖任何个人账号(避免「离职删号 CI 瘫痪」)。

  • K8s 的网络默认安全吗? 不安全:多数 CNI 下所有 Pod 间网络互通,无默认隔离。需要用 NetworkPolicy 显式声明(基于 label 的 L3/L4 规则),且生效依赖 CNI 支持策略执行。纵深防御组合:NetworkPolicy 收网络 + RBAC 收 API + securityContext 收容器 + Secret/密管收凭证。

自测三问

  1. Role 和 ClusterRole 如何选?ClusterRole 一定更危险吗?
  2. 为什么 CI 流水线应该用专用 ServiceAccount 而不是某个人的 kubeconfig?
  3. 列出三件「即使 RBAC 配好也仍然要做」的安全措施。

小结一句话

RBAC 用 Role+Binding 回答「谁能对哪些资源做什么」,再叠加非 root 运行、镜像扫描与网络策略构成纵深防御——下一课把全部知识串起来,完成 backend 的完整部署验收。

延伸

  • Using RBAC Authorization
  • Security Checklist
  • 下一课预告:综合练习——从零把 backend(Deployment+Service+ConfigMap+Secret+探针+资源声明)完整部署进本地集群,并演练发布与回滚。
加载本节练习…
← 上一课资源配额与 HPA下一课 →综合练习:部署 backend