目录
3.2角色绑定(RoleBinding)和集群角色(ClusterRoleBinding)
3.7RoleBinding 和 ClusterRoleBinding示例
4.1如何在Role中定义规则以控制对资源及其子资源的访问权限的示例
一、安全机制
Kubernetes的安全机制非常关键,因为它确保了集群的稳定性和数据的安全。
认证----->授权----->准入控制(Adminationcontroller)
1.认证(Authenticating)
是对客户端的认证,通俗点就是用户名密码验证
这是安全机制的第一道防线。它负责确认请求者的身份。在 Kubernetes 中,认证通常通过以下几种方式实现
- 客户端证书:用户或服务可以通过客户端证书进行身份验证。
- Bearer Tokens:用户可以获取一个令牌(Token),并在请求中携带这个令牌。
- 基本认证:使用用户名和密码进行基本的 HTTP 认证。
- SSH 密钥:对于某些操作,如节点登录,可以使用 SSH 密钥进行认证。
2.授权(Authorization)
是对资源的授权,k8s 中的资源无非是容器,最终其实就是容器的计算,网络,存储资源,当一个请求经过认证后,需要访问某一个资源(比如创建一个pod),授权检查会根据授权规则判定该资源(比如某namespace 下的 pod)是否是该客户可访问的。
一旦用户或服务通过认证,下一步就是确定他们有哪些权限。Kubernetes 提供了几种鉴权机制
- Role-Based Access Control (RBAC):这是 Kubernetes 最常用的鉴权方式,它允许管理员定义角色(Role)和角色绑定(RoleBinding),以控制对资源的访问。
- Attribute-Based Access Control (ABAC):这是一种更细粒度的鉴权方式,它基于用户、资源和操作的属性来决定访问权限。
- Webhook 鉴权:允许调用外部服务来决定访问权限。
3.准入(Admission Control)机制
准入控制器(Admission Controller)位于 APIServer 中,在对象被持久化之前,准入控制器拦截对 APlServer 的请求,一般用来做身份验证和授权。其中包含两个特殊的控制器:MutatingAdmissionWebhook和 ValidatingAdmissionWebhook。分别作为配置的变异和验证准入控制 webhook。变更(Mutating)准入控制:修改请求的对象验证(Validating)准入控制:验证请求的对象
即使请求者通过了认证和鉴权,准入控制还会在资源被创建或修改之前进行最后的检查。这是为了确保资源的创建符合集群的策略和规范。准入控制器可以包括
- MutatingWebhook:在资源被持久化之前,可以修改资源对象。
- ValidatingWebhook:验证资源对象是否符合集群的策略和规范。
- ResourceQuota:限制资源的使用量,如 CPU、内存和存储。
- NamespaceLifecycle:管理命名空间的生命周期。
这些机制共同工作,确保了 Kubernetes 集群的安全性。管理员可以根据集群的需求和安全策略来配置这些机制。
二、认证
这些认证方式确保了只有合法的用户和服务能够与 Kubernetes API Server 进行交互
1.认证方式
- HTTP Token 认证:
- 客户端需要获取一个 Token,这个 Token 通常是由 Kubernetes API Server 生成并存储在一个安全的地方。
- 客户端在发起请求时,将这个 Token 放在 HTTP 请求的头部(Header)中,通常是 Authorization 字段。
- API Server 会验证这个 Token 是否有效,以及对应的用户是否有权进行请求的操作。
- HTTP Basic 认证:
- 用户名和密码组合使用 Base64 编码后,形成一串编码字符串。
- 这串编码字符串被放在 HTTP 请求的 Authorization 头部中,以 Basic 开头。
- API Server 解码后验证用户名和密码的正确性。
- HTTPS 证书认证:
- 这是一种更为安全的认证方式,通常用于服务之间的通信。
- 客户端和服务器都需要有由可信的证书颁发机构(CA)签发的 SSL/TLS 证书。
- 在建立 HTTPS 连接时,双方会交换并验证对方的证书,确保通信双方的身份。
- 这种方式不仅能够验证客户端的身份,还能验证服务器的身份,实现双向认证(Mutual TLS, mTLS)。
2.总结
Token 和 Basic 认证主要是单向的,即只能验证客户端对服务器的身份。而 HTTPS 证书认证可以实现双向认证,这对于需要确保通信双方身份的场景非常重要,比如在 Kubernetes API Server 与 etcd 或其他组件之间的通信中。使用 HTTPS 证书认证可以防止中间人攻击,确保数据传输的安全性。
3.认证机制框架和相关组件
- 需要被认证的访问类型:
- Kubernetes 组件(如 kubectl、kubelet、kube-proxy)需要与 API Server 通信,这些通信需要通过认证。
- Kubernetes 管理的 Pod(如 coredns、dashboard)也需要访问 API Server,同样需要认证。
- 安全性说明:
- 控制平面组件(Controller Manager、Scheduler)通常与 API Server 运行在同一台机器上,因此它们可以直接使用非安全端口(如 8080)进行通信。
- 对于需要远程访问 API Server 的组件(如 kubectl、kubelet、kube-proxy),则需要使用 HTTPS 双向认证,通常通过 6443 端口进行。
- 证书颁发:
- 在二进制部署 Kubernetes 时,可能需要手动签发 HTTPS 证书。
- 在 Kubernetes 自动化部署的环境中,kubelet 首次访问 API Server 时使用 Token 进行认证,之后 Controller Manager 会为 kubelet 生成证书,kubelet 使用这个证书进行后续的认证。
- kubeconfig:
- kubeconfig 文件包含了集群的访问参数(如 CA 证书、API Server 地址)和客户端认证信息(如证书和私钥)。
- kubeconfig 文件还包含了集群上下文参数,允许用户在不同的集群之间切换。
- kubectl 使用的 kubeconfig 文件通常位于用户的主目录下的 .kube/config。
- Service Account:
- Service Account 是 Kubernetes 中的一个资源对象,用于代表 Pod 中的容器访问 API Server。
- Service Account 允许 Pod 以一种安全的方式获取访问令牌(Token),而不需要为每个 Pod 单独生成证书。
- Secret 与 Service Account 的关系:
- Kubernetes 中的 Secret 资源对象用于存储敏感信息,如密码、OAuth 令牌和 ssh 密钥。
- Service Account 相关的 Secret 包含了用于认证的 Token,这些 Token 被 Pod 中的容器用来访问 API Server。
- Opaque 类型的 Secret 用于存储任意的非结构化数据,这些数据可以由用户自定义。
这些机制共同构成了 Kubernetes 的安全框架,确保了集群的管理和操作都是安全可控的。通过这些机制,Kubernetes 能够为不同的组件和服务提供适当的认证和授权,同时保持操作的灵活性和便利性。
4.Service Account访问权限机制
Service Account 是 Kubernetes 中用于提供对 API Server 的访问权限的机制。它允许 Pod 中的容器以该 Service Account 的身份进行操作,而无需为每个 Pod 单独创建和管理认证凭据。
4.1Service Account通常包含以下三个部分
- Token:
- 这是一个由 API Server 的私钥签名的 Token 字符串序列号。
- 当 Pod 中的容器需要与 API Server 通信时,可以使用这个 Token 进行认证。
- API Server 会使用其私钥来验证这个 Token 的有效性。
- ca.crt:
- 这是 API Server 的 CA 根证书。
- Pod 中的容器使用这个证书来验证 API Server 发送来的证书,确保通信的安全性。
- 这是双向 TLS(mTLS)认证的一部分,确保了通信双方的身份验证。
- Namespace:
- 这个字段标识了 Service Account 所属的命名空间。
- Service Account 通常与特定的命名空间关联,这限制了它的作用范围。
默认情况下,每个命名空间都会自动创建一个名为 default 的 Service Account。如果 Pod 在创建时没有指定 Service Account,它将默认使用其所属命名空间的 default Service Account。这允许 Pod 以该命名空间的权限进行操作。
kubectl get sa
#显示了当前命名空间中的 Service Account 列表。在这个例子中,default Service Account 已经存在了 18天,并且有一个与之关联的 Secret。这个 Secret 包含了上述提到的 Token 和 CA 证书。
Service Account 的使用简化了 Pod 的认证流程,使得开发者和管理员可以更轻松地管理 Pod 的权限,同时保持集群的安全性。通过 Service Account,Kubernetes 能够为动态创建和销毁的 Pod 提供一种安全且灵活的认证机制。
当 Pod 在 Kubernetes 集群中启动时,它会从与它关联的 Service Account 获取必要的认证信息,并将其挂载到特定的目录 /var/run/secrets/kubernetes.io/serviceaccount/
。这个目录包含了三个关键文件
- ca.crt:这是 CA 根证书,用于验证 API Server 的身份。Pod 中的容器在与 API Server 通信时,会使用这个证书来确保它们正在与合法的 API Server 通信。
- namespace:这是一个文件,包含了 Pod 所属的命名空间。这个信息对于 API Server 来说很重要,因为它决定了 Pod 可以访问的资源范围。
- token:这是一个由 API Server 签发的 Token,用于在 API Server 进行身份验证。当 Pod 中的容器需要访问 API Server 时,它会使用这个 Token 来证明自己的身份。
kubectl get pod -n kube-system
#显示了 kube-system 命名空间中的 Pod 列表。这些 Pod 包括了 Kubernetes 控制平面组件和其他关键组件。每个 Pod 都会挂载其关联 Service Account 的认证信息。
kubectl exec -it kube-proxy-mgtvt -n kube-system sh
ls /var/run/secrets/kubernetes.io/serviceaccount/
#列出了挂载的认证信息文件,这证实了每个 Pod 都能够访问其 Service Account 的认证信息。
这种机制确保了 Pod 能够安全地与 API Server 通信,同时也使得 Pod 的管理和认证过程更加自动化和透明。
三、鉴权
鉴权(Authorization)是 Kubernetes 安全机制中的一个关键环节,它决定了用户或系统组件在通过认证后能够执行哪些操作。鉴权策略定义了对资源的访问权限,确保只有具有适当权限的用户或服务可以访问或修改资源。
1.授权策略
- AlwaysDeny:
- 这种策略会拒绝所有的请求,无论请求的内容是什么。
- 通常用于测试环境,以确保在开发或调试过程中不会有意外的资源访问。
- AlwaysAllow:
- 这种策略允许所有的请求,不对请求进行任何权限检查。
- 这同样通常用于测试环境,或者在不需要进行权限控制的情况下。
- ABAC(Attribute-Based Access Control):
- ABAC 是一种细粒度的访问控制策略,它基于用户、资源和操作的属性来决定访问权限。
- 管理员可以定义复杂的规则,这些规则考虑了用户的属性(如角色、部门)和资源的属性(如标签、注解)。
- ABAC 提供了高度的灵活性,但配置起来可能比较复杂。
- Webhook:
- Webhook 鉴权策略允许 API Server 调用外部的 RESTful 服务来决定是否允许请求。
- 这种方式可以与现有的身份管理系统(如 LDAP、OAuth 服务器)集成,实现集中化的鉴权管理。
- Webhook 鉴权策略提供了一种灵活的方式来扩展 Kubernetes 的鉴权能力。
- RBAC(Role-Based Access Control):
- RBAC 是 Kubernetes 自 1.6 版本起默认的鉴权模式。
- 在 RBAC 中,管理员可以定义角色(Role)和角色绑定(RoleBinding)。
- 角色定义了一组权限,而角色绑定则将角色分配给用户或用户组。
- RBAC 提供了一种结构化的方式来管理权限,使得权限的分配和审计更加清晰和容易。
在实际部署中,RBAC 是最常用的鉴权策略,因为它提供了一种既灵活又易于管理的方式来控制对 Kubernetes 资源的访问。通过定义角色和角色绑定,管理员可以精确地控制不同用户和组件的权限,从而保护集群的安全。
2.RBAC 管理用户和组对资源访问权限机制
RBAC(Role-Based Access Control)是 Kubernetes 中用于管理用户和组对资源访问权限的一种机制。与其他访问控制方式相比,RBAC 提供了更细粒度的权限控制,并且更加灵活和易于管理。
官方文档:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
2.1RBAC的优势
- 全面覆盖:RBAC 可以对集群中的资源(如 Pods、Deployments、Services)和非资源(如元信息或资源状态)进行访问控制。
- 动态管理:RBAC 的策略可以通过 Kubernetes API 动态配置和管理,无需重启 API Server。这与 ABAC(Attribute-Based Access Control)不同,ABAC 通常需要重启 API Server 来更新策略。
- 易于操作:RBAC 的配置完全通过 Kubernetes API 资源对象实现,可以使用 kubectl 或直接通过 API 与 API Server 交互。
2.2RBAC的API资源对象
- Role:定义了一组权限,这些权限适用于特定命名空间内的资源。Role 通常用于在单个命名空间内定义访问策略。
- ClusterRole:与 Role 类似,但 ClusterRole 是集群级别的资源,其定义的权限适用于整个集群范围内的资源。
- RoleBinding:将 Role 与用户、组或服务账户(ServiceAccount)绑定,从而授予这些主体(Subjects)在特定命名空间内的权限。
- ClusterRoleBinding:与 RoleBinding 类似,但 ClusterRoleBinding 将 ClusterRole 与主体绑定,授予主体在整个集群范围内的权限。
这些资源对象使得管理员可以灵活地定义和分配权限,以满足不同的安全需求。通过 Role 和 RoleBinding,可以在命名空间级别进行细粒度的访问控制;而通过 ClusterRole 和 ClusterRoleBinding,则可以实现跨命名空间的访问控制。
官方文档提供了关于 RBAC 的详细信息,包括如何创建和管理这些资源对象,以及如何使用它们来保护 Kubernetes 集群的资源。通过提供的链接,可以访问官方文档以获取更多关于 RBAC 的指导和最佳实践。
3.RBAC(基于角色的访问控制)的核心概念和组件
3.1角色(Role)和集群角色(ClusterRole)
- Role:定义了在特定命名空间内对资源的一组操作权限。Role 通常用于限制对单个命名空间内资源的访问。
- ClusterRole:与 Role 类似,但 ClusterRole 提供了跨命名空间的权限。它允许定义一组在整个集群范围内适用的权限。
如果使用 RoleBinding 绑定 ClusterRole,仍会受到命名空间的影响;如果使用 ClusterRoleBinding 绑定 ClusterRole, 将会作用于整个 K8S 集群。
3.2角色绑定(RoleBinding)和集群角色(ClusterRoleBinding)
- RoleBinding:将 Role 与一个或多个用户、组或服务账户(ServiceAccount)绑定,从而授予这些主体在特定命名空间内的权限。
- ClusterRoleBinding:与 RoleBinding 类似,但 ClusterRoleBinding 将 ClusterRole 与主体绑定,授予主体在整个集群范围内的权限。
3.3主体(Subject)
- User:代表一个用户,可以是集群外部的用户或集群内部的服务账户。
- Group:代表一组用户,可以是系统定义的组或自定义组。
- ServiceAccount:代表一个服务账户,它是 Kubernetes 内部的一个账户,通常用于 Pod 身份认证。
User 使用字符串表示,它的前缀 system: 是系统保留的,集群管理员应该确保普通用户不会使用这个前缀格式;Group 书写格式与 User 相同,同样 system: 前缀也为系统保留。
Pod使用 ServiceAccount 认证时,service-account-token 中的 JWT 会保存用户信息。 有了用户信息,再创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成权限绑定了。
3.4权限规则(Rules)
在 Role 或 ClusterRole 中定义的规则指定了哪些资源(如 Pods、Deployments)和哪些操作(如 get、watch、list)被允许。这些规则是累加的,意味着只有白名单权限,没有黑名单权限。
Role只能定义在一个NameSpace中,如果要跨NameSpace则可以创建ClusterRole,也就是说定义ClusterRole,不需要绑定NameSpace。
3.5Role示例
#Role 示例:
apiVersion: rbac.authorization.k8s.io/v1 #指定 core API 组和版本
kind: Role #指定类型为 Role
metadata:
namespace: default #使用默认命名空间
name: pod-reader #Role 的名称
rules: #定义规则
- apiGroups: [""] #""表示 apiGroups 和 apiVersion 使用相同的 core API 组,即 rbac.authorization.k8s.io
resources: ["pods"] #资源对象为 Pod 类型
verbs: ["get", "watch", "list"] #被授予的操作权限
#定义了一个名为 pod-reader 的角色,它允许用户在 default 命名空间中对 Pods 执行获取(get)、监听(watch)和列出(list)操作。
通过这些组件,Kubernetes 管理员可以精细地控制用户和系统组件对资源的访问,从而确保集群的安全性。RBAC 提供了一种声明式的权限管理方式,使得权限的分配和审计变得更加清晰和容易。
3.6ClusterRole示例
apiVersion: rbac.authorization.k8s.io/v1
#这里使用的是 rbac.authorization.k8s.io/v1,这是 RBAC API 的稳定版本。
kind: ClusterRole
#ClusterRole资源类型
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
#定义了角色的权限规则。
- apiGroups: [""]
#指定了 API 组,"" 表示核心 API 组
resources: ["secrets"]
#资源对象为 Secret 类型
verbs: ["get", "watch", "list"]
#指定允许的操作
#提供的 ClusterRole 示例定义了一个名为 secret-reader 的集群角色,这个角色授予了对 Kubernetes Secret 资源的读取(get)、观察(watch)和列出(list)权限。由于这是一个 ClusterRole,这些权限将适用于整个 Kubernetes 集群中的所有命名空间,而不仅仅是单个命名空间。
创建了 ClusterRole 之后,需要创建一个 ClusterRoleBinding 来将这个角色绑定到一个或多个主体(如用户、组或服务账户),从而授予它们相应的权限。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: User
name: "jane@example.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
#这个 ClusterRoleBinding 将 secret-reader 角色授予了用户 jane@example.com,使其能够在整个集群中读取 Secret 资源。
3.7RoleBinding 和 ClusterRoleBinding示例
RoloBinding 可以将角色中定义的权限授予用户或用户组,RoleBinding 包含一组主体(subject),subject 中包含有不同形式的待授予权限资源类型(User、Group、ServiceAccount);
RoloBinding 同样包含对被绑定的 Role 引用;
RoleBinding 适用于某个命名空间内授权,而 ClusterRoleBinding 适用于集群范围内的授权
3.7.1RoleBinding示例1
#RoleBinding 示例1:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: zhangsan
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
#这个 RoleBinding 将 pod-reader 角色授予了用户 zhangsan。
#由于 RoleBinding 在 default 命名空间中定义,因此 zhangsan 用户在 default 命名空间中具有 pod-reader 角色的权限。
3.7.2RoleBinding示例2
#RoleBinding 同样可以引用 ClusterRole 来对当前 namespace 内 User、Group 或 ServiceAccount 进行授权, 这种操作允许集群管理员在整个集群内定义一些通用的 ClusterRole,然后在不同的 namespace 中使用 RoleBinding 来引用。
#RoleBinding 示例2:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: kube-public
subjects:
- kind: User
name: lisi
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
#这个 RoleBinding 引用了一个 ClusterRole(secret-reader),这意味着它授予的权限是集群范围内的。
#尽管如此,由于 RoleBinding 在 kube-public 命名空间中定义,用户 lisi 只能访问 kube-public 命名空间中的 Secrets。
3.7.3ClusterRoleBinding示例
#ClusterRoleBinding 示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
#这个 ClusterRoleBinding 授予了 manager 组内的所有用户在整个集群范围内对 Secrets 的访问权限。
#由于是 ClusterRoleBinding,它不受命名空间的限制,适用于所有命名空间。
#这些绑定的创建和管理可以通过 kubectl 命令行工具或直接通过 Kubernetes API 进行。例如,要创建 RoleBinding 或 ClusterRoleBinding,可以使用以下 kubectl 命令
kubectl create rolebinding <binding-name> --role=<role-name> --user=<user-or-group> --namespace=<namespace>
#或者,对于 ClusterRoleBinding
kubectl create clusterrolebinding <binding-name> --clusterrole=<clusterrole-name> --group=<group-name>
通过这种方式,Kubernetes 提供了灵活的权限管理机制,使得管理员可以根据需要精细地控制用户和系统组件对资源的访问。
4.Resources资源
在 Kubernetes 中,资源(Resources)是 API 对象的集合,它们代表了集群中的对象,如 Pods、Services、Secrets 等。资源可以是命名空间作用域的(例如 Pods、Services),也可以是集群作用域的(例如 Nodes、ClusterRoles)。此外,某些资源还可能包含子资源(Subresources),这些子资源提供了对资源的特定操作,例如 Pod 的日志(/pods/{name}/log)。
http://api/v1/namespaces/{namespace}/pods/{name}/log
GET api/v1/namespaces/{namespace}/pods/{name}/log
在 RBAC(基于角色的访问控制)模型中,可以通过定义 Role 或 ClusterRole 来控制对这些资源及其子资源的访问权限。
4.1如何在Role中定义规则以控制对资源及其子资源的访问权限的示例
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""] # 空字符串表示核心 API 组
resources: ["pods", "pods/log"] # "pods" 是资源,"pods/log" 是子资源
#resources 字段定义了 Role 适用的资源类型,而 apiGroups 字段定义了资源所属的 API 组。在 Kubernetes 中,资源和 API 组的概念允许对不同类型的资源进行细粒度的访问控制。
verbs: ["get", "list"] # 允许的操作
#在这个例子中,pod-and-pod-logs-reader Role 授予了对 default 命名空间中 Pods 的获取(get)和列出(list)权限,同时也允许对这些 Pods 的日志子资源执行相同的操作。
字段 | 含义 |
---|---|
get | 获取单个资源的详细信息 |
list | 列出资源 |
watch | 监视资源的变化 |
create | 创建新资源 |
update | 更新现有资源 |
patch | 部分更新资源 |
delete | 删除资源 |
exec | 在Pod中执行命令 |
4.2Rules规则
在 Kubernetes RBAC(基于角色的访问控制)中,rules 字段定义了一组规则,这些规则指定了哪些操作(verbs)可以对哪些资源(resources)执行。rules 字段中的 verbs、resources 和 apiGroups 是关键的部分,它们共同决定了角色的权限范围。
字段 | 含义 |
---|---|
get | 获取单个资源的详细信息 |
list | 列出资源 |
watch | 监视资源的变化 |
create | 创建新资源 |
update | 更新现有资源 |
patch | 部分更新资源 |
delete | 删除资源 |
exec | 在Pod中执行命令 |
字段 | 含义 |
---|---|
services 、endpoints 、pods | Kubernetes 中的核心资源类型 |
secrets 、configmaps | 用于存储敏感信息和配置数据的资源类型 |
deployments 、jobs 、daemonsets | 应用部署和管理相关的资源类型 |
nodes 、rolebindings 、clusterroles | 集群管理和权限控制相关的资源类型 |
字段 | 含义 |
---|---|
"" | 核心 API 组,也就是 Kubernetes 最初的 API 组 |
"apps" 、"autoscaling" 、"batch" | Kubernetes 扩展的 API 组,包含了额外的资源类型和功能(autoscaling自动伸缩 ) |
在定义 Role 或 ClusterRole 时,可以根据需要组合这些 verbs、resources 和 apiGroups 来精确控制对资源的访问权限。例如,如果你想允许用户查看和列出 Pods,但不允许创建、修改或删除它们,你可以在 rules 中设置 verbs 为 ["get", "list"],resources 为 ["pods"]。
通过这种方式,Kubernetes 提供了一种细粒度的权限管理机制,使得管理员可以根据实际需求为不同的用户和组件分配合适的权限。
四、准入控制
准入控制(Admission Control)是 Kubernetes 中的一个关键特性,它在资源对象被持久化到 etcd 之前,对 API Server 接收到的请求进行检查和验证。准入控制器(Admission Controllers)是一组插件,它们可以拦截和修改请求,或者根据特定的策略拒绝请求。这些控制器有助于维护集群的稳定性和安全性。
Kubernetes 提供了一系列的准入控制器,它们可以按需启用或禁用。
官方文档参考:https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/
1.官方推荐推入控制器
- NamespaceLifecycle:管理命名空间的生命周期,例如,防止删除包含活动资源的命名空间。
- LimitRanger:检查资源请求是否超出了集群设置的限制范围,如 CPU 和内存请求。
- ServiceAccount:确保 Pod 能够正确地使用服务账户进行身份认证。
- DefaultStorageClass:为没有指定存储类的 PersistentVolumes 选择默认的存储类。
- DefaultTolerationSeconds:为没有指定容忍度(Toleration)的 Pods 添加默认的容忍度设置。
- MutatingAdmissionWebhook:允许外部服务通过 webhook 修改请求对象。
- ValidatingAdmissionWebhook:允许外部服务通过 webhook 验证请求对象。
- ResourceQuota:限制命名空间内资源的使用量,如 Pods、CPU 和内存。
- NodeRestriction:限制 Pods 可以在哪些节点上运行。
管理员可以根据集群的具体需求和安全策略来启用或禁用这些准入控制器。例如,如果集群需要严格的资源限制,那么 LimitRanger 和 ResourceQuota 就非常重要。如果集群需要与外部鉴权服务集成,那么 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 就非常有用。
在 Kubernetes 的配置文件中,可以通过 --admission-control 参数来指定启用哪些准入控制器。例如:
kube-apiserver --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction
#这个参数的值是一个逗号分隔的准入控制器列表。通过这种方式,Kubernetes 确保只有符合集群策略的资源对象才能被创建或修改。
2.常见的控制器插件
- NamespaceLifecycle:
- 这个控制器管理命名空间的生命周期,确保只有存在的对象才能在命名空间中创建。
- 它防止删除系统预置的命名空间,如 kube-system。
- 当删除命名空间时,它会确保命名空间中的所有资源对象也被删除。
- LimitRanger:
- LimitRanger 用于配额管理,它检查资源请求是否符合命名空间的 LimitRange 限制。
- 这有助于防止资源过度分配,确保集群资源的合理使用。
- ServiceAccount:
- 这个控制器在创建 Pod 时自动为其添加 ServiceAccount。
- 它确保 Pod 能够使用 ServiceAccount 的身份访问 API Server,这对于 Pod 的认证和授权至关重要。
- ResourceQuota:
- ResourceQuota 控制器用于基于命名空间的配额管理,它确保资源请求不会超过预设的配额限制。
- 这有助于防止单个用户或应用占用过多资源,从而影响集群中其他用户或应用。
- NodeRestriction:
- NodeRestriction 控制器用于限制节点加入集群时的权限。
- 它确保节点以最小权限运行,从而减少潜在的安全风险。
3.完整示例
如何在 Kubernetes 集群中创建一个用户,并限制该用户只能管理指定命名空间的资源。这个过程涉及到用户创建、证书生成、RBAC 授权和 kubeconfig 文件的配置。
3.1创建用户
useradd cxk
passwd cxk
#使用 useradd 和 passwd 命令创建一个名为 zhangsan 的用户,并设置密码
3.2生成证书和Kubeconfig文件
#使用这个用户进行资源操作,会发现连接 API Server 时被拒绝访问请求
su - cxk
kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?
#创建用于用户连接到 API Server 所需的证书和 kubeconfig 文件
#先上传证书生成工具 cfssl、cfssljson、cfssl-certinfo 到 /usr/local/bin 目录中
chmod +x /usr/local/bin/cfssl*
mkdir /opt/cxk
cd /opt/cxk
vim user-cert.sh
#创建一个 user-cert.sh 脚本,用于自动化证书生成过程
#######################
cat > cxk-csr.json <<EOF
{
"CN": "cxk",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
#API Server 会把客户端证书的 CN 字段作为 User,把 names.O 字段作为 Group
cd /etc/kubernetes/pki/
cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /opt/cxk/cxk-csr.json | cfssljson -bare cxk
#使用 CFSSL 工具生成用户 cxk 的证书和私钥
chmod +x user-cert.sh
./user-cert.sh
#/etc/kubernetes/pki/ 目录中会生成 cxk-key.pem、cxk.pem、cxk.csr
3.3配置Kubeconfig文件
cd /opt/cxk
vim rbac-kubeconfig.sh
#使用 rbac-kubeconfig.sh 脚本设置 kubeconfig 文件,包括集群参数、客户端认证参数和上下文参数。
APISERVER=$1
# 设置集群参数
export KUBE_APISERVER="https://$APISERVER:6443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=cxk.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials cxk \
--client-key=/etc/kubernetes/pki/cxk-key.pem \
--client-certificate=/etc/kubernetes/pki/cxk.pem \
--embed-certs=true \
--kubeconfig=cxk.kubeconfig
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=cxk \
--namespace=cxk \
--kubeconfig=cxk.kubeconfig
# 使用上下文参数生成 cxk.kubeconfig 文件
kubectl config use-context kubernetes --kubeconfig=cxk.kubeconfig
3.4创建命名空间
kubectl create namespace cxk
chmod +x rbac-kubeconfig.sh
./rbac-kubeconfig.sh 192.168.241.11
#查看证书
cat cxk.kubeconfig
mkdir /home/cxk/.kube
cp cxk.kubeconfig /home/cxk/.kube/config
chown -R cxk:cxk /home/cxk/.kube/
3.5RBAC授权
vim rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: cxk
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create"]
#创建一个名为 pod-reader 的 Role,允许在 cxk 命名空间中读取 Pods
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: cxk
subjects:
- kind: User
name: cxk
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
#创建一个 RoleBinding,将 pod-reader Role 绑定到用户 cxk
kubectl apply -f rbac.yaml
kubectl get role,rolebinding -n cxk
3.6测试操作权限
#切换用户,测试操作权限
su - cxk
vim pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
containers:
- name: nginx
image: nginx
kubectl create -f pod-test.yaml
kubectl get pods -o wide
#访问 svc 资源就会被拒绝
kubectl get svc
Error from server (Forbidden): services is forbidden: User "cxk" cannot list resource "services" in API group "" in the namespace "cxk"
#也无法访问 default 命名空间
kubectl get pods -n default
Error from server (Forbidden): pods is forbidden: User "cxk" cannot list resource "pods" in API group "" in the namespace "default"
#使用 root 用户查看
kubectl get pods --all-namespaces -o wide
#由此可以看出 RoleBinding 的用户只能管理指定的命名空间中的资源
3.7管理员权限
#也可以通过绑定 admin 角色,来获得管理员权限
kubectl create rolebinding cxk-admin-binding --clusterrole=admin --user=cxk --namespace=cxk
#如果需要,可以创建一个新的 RoleBinding,将 admin 角色绑定到用户 cxk,从而授予其管理员权限。
这个过程展示了如何通过 RBAC 和证书管理来控制用户对 Kubernetes 集群资源的访问。通过这种方式,可以确保用户只能访问和操作他们被授权的资源,从而提高集群的安全性。
五、总结
1.K8S安全机制
- 认证(Authenticating)
- 鉴权(Authorization)
- 准入控制(Admission Control)
2.认证(Authenticating)
- Token认证:使用很长很复杂Token字符串做认证,通常是单向认证
- Basic认证:使用账号和密码的格式通过base64编码和解码认证,通常是单向认证
- https认证:使用通过CA机构签发的证书,进行https认证,可以实现双向认证
K8S认证(Kubectl、Kubelet、Controller-Manager、Scheduler等)与APIServer通信,是使用https证书认证,默认使用6443端口通信,使用Kubeconfig配置文件就知道使用了什么证书连接到哪个K8S集群的APIServer
Pod形式运行的组件(Dashboard、CoreDNS、外置存储存储插件(PROVISIONER))与APIServer通信,使用的是ServiceAccount作为Pod的服务账号来去访问APIServer,每个Pod都会有一个ServiceAccount服务账号,可以创建Pod资源的时候去指定ServiceAccount字段
3.鉴权(Authorization)
3.1鉴权策略
- AlwaysDeny
- AlwaysAllow
- ABAC(Attribute-Based Access Control)
- WebHook
- RBAC(Role-Based Access Control)(默认控制策略)
3.2RBAC四个资源对象
角色Role、ClusterRole都可以是实现定义角色的赋予某些资源(Rules、Resource)的操作权限(Rules、Verbs)
- Role 受命名空间影响,只能在某一个命名空间中有效
- ClusterRole 默认可以在K8S当中所有命名空间有效,配置中不需要定义NameSpace
角色绑定 RoleBinding、ClusterRoleBinding 把账户主题绑定Subject(User、Group、ServiceAccount)和角色进行绑定,使主体和账户具有相关资源的操作权限
- RoleBinding:和同一个命名空间的Role去绑定的话,可以使主体账户在这个空间中具有相关资源的操作权限,和ClusterRole绑定,以主体账户在RoleBinding所在的命名空间中具有相关资源的操作权限
- ClusterRoleBinding: 和ClusterRole绑定,可以使主体账户在K8S所有的命名空间中具有资源的相关操作权限
3.3创建RBAC鉴权
- 先创建Role ClusterRole 定义角色赋予某些资源的操作权限
- 再创建RoleBinding和ClusterRoleBinding 把主体和角色进行绑定
4.准入控制(Admission Control)
添加准入控制插件,实现额外的准入控制规则对资源进行请求做检查
如果你想让一个Pod、Service、ConfigMap、Secret等普通用户,具有接入K8s集群相关资源的操作权限
- 创建Service Account或者用户
- 做认证 Token 证书认证
- Service Account 会自动生成Service Account Token的Secret资源
- 用户需要创建证书,把cfssl等工具通过CA证书和私钥文件生成证书和私钥,使用CA证书和私钥文件创建Kubeconfig配置文件,把Kubeconfig配置文件导入自动的家目录中,kube/config文件中
- 做RBAC鉴权 RoleClusterRole 创建角色赋予给资源的操作权限,RoleBinding|ClusterRoleBinding 把用户(主体)和角色进行绑定
- 此后Pod或者用户就具有相关的命名空间中对相关资源有了操作权限