安全
Kubernetes 中的用户
1、所有 Kubernetes 集群都有两类用户
(1)由 Kubernetes 管理的服务账号
(2)普通用户
2、Kubernetes 假定普通用户是由一个与集群无关的服务通过以下方式之一进行管理的
(1)负责分发私钥的管理员
(2)类似 Keystone 或者 Google Accounts 这类用户数据库
(3)包含用户名和密码列表的文件
3、有鉴于此,Kubernetes 并不包含用来代表普通用户账号的对象,普通用户的信息无法通过 API 调用添加到集群中
(1)尽管无法通过 API 调用来添加普通用户,Kubernetes 仍然认为能够提供由集群的证书机构签名的合法证书的用户是通过身份认证的用户
(2)基于这样的配置,Kubernetes 使用证书中的 'subject' 的通用名称(Common Name)字段 (例如,"/CN=bob")来确定用户名
(3)接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对某资源执行特定的操作
4、与此不同,服务账号是 Kubernetes API 所管理的用户
(1)它们被绑定到特定的命名空间,或者由 API 服务器自动创建,或者通过 API 调用创建
(2)服务账号与一组以 Secret 保存的凭据相关,这些凭据会被挂载到 Pod 中,从而允许集群内的进程访问 Kubernetes API
5、API 请求则或者与某普通用户相关联,或者与某服务账号相关联,亦或者被视作匿名请求
(1)这意味着集群内外的每个进程在向 API 服务器发起请求时都必须通过身份认证,否则会被视作匿名用户
(2)这里的进程可以是在某工作站上输入 kubectl 命令的操作人员,也可以是节点上的 kubelet 组件,还可以是控制面的成员
认证
1、建立 TLS 后,HTTP 请求将进入认证(Authentication)步骤
2、集群创建脚本或者集群管理员配置 API 服务器,使之运行一个或多个身份认证组件
(1)认证步骤的输入整个 HTTP 请求;但是,通常组件只检查头部(或 / 和)客户端证书
(2)认证模块包含客户端证书、密码、普通令牌、引导令牌、JSON Web 令牌(JWT,用于服务账户)
(3)可以指定多个认证模块,在这种情况下,服务器依次尝试每个验证模块,直到其中一个成功
(4)如果请求认证不通过,服务器将以 HTTP 状态码 401 拒绝该请求
(5)反之,该用户被认证为特定的 username,并且该用户名可用于后续步骤以在其决策中使用
(6)部分验证器还提供用户的组成员身份,其他则不提供
3、Kubernetes 通过身份认证插件利用客户端证书、持有者令牌(Bearer Token)或身份认证代理(Proxy)来认证 API 请求的身份
(1)可以同时启用多种身份认证方法,并且通常会至少使用两种方法:针对服务账号使用服务账号令牌、至少另外一种方法对用户的身份进行认证
(2)当集群中启用了多个身份认证模块时,第一个成功地对请求完成身份认证的模块会直接做出评估决定
(3)API 服务器并不保证身份认证模块的运行顺序
(4)与其它身份认证协议(LDAP、SAML、Kerberos、X509 的替代模式等等)都可以通过使用一个身份认证代理或身份认证 Webhoook 来实现
4、身份认证策略
(1)X509 客户证书:通过给 API 服务器传递 --client-ca-file=SOMEFILE 选项,就可以启动客户端证书身份认证
(2)静态令牌文件:当 API 服务器的命令行设置了 --token-auth-file=SOMEFILE 选项时,会从文件中读取持有者令牌
(3)启动引导令牌:为了支持平滑地启动引导新的集群,Kubernetes 包含了一种动态管理的持有者令牌类型,称作启动引导令牌(Bootstrap Token)
(4)服务账号令牌:服务账号(Service Account)是一种自动被启用的用户认证机制,使用经过签名的持有者令牌来验证请求
(5)OpenID Connect(OIDC)令牌:OpenID Connect 是一种 OAuth2 认证方式,被某些 OAuth2 提供者支持,例如:Azure 活动目录、Salesforce、Google
(6)Webhook 令牌身份认证:Webhook 身份认证是一种用来验证持有者令牌的回调机制
(7)身份认证代理:API 服务器可以配置成从请求的头部字段值(如 X-Remote-User)中辩识用户。这一设计是用来与某身份认证代理一起使用 API 服务器,代理负责设置请求的头部字段值
鉴权
1、将请求验证为来自特定的用户后,请求必须被鉴权
(1)请求必须包含请求者的用户名、请求的行为以及受该操作影响的对象
(2)如果现有策略声明用户有权完成请求的操作,那么该请求被鉴权通过
鉴权模块
1、Node
(1)一个专用鉴权模式,根据调度到 kubelet 上运行的 Pod 为 kubelet 授予权限
(2)节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求进行授权
2、ABAC
(1)基于属性的访问控制(ABAC)定义了一种访问控制范型,通过使用将属性组合在一起的策略,将访问权限授予用户
(2)策略可以使用任何类型的属性(用户属性、资源属性、对象,环境属性等)
3、RBAC
(1)基于角色(Role)的访问控制(RBAC)是一种基于企业内个人用户的角色来管理对计算机或网络资源的访问的方法
(2)在此上下文中,权限是单个用户执行特定任务的能力,例如:查看、创建、修改文件
(3)被启用之后,RBAC(基于角色的访问控制)使用 rbac.authorization.k8s.io API 组来驱动鉴权决策,从而允许管理员通过 Kubernetes API 动态配置权限策略
(4)要启用 RBAC,在启动 API 服务器时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC
kube-apiserver --authorization-mode=Example,RBAC --<其他选项> --<其他选项>
4、Webhook
(1)WebHook 是一种 HTTP 回调,某些条件下触发的 HTTP POST 请求,通过 HTTP POST 发送的简单事件通知
(2)一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL
(3)具体来说,当在判断用户权限时,Webhook 模式会使 Kubernetes 查询外部的 REST 服务
RBAC API 声明了四种 Kubernetes 对象
1、Role、ClusterRole、RoleBinding、ClusterRoleBinding
2、可以像使用其他 Kubernetes 对象一样,通过类似 kubectl 这类工具描述对象,或修补对象
Role 和 ClusterRole
1、RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则,这些权限是纯粹累加的(不存在拒绝某操作的规则)
(1)Role 总是用来在某个命名空间内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的命名空间
(2)与之相对,ClusterRole 则是一个集群作用域的资源
(3)这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是命名空间作用域的,要么是集群作用域的,不可两者兼具
2、ClusterRole 有若干用法
(1)定义对某命名空间域对象的访问权限,并将在个别命名空间内被授予访问权限
(2)为命名空间作用域的对象设置访问权限,并被授予跨所有命名空间的访问权限
(3)为集群作用域的资源定义访问权限
3、如果你希望在命名空间内定义角色,应该使用 Role;如果你希望定义集群范围的角色,应该使用 ClusterRole
4、ClusterRole 同样可以用于授予 Role 能够授予的权限。因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限
(1)集群范围资源,比如:节点(Node)
(2)非资源端点,比如:/healthz
(3)跨命名空间访问的命名空间作用域的资源,如:Pod
5、Role 或 ClusterRole 对象的名称必须是合法的路径分段名称
RoleBinding 和 ClusterRoleBinding
1、角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户
(1)它包含若干主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用
(2)RoleBinding 在指定的命名空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权
2、一个 RoleBinding 可以引用同一的命名空间中的任何 Role
(1)或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的命名空间
(2)如果你希望将某 ClusterRole 绑定到集群中所有命名空间,你要使用 ClusterRoleBinding
3、RoleBinding 或 ClusterRoleBinding 对象的名称必须是合法的路径分段名称
4、RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在命名空间的资源。这种引用使得你可以跨整个集群定义一组通用的角色,之后在多个命名空间中复用
5、要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding
准入控制器
1、一段代码,它会在请求通过认证和鉴权之后、对象被持久化之前拦截到达 API 服务器的请求
2、准入控制器可以执行验证(Validating) (和 / 或)变更(Mutating) 操作
(1)变更(mutating)控制器可以根据被其接受的请求更改相关对象
(2)验证(validating)控制器则不行
3、准入控制器限制创建、删除、修改对象的请求
(1)准入控制器也可以阻止自定义动作,例如:通过 API 服务器代理连接到 Pod 的请求
(2)准入控制器不会 (也不能)阻止读取(get、watch 或 list)对象的请求
(3)准入控制器编译进 kube-apiserver 可执行文件,并且只能由集群管理员配置
4、准入控制过程分为两个阶段
(1)第一阶段,运行变更准入控制器
(2)第二阶段,运行验证准入控制器
(3)某些控制器既是变更准入控制器,又是验证准入控制器
(4)如果两个阶段之一的任何一个控制器拒绝了某请求,则整个请求将立即被拒绝,并向最终用户返回错误
(5)最后,除了对对象进行变更外,准入控制器还可能有其它副作用:将相关资源作为请求处理的一部分进行变更。增加配额用量就是一个典型的示例,说明了这样做的必要性。此类用法都需要相应的回收或回调过程,因为任一准入控制器都无法确定某个请求能否通过所有其它准入控制器
5、如何启用一个准入控制器
(1)Kubernetes API 服务器的 enable-admission-plugins 标志接受一个(以逗号分隔的)准入控制插件列表, 这些插件会在集群修改对象之前被调用
kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger ...
(2)根据你 Kubernetes 集群的部署方式以及 API 服务器的启动方式,你可能需要以不同的方式应用设置。例如,如果将 API 服务器部署为 systemd 服务,你可能需要修改 systemd 单元文件;如果以自托管方式部署 Kubernetes,你可能需要修改 API 服务器的清单文件
6、怎么关闭准入控制器
(1)Kubernetes API 服务器的 disable-admission-plugins 标志,会将传入的(以逗号分隔的) 准入控制插件列表禁用,即使是默认启用的插件也会被禁用
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny ...
7、查看默认启用的插件
kube-apiserver -h | grep enable-admission-plugins
(1)在 Kubernetes 1.26 中,默认启用的插件有:CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, LimitRanger, MutatingAdmissionWebhook, NamespaceLifecycle, PersistentVolumeClaimResize, PodSecurity, Priority, ResourceQuota, RuntimeClass, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionPolicy, ValidatingAdmissionWebhook
(2)在该列表中,有两个特殊的控制器:MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。 它们根据 API 中的配置, 分别执行变更和验证准入控制 webhook
(3)ValidatingAdmissionPolicy 准入插件默认被启用, 但只有启用 ValidatingAdmissionPolicy 特性门控 和 admissionregistration.k8s.io/v1alpha1 API 时才会激活
8、每个准入控制器的作用
(1)AlwaysAdmit:该准入控制器允许所有的 Pod 进入集群。此插件已被弃用,因其行为与没有准入控制器一样
(2)AlwaysDeny:拒绝所有的请求。由于它没有实际意义,已被弃用
(3)AlwaysPullImages:该准入控制器会修改每个新创建的 Pod,将其镜像拉取策略设置为 Always
(4)CertificateApproval:此准入控制器获取审批 CertificateSigningRequest 资源的请求,并执行额外的鉴权检查,
(5)CertificateSigning:此准入控制器监视对 CertificateSigningRequest 资源的 status.certificate 字段的更新请求, 并执行额外的鉴权检查
(6)CertificateSubjectRestriction:此准入控制器监视 spec.signerName 被设置为 kubernetes.io/kube-apiserver-client 的 CertificateSigningRequest 资源创建请求,并拒绝所有将 “group”(或 “organization attribute”) 设置为 system:masters 的请求
(7)DefaultIngressClass:该准入控制器监测没有请求任何特定 Ingress 类的 Ingress 对象创建请求,并自动向其添加默认 Ingress 类
(8)DefaultStorageClass:此准入控制器监测没有请求任何特定存储类的 PersistentVolumeClaim 对象的创建请求,并自动向其添加默认存储类
(9)DefaultTolerationSeconds:此准入控制器基于 k8s-apiserver 的输入参数 default-not-ready-toleration-seconds 和 default-unreachable-toleration-seconds 为 Pod 设置默认的容忍度,以容忍 notready:NoExecute 和 unreachable:NoExecute 污点 (如果 Pod 尚未容忍 node.kubernetes.io/not-ready:NoExecute 和 node.kubernetes.io/unreachable:NoExecute 污点的话),默认为 5 分钟
(10)DenyServiceExternalIPs:此准入控制器拒绝新的 Service 中使用字段 externalIPs
(11)EventRateLimit:此准入控制器缓解了请求存储新事件时淹没 API 服务器的问题
审计
1、Kubernetes 审计(Auditing)提供了一套与安全相关的、按时间顺序排列的记录,其中记录了集群中的操作序列
2、集群对用户、使用 Kubernetes API 的应用程序以及控制平面本身产生的活动进行审计
3、审计功能使得集群管理员能够回答以下问题
(1)发生了什么?
(2)什么时候发生的?
(3)谁触发的?
(4)活动发生在哪个(些)对象上?
(5)在哪观察到的?
(6)它从哪触发的?
(7)活动的后续处理行为是什么?
4、审计记录最初产生于 kube-apiserver 内部
(1)每个请求在不同执行阶段都会生成审计事件
(2)这些审计事件会根据特定策略被预处理并写入后端
(3)策略确定要记录的内容和用来存储记录的后端
(4)当前的后端支持日志文件和 webhook
5、每个请求都可被记录其相关的阶段(stage)。已定义的阶段有:
(1)RequestReceived - 此阶段对应审计处理器接收到请求后,并且在委托给 其余处理器之前生成的事件
(2)ResponseStarted - 在响应消息的头部发送后,响应消息体发送前生成的事件。 只有长时间运行的请求(例如 watch)才会生成这个阶段
(3)ResponseComplete - 当响应消息体完成并且没有更多数据需要传输的时候
(4)Panic - 当 panic 发生时生成
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战