一、API Server认证管理
Kubernetes集群有两种用户账号:第1种是集群内部的Service Account;第2种是外部的用户账号,可能是某个运维人员或外部应用的账号。Kubernetes并不支持常规的个人账号,但拥有被Kubernetes集群的CA证书签名的有效证书,个人用户就可被授权访问Kubernetes集群了。
Service Account也是一种账号,但它并不是给Kubernetes集群的用户(系统管理员、运维人员、租户用户等)用的,而是给运行在Pod里的进程用的,它为Pod里的进程提供了必要的身份证明。
在每个命名空间中都有一个名为default的默认Service Account对象,在这个Service Account里面有一个名为Tokens的可以作为Volume被挂载到Pod里的Secret,Pod启动时,这个Secret会自动被挂载到Pod的指定目录下,用来协助完成Pod中的进程访问API Server时的身份鉴权。
Kubernetes之所以要创建两套独立的账号系统,原因如下。
- ◎ User账号是给人用的,Service Account是给Pod里的进程用的,面向的对象不同。
- ◎ User账号是全局性的,Service Account则属于某个具体的命名空间。
- ◎ 通常来说,User账号是与后端的用户数据库同步的,创建一个新用户时通常要走一套复杂的业务流程才能实现,Service Account的创建则需要极轻量级的实现方式,集群管理员可以很容易地为某些特定任务创建一个Service Account。
- ◎ 对于这两种不同的账号,其审计要求通常不同。
- ◎ 对一个复杂的系统来说,多个组件通常拥有各种账号的配置信息,Service Account是在命名空间级别隔离的,可以针对组件进行一对一的定义,同时具备很好的“便携性”。
需要有一个CA证书,CA是PKI系统中通信双方都信任的实体,被称为可信第三方(Trusted Third Party,TTP)。CA作为可信第三方的重要条件之一,就是其行为具有非否认性。作为第三方而不是简单的上级,就必须让信任者有追究自己责任的能力。
HTTPS证书认证,CA认证工作流:
(1)HTTPS通信双方的服务端向CA机构申请证书,CA机构是可信的第三方机构,它可以是一个公认的权威企业,也可以是企业自身。企业内部系统一般都用企业自身的认证系统。CA机构下发根证书、服务端证书及私钥给申请者。
(2)HTTPS通信双方的客户端向CA机构申请证书,CA机构下发根证书、客户端证书及私钥给申请者。
(3)客户端向服务端发起请求,服务端下发服务端证书给客户端。客户端在接收到证书后,通过私钥解密证书,并利用服务端证书中的公钥认证证书信息比较证书里的消息,例如,比较域名和公钥与服务器刚刚发送的相关消息是否一致,如果一致,则客户端认可这个服务器的合法身份。
(4)客户端发送客户端证书给服务端,服务端在接收到证书后通过私钥解密证书,获得客户端证书公钥,并用该公钥认证证书的信息,确认客户端是否合法。
(5)客户端通过随机密钥加密信息,并发送加密后的信息给服务端。在服务端和客户端协商好加密方案后,客户端会产生一个随机的密钥,客户端通过协商好的加密方案加密该随机密钥,并发送该随机密钥
到服务端。服务端接收这个密钥后,双方通信的所有内容都通过该随机密钥加密。
为了验证使用者的身份,需要客户端向服务端提供一个可靠的身份信息,称之为Token,这个Token被放在HTTP Header头里,在Token里有信息来表明客户身份。
二、RBAC
Role Based Access Control
RBAC(Role-Based Access Control,基于角色的访问模式控制)
在RBAC管理体系中,Kubernetes引入了4个资源对象:Role、ClusterRole、RoleBinding和ClusterRoleBinding。同其他API资源对象一样,用户可以使用kubectl或者API调用等方式操作这些资源对象。
1、角色(Role)和集群角色(ClusterRole)
一个角色就是一组权限的集合,在Role中设置的权限都是许可(Permissive)形式的,不可以设置拒绝(Deny)形式的规则。Role设置的权限将会局限于命名空间(namespace)范围内,如果需要在集群
级别设置权限,就需要使用ClusterRole了。
2、角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)
角色绑定或集群角色绑定用来把一个角色绑定到一个目标主体上,绑定目标可以是User(用户)、Group(组)或者Service Account。RoleBinding用于某个命名空间中的授权,ClusterRoleBinding用于集群范围内的授权。
3、RoleBinding也可以引用ClusterRole。
对目标主体在其所在命名空间授予在ClusterRole中定义的权限。一种常见的用法是集群管理员预先定义好一组ClusterRole(权限设置),然后在多个命名空间中重复使用这些ClusterRole。
官网指导:
https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
三、为什么要有RBAC
细粒度的权限划分,对不同的人赋予不同的权限,精细化的管控。
开启RBAC位置如下:
二进制方式安装
安装时候已经默认开启
[root@k8s-master01 qos]#cat /usr/lib/systemd/system/kube-apiserver.service | grep RBAC--authorization-mode=Node,RBAC \
admin方式安装
[root@k8s-master01 qos]# vim /etc/kubernetes/manifests/kube-apiserver.yml
四、权限划分
RBAC API 声明了四种 Kubernetes 对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。
指定权限:
- ClusterRole:没有命名空间限制,是一个集群作用域的资源。
- Role:有命名空间限制,只对某个命名空间限制。
如果你希望在命名空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole。
授权绑定
- ClusterRoleBinding:对整个集群范围进行指定权限。
- RoleBinding:命名空间中执行授权,创建在哪个命名空间下,就有哪个命名空间的权限。
如果你希望将某 ClusterRole 绑定到集群中所有命名空间,你要使用 ClusterRoleBinding。一个 RoleBinding 可以引用同一的名字空间中的任何 Role。
ClusterRole可以绑定RoleBinding,用于跨命名空间访问。
一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。
五、权限绑定详解
1. Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API groupresources: ["pods"]verbs: ["get", "watch", "list"]
➢ kind:定义资源类型为Role
➢ apiversion:定义该资源的API版本,使用v1版本,因为其它版本如beta版本在Kubernetes1.22+将被彻底弃用。
➢ metadata:元数据定义
- namespace:因为Role是作用单个Namespace下的,具有命名空间隔离,所以需要制定Namespace,不指定则为default
- name:Role的名称
➢ rules:定义具体的权限,切片类型,可以配置多个
- apiGroups:包含该资源的apiGroup名称,比如extension ,留空也行
- resources:定义对哪些资源进行授权,切片类型,可以定义多个,比如pods、service等
- verbs:定义可以执行的操作,切片类型,可以定义多个,比如create、delete、list、get、watch、deletecollection等
2. ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制name: secret-reader
rules:
- apiGroups: [""]# 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"resources: ["secrets"]verbs: ["get", "watch", "list"]
ClusterRole 同样可以用于授予 Role 能够授予的权限。 因为 ClusterRole 属于集群范围,所以没有命名空间配置。
它也可以为以下资源授予访问权限:
-
集群范围资源(比如节点(Node))
-
非资源端点(比如
/healthz
) -
跨名字空间访问的名字空间作用域的资源(如 Pod)
比如,可以使用 ClusterRole 来允许某特定用户执行
kubectl get pods --all-namespaces
查看healthz
# 查看apiserver端口
[root@k8s-master01 qos]#netstat -lnpt | grep apiserver
tcp6 0 0 :::6443 :::* LISTEN 1390/kube-apiserver# 健康状态正常
# [root@k8s-master01 qos]#curl https://127.0.0.1:6443/healthz -k
ok[root@k8s-master01 qos]#
3. RoleBinding
角色绑定(Role Binding)是将权限赋予一个用户或者一组用户,有命名空间限制。
下面的例子中的 RoleBinding 将 “pod-reader” Role 授予在 “default” 名字空间中的用户 “jane”。 这样,用户 “jane” 就具有了读取 “default” 名字空间中所有 Pod 的权限。
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该名字空间中有一个名为 “pod-reader” 的 Role
kind: RoleBinding
metadata:name: read-podsnamespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: Username: jane # "name" 是区分大小写的apiGroup: rbac.authorization.k8s.io
roleRef:# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系kind: Role # 此字段必须是 Role 或 ClusterRolename: pod-reader # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配apiGroup: rbac.authorization.k8s.io
➢ subjects:配置被绑定对象,可以配置多个,
- kind:绑定对象的类别,当前为User,还可以是Group、ServiceAccount
- name:绑定对象名称
➢ roleRef:绑定的类别
- kind:指定权限来源,可以是Role或ClusterRole
- name:
Role
或ClusterRole
的名字 - apiGroup:API 组名
➢ apiGroup 可以不写
生产中一般使用serviceaccounts来作为主要管理对象
[root@k8s-master01 qos]#kubectl get serviceaccounts
NAME SECRETS AGE
default 0 88d[root@k8s-master01 qos]#kubectl get sa
NAME SECRETS AGE
default 0 88d
4. ClusterRoleBinding
要跨整个集群完成访问权限的授予,使用一 ClusterRoleBinding。
下面的 ClusterRoleBinding 允许 “manager” 组内的所有用户访问任何名字空间中的 Secret。
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
kind: ClusterRoleBinding
metadata:name: read-secrets-global
subjects:
- kind: Groupname: manager # 'name' 是区分大小写的apiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io
创建了绑定之后,不能再修改绑定对象所引用的 Role 或 ClusterRole。
如果想要改变现有绑定对象中 roleRef
字段的内容,必须删除重新创建绑定对象。
六、对资源的引用(角色)
子资源
在这里,pods
对应名字空间作用域的 Pod 资源,而 log
是 pods
的子资源。 在 RBAC 角色表达子资源时,使用斜线(/
)来分隔资源和子资源。 要允许某主体读取 pods
同时访问这些 Pod 的 log
子资源,可以这样写"pods/log"
或"pods/exec"
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-and-pod-logs-reader
rules:
- apiGroups: [""]resources: ["pods", "pods/log"]verbs: