Kubernetes集群安全机制
概述
当我们访问K8S集群时,需要经过三个步骤完成具体操作
- 认证
- 鉴权【授权】
- 准入控制
进行访问的时候,都需要经过 apiserver, apiserver做统一协调,比如门卫
- 访问过程中,需要证书、token、或者用户名和密码
- 如果访问pod需要serviceAccount
认证
对外不暴露8080端口,只能内部访问,对外使用的端口6443
客户端身份认证常用方式
- https证书认证,基于ca证书
- http token认证,通过token来识别用户
- http基本认证,用户名 + 密码认证
鉴权
基于RBAC进行鉴权操作
基于角色访问控制
准入控制
就是准入控制器的列表,如果列表有请求内容就通过,没有的话 就拒绝
RBAC介绍
基于角色的访问控制,RBAC将角色和角色绑定分开,角色指的是一组定义好的操作集群资源的权限,而角色绑定是将角色和用户、组或者服务账号实体绑定,从而赋予这些实体权限。可以看出 RBAC 这种授权方式很灵活,要赋予某个实体权限只需要绑定相应的角色即可。
针对 RBAC 机制,k8s 提供了四种 API 资源:Role、ClusterRole、RoleBinding、ClusterRoleBinding。
k8s中有默认的几个角色
- role:特定命名空间访问权限
- ClusterRole:所有命名空间的访问权限
角色绑定
- roleBinding:角色绑定到主体
- ClusterRoleBinding:集群角色绑定到主体
主体
- user:用户
- group:用户组
- serviceAccount:服务账号
RBAC实现鉴权
创建命名空间
kubectl get namespace
然后我们创建一个自己的命名空间 roledemo
kubectl create ns roledemo
命名空间创建Pod
为什么要创建命名空间?因为如果不创建命名空间的话,默认是在default下
kubectl run nginx --image=nginx -n roledemo
创建角色
- Role: 只能用于授予对某一单一命名空间中资源的访问权限,因此在定义时必须指定 namespace;
以下示例描述了 default 命名空间中的一个 Role 对象的定义,用于授予对 pod 的读访问权限:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: roledemo
name: pod-reader
rules:
- apiGroups: [""] # 空字符串""表明使用core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
tip:这个角色只对pod 有 get、list权限
然后通过 yaml创建我们的role
# 创建 kubectl apply -f rbac-role.yaml # 查看 kubectl get role -n roledemo
- ClusterRole:针对集群范围的角色,能访问整个集群的资源;
下面示例中的 ClusterRole 定义可用于授予用户对某一特定命名空间,或者所有命名空间中的 secret(取决于其绑定方式)的读访问权限:
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: # 鉴于ClusterRole是集群范围对象,所以这里不需要定义"namespace"字段 name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
创建角色绑定
- RoleBinding:将 Role 和用户实体绑定,从而赋予用户实体命名空间内的权限,同时也支持 ClusterRole 和用户实体的绑定;
下面示例中定义的 RoleBinding 对象在 default 命名空间中将 pod-reader 角色授予用户 jane。 这一授权将允许用户 jane 从 default 命名空间中读取pod:
# 以下角色绑定定义将允许用户"jane"从"default"命名空间中读取pod。 kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-pods namespace: roledemo subjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role # this must be Role or ClusterRole name: pod-reader #this must match the name of the Role or ClusterRole you wish to bing to apiGroup: rbac.authorization.k8s.io
然后创建我们的角色绑定
# 创建角色绑定 kubectl apply -f rbac-rolebinding.yaml # 查看角色绑定 kubectl get role, rolebinding -n roledemo
- ClusterRoleBinding:将 ClusterRole 和用户实体绑定,从而赋予用户实体集群范围的权限;
下面示例中所定义的 ClusterRoleBinding 允许在用户组 manager 中的任何用户都可以读取集群中任何命名空间中的 secret:
# 以下`ClusterRoleBinding`对象允许在用户组"manager"中的任何用户都可以读取集群中任何命名空间中的secret。 kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 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
使用证书识别身份
我们首先得有一个 rbac-user.sh 证书脚本
这里包含了很多证书文件,在TSL目录下,需要复制过来
通过下面命令执行我们的脚本
./rbac-user.sh
最后我们进行测试
# 用get命令查看 pod 【有权限】 kubectl get pods -n roledemo # 用get命令查看svc 【没权限】 kubectl get svc -n roledmeo
关于 RBAC 更详细的讲解见这里:https://jimmysong.io/kubernetes-handbook/concepts/rbac.html