TOC

ServiceAccount

    Kubernetes之上的认证用户有两种第一种是常规用户UserAccount,第二种是ServiceAccount,对于ServiceAccount指的是将来在Kubernetes之上的某一个Pod,甚至在Kubernetes之外的运行的某一守护进程,如果需要在必要的时候访问Kubernetes接入APIServer也应该进行认证,此时认证用户帐号是什么以及认证信息是什么,通常应该通过ServiceAccount并结合ServiceAccount当中的Security来完成认证信息的提供;
    每一个ServiceAccount的定义方式很简单,简称为SA,在创建SA资源的时候我们可以指定metadata.name来指定该SA的名称,metadata.namespace来指定该ServiceAccount所属的namespace,当前的用户的认证信息是什么则需要靠secrets来提供,这个secrets可以不用非得是tls帐号密码,因为我们的证书和私钥在secrets当中,如果要定义为tls类型的,那是用于ssl通信的,而不是用于认证的,因此这里的secrets不能使用secret创建时的tls类型,而应该使用generic类型的证书,不过呢,在我们创建ServiceAccount是完全不必要自己去定义secerts的,因为我们在创建ServiceAccount帐号时,Kubernetes会自动给我们生成一个secerts,这个secrets保存了相应用户的认证信息,认证并不关键,创建secert的目标不是为了认证,认证代表不了这个用户能做什么,因此直接帮我们生成了认证,让客户端拿着这个密钥可以正常认证通过,关键在于授权,也就是管理员为这个ServiceAccount绑定了什么权限,那么以这个用户运行的Pod或守护进程也相应的拥有什么权限,因此secerts我们不用自己创建它能够自动生成的;
    [root@node1 ~]# kubectl explain serviceaccount.secrets

利用配置清单创建SA
[root@node1 ~]# cat sa.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cce
  namespace: default
[root@node1 ~]# kubectl apply -f sa.yaml 
[root@node1 ~]# kubectl get sa
NAME      SECRETS   AGE
cce       1         17s
default   1         29d
[root@node1 ~]# kubectl describe sa cce 
Name:                cce
Namespace:           default
Labels:              <none>
Annotations:         kubectl.kubernetes.io/last-applied-configuration:
                       {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"cce","namespace":"default"}}
Image pull secrets:  <none>
Mountable secrets:   cce-token-4sj5m
Tokens:              cce-token-4sj5m  # 可以看出,当我们创建了一个ServiceAccount之后Kubernetes会自动为我们创建一个Token,无需去自建一个secrets
Events:              <none>

Requests Attributes

    Kubernetes是基于http或https协议工作的,因此其对应的操作请求,无非就是增删改查,这些增删改查都被直接映射成了http协议的get、put、delete等操作,因此在每一个Kubernetes的相关请求当中,通常这个请求会包含类似以下的信息;
user:这个请求者的身份;
group:这个请求者所属的组;
extra:额外的属性信息;
Resource:指定使用哪个Kind资源;
Subresource:有些资源还有子资源;
API:也就是我们的Kubernetes标准资源属于哪一个API群组下面的那个API;
API:api群组;
Namespace:指定名称空间;
Request path:相对于我们API来讲,就是请求的URL路径,这个URL其实就是Resource的标识方式;
HTTP request verb:HTTP请求方法,GET、DELETE...;
API request verb:向Kubernetes API的请求方法,比如get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection;

Kubernetes内建授权插件

Node:专用的授权插件,根据Pod对象调度的结果为Nde进行授权,Node是不具有管理和操作Pod权限的,一旦调度器调度到这个Pod跑在某一Pod,那么这个时候就必须为这个Node授权能够访问Pod的相关定义,这是自动完成的;
ABAC:基于属性的访问控制,我们授权就是指一个用户能操作哪个资源的哪个字段,因为属性就是指字段之意,在字段级别做控制,1.6之前的版本使用;
RBAC:基于角色的访问控制,事先定义好角色,直接将权限赋予给角色,只要用户属于这个角色也就有该赋予的权限;
Webhook:web钩子,其实也就是一个http的回调函数,一般而言就是某一个http上的资源发生变化时,能够发起触发,然后做出相应的操作;
RBAC
    对于用户授权来讲,对于Kubernetes1.8版本之后强制生效RBAC,任何人的操作必须在RBAC中有明确定义,如果没有定义,就没有权限,而匿名用户默认在RBAC中没有权限,包括认证进来的用户也只有极少数的权限,使用rbac.authorization.k8s.io API驱动授权决策,并支持动态配置,在使用kubadm部署的集群里面查看/etc/kubernetes/manifests/kube-apiserver.yaml该文件就可以查看到默认启用的授权插件;
    说白了,RABC出现的原因是serviceaccount只管认证,不管权限,也就是说默认情况下什么都有;
Kubernetes支持的操作(Determine the Request Verb)

    为了实现RBAC,需要有用户,这个用户账号有两种,我们称之为Subjects主语,第一种是UserAccount,第二种是ServiceAccount,这就是我们RBAC当中可以拿来当主语的东西;
    第二个我们称之为Objects宾语,叫资源,在Kubernetes上能够被操作的资源有三类,第一类,我们叫做Resources,比如Pod,Deployment这都是资源,第二类叫做子资源SubResouces,比如Pod的logs或者status或者URL类型的非对象型资源;
    第三种我们称之为Role和RoleBinding,在Role当中我们定义能够对哪个或哪些资源定义哪些操作,比如允许用户get、put在集群上的deployment资源,如果需要某个用户来扮演这个角色,那我们就需要使用RoleBinding,从而使得让Subjects拥有Role的权限,Role还分为Role和ClusterRole,集群级别和namespace级别,RoleBinding还分为RoleBinding和ClusterRoleBinding,将Role绑定集群级别和namespace;
要点
    在Kubernetes之上分两种资源,集群级别,名称空间级别,所以Role还分为Role和ClusterRole,分别赋予不同级别的操作权限,如果定义集群级别的资源,比如pv,namespace或者node等,名称空间级别的Pod,Controller,Service等,他们分别用于完成不同级别的资源;
    还有一种情况ClusterRole本应该包含ClusterRole,但是它也可以包含Role,首先集群级别的角色并不是只能操作集群级别在资源,而是能够操作集群范围的资源,集群范围包含namespace,当然有一点是确定的名称空间级别资源不能包含集群级别的资源,所以ClusterRole角色的权限可以施加于namespacce级别的资源也可以施加于集群级别的资源,因此RoleBinding还能够把Role绑定到ClusterRole,因为如果有一个ClusterRole需要去创建Pod,那么就需要赋予ClusterRole有namespace级别的权限,因为集群级别的namespace就是所有的namespace,也就是说允许在所有的namespace创建资源,那么此时如果使用RoleBinding绑定到一个ClusterRole,那也就是说把一个用户在一个名称空间上绑定到了ClusterRole,那么又因为Role是namespace级别的资源,虽然Role有了指定的ClusterRole的权限,但是Role是namespace级别的资源所以即使它的权限最大也之能在这个namespace内部,主要作用还是为了实现权限统一定义,在全局模式下定义一个组,让用户加入进来,那么就有了相应的权限了,无需每次都重新定义一个Role;
    所谓的授权就是让Subjects可以操作Objects而已,但是他们不能直接产生关联关系,我们需要一个Role这个中间桥建立关联,这样的好处是,将来我们做权限变更只需要修改Role即可,不用动用户的信息,就能完成权限的变动,实现动态授权并实时生效;
作用域
Role:Role对象只能用于授予对某一namespace中资源的访问权限,以下示例表示在“default” namespace中定义一个Role对象,用于授予对资源pods的读访问权限,绑定到该Role的用户则具有get/watch/list pod资源的权限;
ClusterRole:ClusterRole对象可以授予整个集群范围内资源访问权限, 也可以对以下几种资源的授予访问权限;
查看Kubernetes的API群组
    为了更容易对API进行扩展,Kubemetes 使用API Groups (API组)进行标识。APIGroups 以及REST URL中的路径进行定义。当前支持两类API groups;
        1、Core Groups (核心组),也可以称为Legacy Groups,该组的REST路径位于/api/v1, 作为 Kubernetes 最核心的 API,它是没有“组”的概念,例如 ”vl“,在资源对象的定义中表示为”apiVersion: v1“;
        2、具有分组信息的API,以/apis/$GROUP_NAME/$VERSIONURL路径进行标识,在资源对象的定义中表示为apiVersion: $GROUP_NAME/$VERSION(例如,apiVersion: batch/v1);

当API群组为空时,说明就是核心API群组,此时我们在创建Role或者Cluster的时候只需要给定一个空字符串即可;

简单示例
apiVersion: v1
kind: Namespace
metadata:
  name: auth
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cce
  namespace: auth  # 表示允许操作的namespace
rules:
- apiGroups: [""] # ""表示core API group
  resources: ["pods","pods/log"] # 允许对API群组里面哪些资源进行操作
  verbs: ["get","list","watch"]  # 可以通过get查看指定资源,list表示可以列出同一类型的所有资源,watch表示可以使用-w去监控资源变动
Role示例
    这里的role不是一个user,user在证书的CN里面,role键名之意角色,创建一个role,给定部分权限,允许读取default名称空间的资源;
# 创建一个role
[root@node1 ~]# cat role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: resource-reader
  namespace: default
rules:
- apiGroups: [""] # ""表示core API group
  resources: ["pods","pods/log","services"] # 表示允许操作的资源
  verbs: ["get","list","watch"]  # 表示允许执行的操作,get单个,list所有
[root@node1 ~]# kubectl apply -f role.yaml
[root@node1 ~]# kubectl get role
NAME              AGE
resource-reader   8m30s
# 创建rolebinding将指定用户绑定到上面的角色
[root@node1 ~]# cat rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cce-resource-reader
  namespace: default
subjects:
- kind: User # User或者Group或者ServiceAccount,如果是ServiceAccount还需要定义一个namespace字段
  name: cce  # 用户名或者组名或者服务名
  apiGroup: rbac.authorization.k8s.io #   对于ServiceAccount可以是空,对于普通用户和组默认是rbac.authorization.k8s.io
roleRef:
  kind: Role # Role或者ClusterRole
  name: resource-reader  # 引用role资源的子资源名称
  apiGroup: rbac.authorization.k8s.io # 我们创建Role的时候使用的apigroup,也就是上面的role资源数据哪个API群组
[root@node1 ~]# kubectl apply -f rolebinding.yaml
[root@node1 ~]# kubectl get rolebindings
NAME                  AGE
cce-resource-reader   44s
# 创建用户,新建一个私钥
[root@node1 ~]# openssl genrsa -out cce.key 2048
# 为证书生成一个证书签署请求,并且使用kubernetes的CA来签署
[root@node1 ~]# openssl req -new -key cce.key -out cce.csr -subj "/CN=cce/O=kubernetes"
# 利用kubernetes的CA来签署我们的证书
[root@node1 ~]# openssl x509 -req -in cce.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out cce.crt -days 36500
[root@node1 ~]# mkdir /etc/kubernetes/cce
[root@node1 ~]# mv cce.crt cce.csr cce.key /etc/kubernetes/cce/
# 创建一个新的kubeconfig文件
[root@node1 ~]# kubectl config set-cluster cce-cluster --server=https://172.16.1.2:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/etc/kubernetes/cce.conf
# 设定用户配置信息
[root@node1 ~]# kubectl config set-credentials cce --client-certificate=/etc/kubernetes/cce/cce.crt --client-key=/etc/kubernetes/cce/cce.key --username=cce --kubeconfig=/etc/kubernetes/cce.conf --embed-certs=true
# 将user和cluster组合起来形成一个context
[root@node1 ~]# kubectl config set-context context-cce --cluster=cce-cluster --user=cce --kubeconfig=/etc/kubernetes/cce.conf
# 指定默认使用的context
[root@node1 ~]# kubectl config use-context --kubeconfig=/etc/kubernetes/cce.conf context-cce 
# 测试是否能够读取service
[root@node1 ~]# kubectl get service --kubeconfig=/etc/kubernetes/cce.conf  
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   30d
# 测试是否能读取deployment
[root@node1 ~]# kubectl get deployments.apps --kubeconfig=/etc/kubernetes/cce.conf
Error from server (Forbidden): deployments.apps is forbidden: User "cce" cannot list resource "deployments" in API group "apps" in the namespace "default"  # 提示权限被拒绝
# 增加deployments权限
[root@node1 ~]# cat role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: resource-reader
  namespace: default
rules:
- apiGroups: ["*"] # * 表示所有api群组
  resources: ["pods","pods/log","services","namespaces","deployments"] # 只允许操作哪些资源
  verbs: ["get","list","watch"] # 只运行对资源进行何种操作
[root@node1 ~]# kubectl apply -f role.yaml 
# 测试权限
[root@node1 ~]# kubectl get deployments.apps --kubeconfig=/etc/kubernetes/cce.conf  
No resources found in default namespace.
ClusterRole示例
    创建一个ClusterRole允许访问集群级别的资源,集群级别权限也就是最大的,不局限于namespace,也就是说权限再不受namespace的控制,比如授予了一个list权限,那也就可以查看整个集群所有的namespace,不局限于namespace,它和Role的区别也仅仅是namespace;
# 创建一个ClusterRole
[root@node1 ~]# cat clusterrole.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-resource-reader
  # namespace: default 集群级别的角色不需要namespace
rules:
- apiGroups: ["*"] # ""表示core API group
  resources: ["pods","pods/log","services","namespaces","deployments"]
  verbs: ["get","list","watch"]
[root@node1 ~]# kubectl get clusterrole cluster-resource-reader 
NAME                      AGE
cluster-resource-reader   3m2s
# 创建一个ClusterRoleBinding
[root@node1 ~]# cat clusterrolebinding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cce-cluster-resource-reader
  # namespace: default 集群级别的角色不需要namespace
subjects:
- kind: User
  name: cce
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole # 这里绑定的也不再是Role而是ClusterRole
  name: cluster-resource-reader
  apiGroup: rbac.authorization.k8s.io
[root@node1 ~]# kubectl get clusterrolebindings.rbac.authorization.k8s.io cce-cluster-resource-reader 
NAME                          AGE
cce-cluster-resource-reader   3m24s
# 测试权限
[root@node1 ~]# kubectl get pods -n kube-system --kubeconfig=/etc/kubernetes/cce.conf 
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-5644d7b6d9-ngnpl                1/1     Running   1          30d
coredns-5644d7b6d9-tg25q                1/1     Running   1          30d

交叉授权

    让一个Role绑定ClusterRolebinding,因为创建Role的时候需要指定namespace,所以虽然绑定的是ClusterRoleBinding,但是它只能操作特定名称空间集群级别的资源;
# ClusterRole不变
[root@node1 ~]# cat clusterrole.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-resource-reader
  # namespace: default 集群级别的角色不需要namespace
rules:
- apiGroups: ["*"] # ""表示core API group
  resources: ["pods","pods/log","services","namespaces","deployments"]
  verbs: ["get","list","watch"]
[root@node1 ~]# kubectl get clusterrole cluster-resource-reader 
NAME                      AGE
cluster-resource-reader   3m2s
# 创建一个RoleBinding,将用户绑定到ClusterRole,Role是名称空间级别,所以即使绑定了ClusterRole那也只能在Role允许的名称空间级别操作
[root@node1 ~]# cat cce-robing.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding  # 指定为RoleBinding
metadata:
  name: cce-resource-reader
  namespace: default  # 指定允许的namespace
subjects:
- kind: User
  name: cce
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole # 绑定类型为ClusterRole
  name: cluster-resource-reader
  apiGroup: rbac.authorization.k8s.io
[root@node1 ~]# kubectl get rolebindings.rbac.authorization.k8s.io cce-resource-reader 
NAME                  AGE
cce-resource-reader   3m35s
# 测试权限
[root@node1 ~]# kubectl get pods -n default --kubeconfig=/etc/kubernetes/cce.conf  # default空间没问题
No resources found in default namespace.
# 换一个名称空间测试
[root@node1 ~]# kubectl get pods -n kube-system --kubeconfig=/etc/kubernetes/cce.conf  # 测试权限不足
Error from server (Forbidden): pods is forbidden: User "cce" cannot list resource "pods" in API group "" in the namespace "kube-system"

Kubernetes内建Cluster

cluster-admin:超级管理员权限,拥有整个集群的所有权限;
admin:假如需要授权一个用户对某个名称空间具有管理员权限,那么就可以使用rolebinding绑定到这个admin的集群角色,自动成为该名称空间的管理员;
edit:假如需要授权一个用户对某个名称空间具有修改权限,那么就可以使用rolebinding绑定到这个edit的集群角色,然后就可以修改该名称空间的资源了;
view:假如需要授权一个用户对某个名称空间具有查看你权限,那么就可以使用rolebinding绑定到这个view的集群角色,然后就可以查看该名称空间的资源了;
总结
    如果期望一个用户拥有指定名称空间的管理员权限,那么使用rolebing绑定到内建的admin集群角色即可,如果期望一个用户成为整个集群的管理员权限,那么使用clusterrolebinding绑定到admin集群角色即可;
# 绑定之前先测试是否有权限
[root@node1 ~]# kubectl get pods -n default --kubeconfig=/etc/kubernetes/cce.conf     
Error from server (Forbidden): pods is forbidden: User "cce" cannot list resource "pods" in API group "" in the namespace "default"   # 测试无权限
# 手动将cce用户使用clusterrolebinding绑定到cluster-admin,这个时候就拥有了整个集群的所有管理权限
[root@node1 ~]# kubectl create clusterrolebinding cluster-role --clusterrole=cluster-admin --user=cce
clusterrolebinding.rbac.authorization.k8s.io/cluster-role created
# 测试权限
[root@node1 ~]# kubectl get pods -n default --kubeconfig=/etc/kubernetes/cce.conf 
No resources found in default namespace.  # 测试通过



# 绑定之前先测试权限
[root@node1 ~]# kubectl get pods --kubeconfig=/etc/kubernetes/cce.conf                 
Error from server (Forbidden): pods is forbidden: User "cce" cannot list resource "pods" in API group "" in the namespace "default"
# 手动将cce用户使用rolebinding绑定到cluster-admin,这个时候就拥有了指定集群的所有管理权限
[root@node1 ~]# kubectl create rolebinding role --clusterrole=admin --user=cce        
rolebinding.rbac.authorization.k8s.io/role created
# 测试权限
[root@node1 ~]# kubectl get pods --kubeconfig=/etc/kubernetes/cce.conf        
No resources found in default namespace.  # 权限测试通过

Dashborad示例

    基于WEB的用户图形界面,基于这个图形界面可以看到Pod,Pod控制器等相关资源,必要时也可以直接把yaml格式的配置清单贴进配置界面进行应用,这是一个用户访问的接口,所以我们就得静心组织Dashboard的用户权限,Dashboard有一特点,它的多用户的,也就意味着你可以用不同权限的用户来进行不同的资源管理,Dashboard自己不会做任何用户认证,它仅仅将认证请求代理至Kubernetes,也就意味着所有的用户得是Kubernetes的用户,用户权限也是在Kubernetes之上所拥有权限;
    这里的用户帐号很独特,输入用户帐号之后不是用户直接访问Kubernetes的,它需要代理给Dashboard,Dashboard自己是一个Pod,任何Pod要访问Kubernetes都需要使用ServiceAccount,因此Dashboard使用的帐号是ServiceAccount,不能是普通用户或者是常规用户帐号;
    我们应该把Dashboard利用Service的NodePort类型或者使用ingress开放至集群外部;
dashboard Github:https://github.com/kubernetes/dashboard
因为Kubernetes比较高1.16所以默认的dashboard不兼容查看说明:https://github.com/kubernetes/dashboard/blob/93474e53b9ce5a1de0acba93c5aff6295d91dd19/docs/user/installation.md
# 创建一个私钥,用于dashboard的ssl证书
[root@node1 ~]# openssl genrsa -out dashboard.key 2048
# 创建一个证书签署请求
[root@node1 ~]# openssl req -new -key dashboard.key -out dashboard.csr -subj "/O=cce/CN=dashboard"
# 利用kubernetes的CA来签署我们的证书
[root@node1 ~]# openssl x509 -req -in dashboard.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out dashboard.crt -days 36500
[root@node1 ~]# mkdir /etc/kubernetes/dashboard
[root@node1 ~]# mv dashboard.csr dashboard.crt dashboard.key /etc/kubernetes/dashboard/
# 基于自建证书和私钥创建一个secert,从而被我们的dashboard所加载,用它来作为dashboard的ssl证书
[root@node1 ~]# kubectl create namespace kubernetes-dashboard
[root@node1 ~]# kubectl create secret generic kubernetes-dashboard-certs -n kubernetes-dashboard --from-file=dashboard.crt=/etc/kubernetes/dashboard/dashboard.crt --from-file=dashboard.key=/etc/kubernetes/dashboard/dashboard.key   # 因为配置清单默认type为Opaque而不是tls所有要使用generic类型
[root@node1 ~]# kubectl get -n kubernetes-dashboardsecrets kubernetes-dashboard-certs -o yaml
apiVersion: v1
data:
  dashboard.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN0VENDQVowQ0NRRENkUER3VjBvb3RUQU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHIKZFdKbGNtNWxkR1Z6TUNBWERURTVNVEl3TnpBNE1UWXdOMW9ZRHpJeE1Ua3hNVEV6TURneE5qQTNXakFpTVF3dwpDZ1lEVlFRS0RBTmpZMlV4RWpBUUJnTlZCQU1NQ1dSaGMyaGliM0poWkRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUsyR3p4cGpKTFRSZUhla1dWRm1iRXhLY3ZaMFFpYmxRdFpvR05mNnRlbTcKYzFkK1RSRWk0bGFkZWV0TzNVUXprRVlpNmFYTHNadnRCclFTRUd5SG80Z3hhaWMzTVM0eDFPc1RPOHljOUxubApXdjFodDgwYzFWdHRuUDl1Tmo4dGsrc0F6TnhkNDhJNjJFUUw0VzhvSUpwR2wyWVQxbTU4Z2x6c2ozemkxVHJ3ClZ6VHhOaUNwOUdKdjY3SVNmQUxsQXFzeS9IRWNGSTlXcllIS001b2hIcDhGaEgyOTNBWC9zTGhRZGhEcVR6ekwKc1l5WEUra2dkclZaN1Jic2gyNjYxZDBwR2NzMUpHSVBGclhnVGFFeTNyY2w1YWYydGhXbUY3Mi9pZFFMcmpSagpJQUlxZW52ZWVUYWFhdStpWnpXMG05WngwOHFIeGlIL1FXckRKZ1Fwbm1NQ0F3RUFBVEFOQmdrcWhraUc5dzBCCkFRc0ZBQU9DQVFFQVRoSHpYSHBXMXJIQjJCOTNUdndQcHB0Q1JDTDZVdVVwaHd3bWk2allOVmY2ZFBZMjRuMksKUWxmOUh5RStXM1FSVHcycld1OFB6UnRTNGdOR2k5MlpUbnBZQS95TmdtZVFGY3U1T0NUSHkvb1JFdmNDN2wyNgpMN3J5c0E3VmJjR3llTml4eUlUVmpZNXJjTE02Y21SeHZRZDNCcEZhaEZudG1PaEE2N1c5NnJDenZQYW5EK2NCCkpFTzFyQ1B6Umw3dDlPY21kSUg0SythRndhendDNFRrN291VjExVCtvYWJRYWdPZlcrbnVYNlNrR3JoUVErR0wKdU1DWWt5RWhzc2JpL1Z0QklYMlBtTUw2eHJRT3VTQ0M1eEpuaklHaWJVYStFUEJSa1drc1dYZzJzYjRtZ3VhRgpTQzV4MnRQbjZTSVZUWHd6S2lyOUE1NC9EQklJZlVJb1pRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  dashboard.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBclliUEdtTWt0TkY0ZDZSWlVXWnNURXB5OW5SQ0p1VkMxbWdZMS9xMTZidHpWMzVOCkVTTGlWcDE1NjA3ZFJET1FSaUxwcGN1eG0rMEd0QklRYkllamlERnFKemN4TGpIVTZ4TTd6SnowdWVWYS9XRzMKelJ6VlcyMmMvMjQyUHkyVDZ3RE0zRjNqd2pyWVJBdmhieWdnbWthWFpoUFdibnlDWE95UGZPTFZPdkJYTlBFMgpJS24wWW0vcnNoSjhBdVVDcXpMOGNSd1VqMWF0Z2Nvem1pRWVud1dFZmIzY0JmK3d1RkIyRU9wUFBNdXhqSmNUCjZTQjJ0Vm50RnV5SGJyclYzU2taeXpVa1lnOFd0ZUJOb1RMZXR5WGxwL2EyRmFZWHZiK0oxQXV1TkdNZ0FpcDYKZTk1NU5wcHE3NkpuTmJTYjFuSFR5b2ZHSWY5QmFzTW1CQ21lWXdJREFRQUJBb0lCQVFDVnloVGtka2l0UFZSOApFb1ozV2E2S2ZJbVliT3Jkb0hGOW13WTNDZGdXRnhXTnBSenBlZTlmVFRoOUF1ckZnSzA5bmMyS3JMWjRIcmIyCm9kRkRuaUp2NGhmOEdneCtEODMzemZhRXZjZ1M0QVVYVEU3WTQ5Yll3Vm9RdEJabm12UmdtNlE3WldEQnZRSUsKV3ljU1NOVTcxMHZCZGNaWVFXcFd4RzFvSkhaa0ZMK1NEV3pNcUtxNy9VZ0RoeWthTlBRNHdhWjRUVFFaMDdCdgpnd2h4RnN5MWZKeDBDaWV4NGZCa1JudURVa3JTYVV1Tlduekp2TVBXK2ZjOVJ5ZXByS2VWQXVQZmRReDhkYmN1CnhDa2tlZFFJeERwajZPTTFra2Q1UkZVUVFvNERrS0xQdmtzUENJcy9hMmhIbnFJcmxyb3BzTXg1TFVvNS84T1kKZFQvN1psQ0JBb0dCQU5MdW9yd1p1b3NWcjAxaTVxUDh4Vkp4bWJZazJPY0NhRUN6aWkrQlFPbHRjZ2l6ZnlRSQpqQ1ZnNWJrNmU1ak1YUXVtRWUwWkUxN1J0UStJQ3RFVDdHYURVckRxMkNTdW9JbENXTGVudEdxRmg1a2dOODFSCm5FeG9VVGJxOWtOdEIwbmZRU3lsc0RKZzFMdTFDQzhkMExYTnFJNExNKzlzeHYwcjRPemZpUTV4QW9HQkFOS2EKTXdwL20xWHljb05vWTdNOG9sam1HL2RRcmpUUU5vdnNzclA3ZThhNUYwMllBTjZRRDRibGtWMmpJR1lXSUd6cwoySjk0eDdBSElhM0IzR0xzbTJ2UVVIcEhYdlEzMlBnTGZUSkZ1S0NzaFpPNFhpb1ArNHRRS2h3Q0MrTENjUUR4CmI5RVVhY2dxWmxBRjRTOHlIVUNOL3JKQXZZemNGMk5sYXFFSjlFd1RBb0dCQUxVR2t1bG1GMS9JZzRPaHpwbU0KbFBoMWdGcis4cHdIeDl0SGV0L2NTUTVNbktKMUVqZWxra2wrQ0luWWREeWxuM0VnM0ora2RxaFl4OUNGaStyMQo4MXZqZHJOWlNaanB1ZU15NnBycnRmMzVqVzlRWkRPMHg3UVhqeVBYc1BRYS9UZGNBRDVHRUpxYjJkY2l2ZHhaCjlVWWlNM2Q4aTl6K2VTVE1aS1JHRUFVeEFvR0FhNkh2TUJCamZSdDV0dnNrNlRlMTZTVkJhYlpNTWlXdm12ZVAKcFRpRDI5NUFzS0ZjNEdKVDdTZHFrYWFMS21Gb2xRSysrMUdwREtlNGFLdEpUUzJMaVNCZjRQNlU0cytnRGJVaAplUTMwKy9qd0U3MElNd3NVRGZFY2RFLy9ieGJjMWhTT2h4YWRzWFVwOFAvd1JFU2llcG1YYjlaeWlZajZVd3hECjRLWEx1dzBDZ1lBelR0K2djQ0NncUY1WjdXendvWHNBNWNrZ1JWL0l4K1NwYjNncFhJdUIrVmZFU1FUWVlESHgKQ3dJbjdyeksxMlFLMFgxMjJiR0JUOXovakNJbkhRU3l0eElXcWJ6SGVYMzRVMll6aDA0czB5Tlk3a0lsTnZNbgpPNlhuRjBCSkNucStuQjFPRUQxVFpYSmRKVytnY3RoclpiQmxDaDI5TWhKM0RURGx2d3VtZmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
kind: Secret
metadata:
  creationTimestamp: "2019-12-07T08:23:42Z"
  name: kubernetes-dashboard-certs
  namespace: kube-system
  resourceVersion: "16125"
  selfLink: /api/v1/namespaces/kube-system/secrets/kubernetes-dashboard-certs
  uid: 6f94a139-c9f0-4697-b9c0-d4233606a5e8
type: Opaque
# 正式应用之前需要下载镜像,因为k8s.gcr.io的镜像默认是访问不了的,在各个节点执行;
[root@node1 ~]# docker pull kubernetesui/dashboard:v2.0.0-beta5
# 需要修改配置清单里面Service为NodePort
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30443
  selector:
    k8s-app: kubernetes-dashboard
# 应用配置清单
[root@node1 ~]# kubectl apply -f  https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta5/aio/deploy/recommended.yaml
[root@node1 ~]# kubectl get pods -n kubernetes-dashboard kubernetes-dashboard-6b86b44f87-kqwb7 
NAME                                    READY   STATUS    RESTARTS   AGE
kubernetes-dashboard-6b86b44f87-kqwb7   1/1     Running   0          65s
[root@node1 ~]# kubectl get pods -n kubernetes-dashboard kubernetes-dashboard-6b86b44f87-kqwb7 -o wide
NAME                                    READY   STATUS    RESTARTS   AGE    IP           NODE            NOMINATED NODE   READINESS GATES
kubernetes-dashboard-6b86b44f87-kqwb7   1/1     Running   0          118s   10.244.1.9   node2.cce.com   <none>           <none>
# 创建一个集群级别的ServiceAccount超级用户
[root@node1 ~]# kubectl create serviceaccount dashboard -n kubernetes-dashboard
# 将dashboard和cluster-admin的ClusterRole进行绑定
[root@node1 ~]#  kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard
# 找到它自动生产的secerts
[root@node1 ~]# kubectl get serviceaccounts -n kubernetes-dashboard dashboard -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-12-07T10:03:14Z"
  name: dashboard
  namespace: kubernetes-dashboard
  resourceVersion: "25463"
  selfLink: /api/v1/namespaces/kubernetes-dashboard/serviceaccounts/dashboard
  uid: ad2622c4-e28a-49d6-8cf8-38aab2947fc7
secrets:
- name: dashboard-token-xxqtw  # 自动生产的secerts
# 找到tokens
[root@node1 ~]# kubectl get serviceaccounts -n kubernetes-dashboard dashboard -o yaml               
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-12-07T10:03:14Z"
  name: dashboard
  namespace: kubernetes-dashboard
  resourceVersion: "25463"
  selfLink: /api/v1/namespaces/kubernetes-dashboard/serviceaccounts/dashboard
  uid: ad2622c4-e28a-49d6-8cf8-38aab2947fc7
secrets:
- name: dashboard-token-xxqtw
[root@node1 ~]# kubectl describe -n kubernetes-dashboard secrets dashboard-token-xxqtw 
Name:         dashboard-token-xxqtw
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: dashboard
              kubernetes.io/service-account.uid: ad2622c4-e28a-49d6-8cf8-38aab2947fc7

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  20 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Ik50UUxrZWFyWF8xR3hLX25lQ1k1QUdsU3dQcEhZdGlGTEZLanpJLXJIS0EifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtdG9rZW4teHhxdHciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYWQyNjIyYzQtZTI4YS00OWQ2LThjZjgtMzhhYWIyOTQ3ZmM3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZCJ9.iBjqf2htzkq23QzcwkVQD7jr2-TmDLpsgLwfZYQNs_wiWV8mUPwVGZYun_UXsTt-Iv59bgTexI6JYitHwYbIld0gwMrkSzNYHEZUF-shLxchJVnfHYs3HdES_cVRLWHDWyBOxZYQeFSVfCgtPvF2OJlG6KK9s4m_-yVJaXebQrS1S1MARGtt3w5qnahV99wOzcZQoZr4SEWOFh9kbHWU1ihiz6nOTKkoR3J-fCy8xj834TCDFqA4LZlJswmIjeJtAZTwtn53kO9S1E9d6ETFaC0lwB3reeDuJqdUWRJZ6E9NdjFAZdkezyKqbx_xVldyVhxY8mfVeAnfQ-CmP3lB_Q
# 使用配置清单的方式创建
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cce
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cce-clusterrolebinding-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: ""
  kind: ServiceAccount
  name: cce
  namespace: kubernetes-dashboard

利用创建是ServiceAccount的token创建一个kubeconfig文件用于dashboard登录

# 创建一个集群
[root@node1 ~]# kubectl config set-cluster mykube --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=https://172.16.1.2:6443 --kubeconfig=/etc/kubernetes/dashboard.conf
# 利用现有ServiceAccount的token创建kubeconfig文件
[root@node1 ~]# kubectl config set-credentials cce --token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ik50UUxrZWFyWF8xR3hLX25lQ1k1QUdsU3dQcEhZdGlGTEZLanpJLXJIS0EifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjY2UtdG9rZW4tZmdkMjgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiY2NlIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNThmY2MzNTQtOTc0ZC00NDQ4LThjYjUtZjZjNjk4YzZjZDMwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmNjZSJ9.Uj9O0rHEnN3sfuAMitVBHR3TeT5vHXuBTccuQMIDPxwv_CYiHO9cbz-oDVJZTQiw91s7J7ch5kqTzPKAGWCwMW4IH2GTnJAu2X1hDi_kenWAEj5jIwADA1OKHD5If0-xatxRWU2EER9JDpiAhat0q8-IFFaBV5k27miQ3ISzUzOnS8JzXcPjU7dBUnhZb3509TnWK5tl6Kq0EK29BqR1zSfEP2_N3-x13b5CZsd6OHVAVvKWRKhanVhNhe0Osp29_GaqLc_D_4hdJfnPHJyprAJoIHqtLaeRi6TP6HIvALr54gxXDH0M7eusZ3CRQPlOrIjVU6kUp8ST6O21stGa7w --kubeconfig=/etc/kubernetes/dashboard.conf
# 设定context 将user和cluster建立关联
[root@node1 ~]# kubectl config set-context dashboard --cluster=mykube --user=cce --kubeconfig=/etc/kubernetes/dashboard.conf 
# 设定默认使用的context
[root@node1 ~]# kubectl config use-context --kubeconfig=/etc/kubernetes/dashboard.conf dashboard
# 测试登录成功

总结

Role join Rolebinding
    这种搭配主要是为了将一个用户限制在一个namespace级别,最大权限也就只能控制这个namespace级别内部的属于namespace级别的资源,具体是否是namespace级别的资源使用api-resources查看;
ClusterRole join ClusterRolebinding
    这种搭配主要是为了控制一个用户在集群级别的资源权限,最大权限也就是最高管理员权限,具体是否是Cluster级别的资源使用api-resources查看;
ClusterRole join Rolebinding
    主要作用还是为了实现权限统一定义,在全局模式下定义一个组,让用户加入进来,那么就有了相应的权限了,无需每次都重新定义一个Role;

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注