一、前言
ApiServer:管理平台访问控制的唯一入口。
用户对API资源进行操作:
1、 对客户端的访问进行认证操作,确认是否有访问k8s权限;token(共享密钥)或SSL(双向SSL认证)二选一
2、 授权检查,确认是否对资源具有相关权限
ABAC(基于属性的访问控制)、RBAC(基于角色的访问控制)、NODE(基于节点)、WebHook(自定义HTTP回调方法的访问控制)
3、 准入控制,对操作资源相关联的其他资源是否有权限。
K8S集群交互的身份认证:kubeconfig(证书)、token
Tips:RBAC(基于角色的访问控制),一般都是许可控制,默认都是拒绝的。
1、对API资源进行操作需要经过的三个阶段:
认证操作:访问k8s的账号及认证通过。不需要串行检查。N种认证插件。
授权检查:检查是否有资源对象是否有操作权限。N种授权插件(webHook,ABAC,Node,RBAC),主流是RBAC。
准入控制:对授权检查后的其他安全检查。比如级联资源对象是否有操作权限,补充类的检查。
认证方式:
认证令牌(token):经由http的守护来实现。
SSL 认证:确认服务器的身份。双向证书认证,SSL会话,HTTPS。
2、Client --> ApiServer应该具有的信息:
APISever:
Subject --> action--> resource
Subject:user group serviceaccount
Object:resource ,resource group ,no-resource url
Action:get list watch patch delete deletecollection等等
【
User:username,uid;
Group
Extra
Api:RequestPath
(https:// 192.168.42.128:6443/apis/apps/v1/namespaces/default/deployments/myapp-deploy/)
HTTP request verb:get post put delete 对应 API requests verb: get list create update patch watch proxy redirect delete deleteCollection等等
Resources
subResource
namespace
API Group
】
https是双向认证的,curl没有经过认证,是不能直接去访问的。
可以用kubectl在本地启动一个认证代理,因为kubectl是被集群认证了的。(kubectl的认证信息:[kubelet@master ~]$ cat .kube/config --- /etc/kubernetes/admin.conf)
[kubelet@master ~]$ kubectl proxy --port=8080 [kubelet@master ~]$ curl http://localhost:8080/api/v1/namespaces # 列出所有的namespace [kubelet@master ~]$ curl http://localhost:8080/apis/apps/v1/namespaces/kube-system/deployments/ # 除核心群组里的资源,请求时都需要用apis
二、认证操作
K8S有两类认证账号:
集群外部的人用的:UserAccount – 不需要自己去创建,只是一种标识
集群内部的Pod与apiServer通信用的:ServiceAccount
1、ServiceAccount:标准的K8S资源对象,专用账号。
[kubelet@master yaml]$ kubectl create serviceaccount mysa -o yaml --dry-run > mysa.yaml # 没有真正创建 [kubelet@master yaml]$ kubectl get pod myapp-deploy-67b4984cb5-fs28j -o yaml –export # 导出配置,已废弃。 [kubelet@master yaml]$ kubectl create serviceaccount admin
创建sa时,会自动创建一个默认的secret。
[kubelet@master ~]$ kubectl explain pod.spec.serviceAccountName #指定pod使用的sa
Pod获取私有仓库镜像时的认证方式有两种:
- 直接使用字段pod.spec.imagePullSecrets来定义
- 使用serviceAccount,serviceAccount里也有Image pull secrets
2、Kubectl的认证实现
[kubelet@master ~]$ kubectl config view # 查看kubeconfig(连入apiServer的认证配置)
# 可以实现一个kubectl管理多个集群,使用不同的或者相同的账号,一个配置文件配置多个账号,多个集群。
[kubelet@master ~]$ kubectl config –h # 可以自己添加cluster,user,context,以及切换当前使用的context。Context表示集群与账号的关联关系
集群的所有认证文件目录:
[kubelet@master ~]$ ll /etc/kubernetes/pki/
3、自定义证书使用kubectl来认证接入到apiServer:
[root@master pki]# cd /etc/kubernetes/pki [root@master pki]# (umask 077; openssl genrsa -out magedu.key 2048) [root@master pki]# openssl req -new -key magedu.key -out magedu.csr -subj "/CN=magedu" [root@master pki]# openssl x509 -req -in magedu.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out magedu.crt -days 365 [root@master pki]# openssl x509 -in magedu.crt -text –noout # 查看 [root@master pki]# kubectl config set-credentials magedu --client-certificate=./magedu.crt --client-key=./magedu.key --embed-certs=true # 创建用户并且隐藏
[root@master pki]# kubectl config set-context magedu@kubernetes --cluster=kubernetes --user=magedu # 创建上下文
[root@master pki]# kubectl config use-context magedu@kubernetes #切换当前使用的context
获取不到资源,因为此账号没有权限。
添加集群同样,查看帮助文档。
默认保存的配置都是在用户家目录下的.kube/config(例:/root/.kube/config)里面,可以手动指定保存在其他的配置文件里(--kubeconfig=/tmp/kube.conf)。
例:[root@master ~]# kubectl config set-cluster kube-cluster --kubeconfig=/tmp/kube.conf --server=https://192.168.42.128:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
[root@master ~]# kubectl config view --kubeconfig=/tmp/kube.conf
三、授权操作
授权操作也是由授权插件来完成。
常用的授权插件:
Node
ABAC基于属性的访问控制
RBAC基于角色的访问控制
Webhook基于http的回机制的访问控制
1、RBAC(基于角色的访问控制)
三要素:
User(用户):K8S中User不是单独的资源。
Role(角色)
Permission(许可)
K8S中有两种级别的资源:集群级别,名称空间级别。
名称空间级别角色定义与绑定:
Role:不能定义拒绝权限,只能定义允许权限,默认就是拒绝。
Operations
Objects
Rolebinding:
UserAccount or ServiceAccount
Role
集群级别的角色定义与绑定:
ClusterRole
ClusterRoleBinding
Tips:如果用Rolebinding去绑定ClusterRole,则ClusterRole只具备名称空间的权限。当需要对多个名称空间授权时,可以用不同名称空间的用户通过RoleBinding去绑定同一个ClusterRole,则这些用户依然只有当前名称空间的权限。
2、创建及使用
Role:
[kubelet@master ~]$ kubectl explain role
[kubelet@master ~]$ kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > yaml/role-demo.yaml
RoleBinding:
[kubelet@master yaml]$ kubectl explain rolebinding
[kubelet@master ~]$ kubectl create rolebinding magedu-read-pods --role=pods-reader --user=magedu --dry-run -o yaml
使用magedu账号可以读取default名称空间的资源,但是不能读kube-system,因为Role(pod-reader)属于default。
[kubelet@master ~]$ kubectl delete rolebinding magedu-read-pods # 删除权限
ClusterRole:
[kubelet@master yaml]$ kubectl explain clusterrole
[kubelet@master ~]$ kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
ClusterRoleBinding:
[kubelet@master ~]$ kubectl create clusterrolebinding –h
[kubelet@master yaml]$ kubectl explain clusterrolebinding
[kubelet@master ~]$ kubectl create clusterrolebinding magedu-read-all-pods --clusterrole=cluster-reader --user=magedu --dry-run -o yaml
[kubelet@master yaml]$ kubectl delete clusterrolebinding magedu-read-all-pods #删除后立即生效,权限回收。
用RoleBinding绑定ClusterRole:
[kubelet@master yaml]$ kubectl create rolebinding magedu-read-pod --clusterrole=cluster-reader --user=magedu --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
此时只有default名称空间的pod读取权限。
Tips:ClusterRoleBinding只能绑定ClusterRole,不能绑定Role;RoleBinding能绑定ClusterRole,也能绑定Role,但绑定ClusterRole权限也是在名称空间中。
系统内建的重要的ClusterRole:
系统中有很多内建的ClusterRole,ClusterRoleBinding
admin:可以用作命名空间的管理员。
[kubelet@master ~]$ kubectl get clusterrole admin -o yaml
cluster-admin:
[kubelet@master ~]$ kubectl get clusterrolebinding cluster-admin -o yaml
用户属于哪个组是在证书中定义的。
四、准入控制
准入控制一般不用管理员操作,了解即可。