Kubernetes 安全管理核心机制
认证、授权和准入控制构成了 Kubernetes 安全体系的三大核心支柱,确保集群资源的安全访问和操作合规性。
认证(Authentication)
认证环节负责验证客户端身份,支持多种验证方式:
- 静态密码文件
- X509 客户端证书
- 服务账号(ServiceAccount)JWT 令牌
- OpenID Connect 令牌
- Webhook 回调认证
典型配置示例:
apiVersion: v1 kind: ServiceAccount metadata: name: dashboard-user授权(Authorization)
授权模块决定已认证用户的操作权限,支持以下模式:
- Node(节点授权)
- ABAC(基于属性的访问控制)
- RBAC(基于角色的访问控制)
- Webhook(自定义授权)
RBAC 配置示例:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]准入控制(Admission Control)
准入控制器在对象持久化前实施最后的安全检查,包含两种类型:
变更型控制器(Mutating)
- 自动添加默认字段
- 注入边车容器
- 修改资源请求参数
验证型控制器(Validating)
- 检查资源规范合规性
- 验证操作合法性
- 实施安全策略
推荐开启的关键控制器:
- ResourceQuota(资源配额)
- PodSecurityPolicy(已弃用,替换为 PSA)
- NodeRestriction(节点限制)
- ServiceAccount(服务账号)
Webhook 配置示例:
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: "pod-policy.example.com" webhooks: - name: "pod-policy.example.com" rules: - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE"] resources: ["pods"]安全实践建议
- 定期轮换服务账号令牌
- 实施最小权限原则
- 启用审计日志记录
- 使用网络策略限制 Pod 通信
- 定期更新集群组件补丁
通过分层安全防护机制,Kubernetes 构建了从身份识别到资源操作的全链条安全防护体系。合理配置这些安全组件可有效降低集群被攻击的风险。
--admission-control=ServiceAccount,NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota,MutatingAdmissionWebhook,ValidatingAdmissionWebhookKubernetes 认证机制详解
Kubernetes 的认证机制是确保集群安全的第一道防线,所有请求必须通过认证后才能进入后续的授权和准入控制阶段。以下是 Kubernetes 认证机制的核心要点:
认证插件类型
令牌(Token)认证
基于共享密钥的对称认证方式。服务器预生成令牌(如 ServiceAccount Token),客户端在 HTTP 请求头(Authorization: Bearer <token>)中携带该令牌。适用于:
- ServiceAccount 自动挂载的令牌(
/var/run/secrets/kubernetes.io/serviceaccount/token)。 - 静态令牌文件(通过
--token-auth-file配置)。
SSL/TLS 双向认证
基于 X.509 证书的双向验证:
- 客户端验证服务器证书:确保访问的
kube-apiserver证书由受信任的 CA 签发,且 Subject 中的 CN(Common Name)或 SAN(Subject Alternative Name)匹配目标主机。 - 服务器验证客户端证书:客户端(如
kubectl)需提供由集群 CA 签发的证书,证书中的 CN 或 O(Organization)字段用于标识用户身份。
Kubernetes 账号体系
用户账号(User Account)
通常对应外部用户(如管理员、开发者),通过以下方式标识:
- X.509 证书中的
CN字段作为用户名,O字段作为用户组。 - 静态令牌文件中的用户名/组信息。
- 外部认证系统(如 LDAP、OIDC)返回的用户标识。
服务账号(ServiceAccount)
集群内 Pod 使用的内置账号:
- 每个 Namespace 自动生成默认的
defaultServiceAccount。 - 令牌通过 Secret 挂载到 Pod 的
/var/run/secrets/kubernetes.io/serviceaccount。 - 通过
kubectl create serviceaccount <name>创建自定义 ServiceAccount。
认证流程示例
用户通过kubectl访问
kubectl使用~/.kube/config中的客户端证书或令牌。- 请求到达
kube-apiserver,验证证书/令牌的合法性(如 CA 签名、有效期)。 - 认证成功后,提取证书中的
CN=system:admin或令牌关联的 ServiceAccount 作为身份标识。
Pod 内部访问 API Server
- Pod 自动挂载的 ServiceAccount Token 被注入请求头。
kube-apiserver验证 Token 是否由集群的 CA 签发,并关联到有效的 ServiceAccount。
关键配置与实践
启用多认证插件
在kube-apiserver启动参数中指定:
--client-ca-file=/path/to/ca.crt # 客户端 CA 根证书 --token-auth-file=/path/to/tokens.csv # 静态令牌文件(格式:token,user,group) --oidc-issuer-url=https://oidc.provider # 集成 OIDC 身份提供商ServiceAccount 令牌管理
自动生成的令牌为 JWT 格式,可通过以下命令查看:
kubectl get secret <serviceaccount-token-name> -o jsonpath='{.data.token}' | base64 --decode调试认证问题
使用kubectl的--v=6参数查看详细认证过程:
kubectl get pods -v=6通过以上机制,Kubernetes 实现了灵活的身份认证体系,支持从集群内到集群外的多种访问场景。
ServiceAccount 与 User account 的区别
ServiceAccount 是为 Pod 中的进程设计的,用于调用 Kubernetes API 或其他外部服务。User account 是为现实中的人设计的,用于登录和操作 Kubernetes 集群。
ServiceAccount 局限于其所在的 namespace,而 User account 是跨 namespace 的。每个 namespace 会自动创建一个 default service account。
ServiceAccount 的自动配置
开启 ServiceAccount Admission Controller 后,每个 Pod 在创建时会自动设置spec.serviceAccount为 default,除非指定了其他 ServiceAccount。系统会验证 Pod 引用的 ServiceAccount 是否存在,否则拒绝创建。
如果没有为 Pod 指定 ServiceAccount,系统会在同一 namespace 下自动指派一个 default service account。这个账号用于 Pod 与 apiserver 之间的通信。
查看 Pod 的 ServiceAccount
使用以下命令可以查看 Pod 的 ServiceAccount 配置:
kubectl get pod <pod-name> -o yaml输出中会包含类似以下内容:
spec: serviceAccountName: default创建自定义 ServiceAccount
可以手动创建 ServiceAccount 并指定给 Pod:
kubectl create serviceaccount <serviceaccount-name>然后在 Pod 的配置中指定该 ServiceAccount:
apiVersion: v1 kind: Pod metadata: name: mypod spec: serviceAccountName: <serviceaccount-name> containers: - name: mycontainer image: nginxServiceAccount 的权限控制
ServiceAccount 的权限通过 Role 和 RoleBinding 或 ClusterRole 和 ClusterRoleBinding 来控制。可以为 ServiceAccount 分配特定的权限,限制其对集群资源的访问。
创建 Role 和 RoleBinding 的示例:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods subjects: - kind: ServiceAccount name: <serviceaccount-name> roleRef: kind: Role name: pod-reader默认 ServiceAccount 的令牌
每个 ServiceAccount 会自动生成一个 token,存储在 secret 中。Pod 可以通过挂载该 token 来访问 apiserver:
kubectl get secret <serviceaccount-token-secret> -o yamlPod 会自动挂载 default service account 的 token 到/var/run/secrets/kubernetes.io/serviceaccount。
[root@k8s-master01 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE mysql-pod-volume 1/1 Running 0 43m nfs-provisioner-cd5589cfc-c8vc5 1/1 Running 0 13h pod-secret 1/1 Running 0 18m web-0 1/1 Running 0 13h web-1 1/1 Running 0 13h[root@k8s-master01 ~]# kubectl get pods web-0 -o yaml | grep "serviceAccountName" serviceAccountName: default [root@k8s-master01 ~]# kubectl describe pods web-0 Volumes: www: Type: PersistentVolumeClaim ClaimName: www-web-0 default-token-cq5qp: Type: Secret (a volume populated by a Secret) SecretName: default-token-cq5qp Optional: false从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-***。pod和apiserver的认证信息通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 serviceaccount 资源。查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。
[root@k8s-master01 ~]# kubectl get sa NAME SECRETS AGE default 1 12d [root@k8s-master01 ~]# kubectl get secret NAME TYPE DATA AGE default-token-cq5qp kubernetes.io/service-account-token 3 12d创建和管理 ServiceAccount
在 Kubernetes 中,ServiceAccount 用于为 Pod 提供身份认证,使其能够访问 API Server。默认的 ServiceAccount 权限有限,如需扩展权限,需手动创建并绑定角色。
创建 ServiceAccount
kubectl create serviceaccount test查看 ServiceAccount 详细信息
kubectl describe sa test此操作会生成一个关联的 Secret(如test-token-hnc57),其中包含用于认证的 Token。
查看 Secret 信息
kubectl get secret kubectl describe secret test-token-hnc57生成的 Token 是 ServiceAccount 连接 API Server 的认证凭证,但仅凭 Token 无操作权限,需进一步授权。
为 ServiceAccount 授权
通过 RoleBinding 或 ClusterRoleBinding 将角色权限绑定到 ServiceAccount,赋予其访问特定资源的权限。
创建 Role 或 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-manager rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"]绑定角色到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: test-pod-access subjects: - kind: ServiceAccount name: test namespace: default roleRef: kind: ClusterRole name: pod-manager apiGroup: rbac.authorization.k8s.io在 Pod 中使用自定义 ServiceAccount
通过serviceAccountName字段指定 Pod 使用的 ServiceAccount。
示例 Pod 定义
apiVersion: v1 kind: Pod metadata: name: test-pod spec: serviceAccountName: test containers: - name: nginx image: nginx使用 kubeconfig 文件管理认证
kubeconfig 文件保存集群认证信息,可通过kubectl config管理。ServiceAccount 的 Token 也可用于生成 kubeconfig。
提取 Token 并生成 kubeconfig
TOKEN=$(kubectl get secret test-token-hnc57 -o jsonpath='{.data.token}' | base64 --decode) kubectl config set-credentials test-user --token=$TOKEN kubectl config set-context test-context --cluster=<cluster-name> --user=test-user kubectl config use-context test-context此方法适用于将 ServiceAccount 认证信息集成到外部工具或脚本中。
Kubernetes RBAC 授权机制详解
Kubernetes 的 RBAC(Role-Based Access Control)是一种细粒度的权限管理机制,通过角色绑定实现用户或服务账号的权限分配。
RBAC 核心组件
RBAC 授权模型包含以下关键资源对象:
- Role:定义在特定命名空间内的权限集合,例如对 Pod 的读写权限
- ClusterRole:全局权限定义,可作用于整个集群
- RoleBinding:将 Role 绑定到用户/组/服务账号(限于命名空间内)
- ClusterRoleBinding:将 ClusterRole 绑定到全局对象
典型权限定义示例:
# Role 示例 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]授权流程
用户通过认证后,API Server 会执行以下授权检查:
- 检查请求中的用户/服务账号信息
- 查询关联的 RoleBinding/ClusterRoleBinding
- 验证绑定的 Role/ClusterRole 是否包含请求的操作权限
- 通过策略引擎评估权限规则
权限配置实践
创建 RoleBinding 将角色与用户关联:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: User name: "user1" apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io权限验证方法
使用 kubectl 检查用户权限:
kubectl auth can-i create deployments --as system:serviceaccount:default:deploy-sa kubectl get pods --kubeconfig=./config其他授权模式对比
- Node 授权:专门用于 kubelet 访问 API Server
- ABAC:基于静态策略文件的权限控制(已逐渐淘汰)
- Webhook:通过外部 HTTP 服务进行权限决策
RBAC 已成为 Kubernetes 生产环境的标准授权方案,建议新集群优先采用此机制。权限配置应遵循最小权限原则,避免过度授权。
权限管理基础
权限管理是系统安全的核心组成部分,涉及用户角色分配、资源访问控制及操作限制。常见的权限模型包括RBAC(基于角色的访问控制)和ABAC(基于属性的访问控制)。
用户角色定义
明确系统中不同角色的职责与权限范围。例如管理员拥有全局配置权限,普通用户仅能访问个人数据。角色划分需遵循最小权限原则,避免过度授权。
访问控制策略
实施细粒度的访问控制策略,如读写执行权限分离。通过ACL(访问控制列表)或Capability-based机制,确保用户只能操作授权范围内的资源。
权限继承与组合
支持权限继承机制,子角色自动继承父角色的基础权限。同时允许权限叠加,满足临时提升权限的场景需求,但需记录审计日志。
动态权限调整
提供运行时权限修改能力,响应突发需求变更。权限变动应触发实时生效机制,并同步通知受影响用户,避免操作中断。
审计与合规
记录所有权限变更操作及访问行为,生成可视化审计报告。定期检查权限分配合规性,识别并修复异常授权配置。
技术实现示例
# RBAC模型示例代码 class User: def __init__(self, roles): self.roles = roles class Role: def __init__(self, permissions): self.permissions = permissions class Permission: def __init__(self, resource, action): self.resource = resource self.action = action安全最佳实践
定期轮换高权限账户凭证,实施多因素认证。敏感操作需二次验证,关键系统保留权限变更的回滚能力。
RBAC 核心组件关系
Role
定义在特定命名空间内的权限集合,仅对所属命名空间的资源有效。例如创建名为role1的角色并赋予 Pod 的读写权限,该权限仅作用于role1所在的命名空间。
RoleBinding
将用户、组或服务账户绑定到Role,权限范围限于绑定所在的命名空间。例如user1通过RoleBinding绑定到role1,则user1仅能在role1的命名空间内执行授权操作。
集群级授权机制
ClusterRole
定义集群范围的权限,可作用于:
- 集群级别的资源(如节点、持久卷)。
- 所有命名空间内的资源(如跨命名空间的 Pod 读写)。
- 非资源型 API(如
/healthz)。
ClusterRoleBinding
将主体(用户、组或服务账户)绑定到ClusterRole,授予其全局权限。例如user2通过ClusterRoleBinding绑定到cluster-admin,则user2拥有集群管理员权限。
关键区别
作用域
Role+RoleBinding:命名空间级别。ClusterRole+ClusterRoleBinding:集群级别。
跨命名空间权限ClusterRole可通过RoleBinding在特定命名空间内授权。例如:
- 创建
ClusterRole定义 Pod 读权限。 - 在命名空间
ns1中使用RoleBinding绑定该ClusterRole到user3,则user3仅在ns1中拥有 Pod 读权限。
典型应用场景
命名空间隔离
开发团队使用Role限制其命名空间内的资源操作,避免影响其他团队。
集群管理
运维人员通过ClusterRole获得节点、存储等全局资源的管理权限。
只读监控
定义ClusterRole允许读取所有命名空间的资源,供监控工具使用。
YAML 示例
命名空间角色与绑定
# Role apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: ns1 name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"] # RoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: ns1 name: read-pods subjects: - kind: User name: user1 apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io集群角色与绑定
# ClusterRole apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-admin rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] # ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-binding subjects: - kind: User name: user2 apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.ioRoleBinding 绑定 ClusterRole 的优势
使用 RoleBinding 绑定 ClusterRole 可以显著减少权限管理的复杂性。例如,当多个命名空间需要相同的管理员权限时,只需定义一个 ClusterRole 并授予所有权限,然后通过 RoleBinding 在每个命名空间内绑定该 ClusterRole。这样避免了为每个命名空间重复定义 Role 和 RoleBinding。
RoleBinding 的作用范围仅限于当前命名空间,即使绑定了 ClusterRole,用户也仅拥有当前命名空间内的权限。这种方式既实现了权限复用,又保证了权限隔离。
ServiceAccount 与 UserAccount 的区别
Kubernetes 中的账户分为两类:
- UserAccount:供集群外部用户使用,例如运维人员或管理员。通过 kubeconfig 文件(如
~/.kube/config)存储认证信息,kubectl 工具会自动读取该文件以完成 API Server 的认证。 - ServiceAccount:供集群内部资源(如 Pod)使用,用于自动化流程或服务间的权限控制。
kubeconfig 中的用户信息
kubeconfig 文件包含访问集群的认证配置,用户名称和密钥信息可在该文件中查看。例如,kubeadm 安装的集群默认用户为kubernetes-admin,其权限通过 ClusterRoleBinding 关联到高权限 ClusterRole(如cluster-admin)。