kubernetes-RBAC、dashboard-12

资源请求属性

        Kubernetes是基于http或https协议工作的(restful风格),因此其对应的操作请求,无非就是增删改查(get、put、delete),因此在每一个Kubernetes的相关请求当中,通常这个请求会包含类似以下的信息; 理论来源

user:  用户名称;
group: 用户所属的组;
extra: 额外属性;
Resource: 指定使用哪个Kind资源;
Subresource: 额外资源的子资源;
API: 也就是我们的Kubernetes标准资源属于哪一个API群组下面的那个API;
Namespace: 名称空间;
Request path: 相对于我们API来讲,就是请求的URL路径;
HTTP request verb:HTTP请求方法,GET、DELETE...;
API request verb:向Kubernetes API的请求方法,比如get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection;

授权插件

  1. Node:节点认证,根据Pod对象调度的结果为Node进行授权,Node会自动授权Pod的相关定义的访问权限;
  2. ABAC:基于属性的访问控制,RBAC之前的算法,1.6之前的版本使用;
  3. RBAC:Role-based AC, 基于角色的访问控制,事先定义好角色,直接将权限赋予给角色,只要用户属于这个角色也就有该赋予的权限;
  4. Webhook:web钩子,其实也就是一个http的回调函数,一般而言就是某一个http上的资源发生变化时,能够发起触发,然后做出相应的操作;

RBAC

        在k8s1.8之后的版本强制使用RBAC用户授权,任何人的操作必须在RBAC中有明确定义,无定义无权限,匿名用户默认无权限,包括刚认证的用户也只有极少数权限,使用rbac.authorization.k8s.io API驱动授权决策,并支持动态配置,RBAC的出现是因为SA只认证不授权,也就是默认权限全开;
        查看默认授权插件可通过kubadm部署的集群中查看: /etc/kubernetes/manifests/kube-apiserver.yaml

RBAC的实现方式

为了实现RBAC,我们需要定义如下消息

  1. 用户,我们称之为Subjects主语,而这个用户账号有两种,这就是我们RBAC可以拿来当主语的东西;
  • 第一种: UserAccount;
  • 第二种: ServiceAccount;
  1. 资源,我们称之为Object宾语,在k8s能够被操作的资源有三类
  • 第一类: 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;

角色(role)说明

在这里插入图片描述

  1. 角色: k8s中授权的机制,一个组织或者任务中的工作位置,其表示为一种责任或资格, 后续的许可授权都添加在角色上, 随后在让用户扮演这个角色,这个用户就相当于拥有了这个角色权限
  2. 权限: 基于所谓的对象,每一个被访问的组件都是对象,在restful的api当中一切皆对象,k8s上运行的组件可分为三种:
    • 对象: 一种角色扮演
    • 对象列表: 在api当中一切皆对象
    • 虚拟路径(非对象资源或非资源url):
  3. Operations:在restful基础中所有的操作,都是指在某个对象上施加的某个行为(action),在一个对象上施加的组合请求叫许可权限, 在Role之上可以授予一个许可权限
  4. 要想实现使用基于的访问控制应当具备的条件: user, role, permissions(operations, objects)
  5. role需要定义的 :
    • operations:操作属性
    • objects:对哪些对象执行什么操作, 写了就是允许,没写就拒绝
    • 用户帐号
  6. rolebinding: 将 用户帐号 绑定在 哪个 角色上,
    在这里插入图片描述

所有的授权都是指派在角色之上,让用户添加角色即可获取相对应的权限。

对象引用的URL格式: 名称空间级别: /apis/<GROUP>/<VERSION>/namespace/<NAMESPACE_NAME>/<KIND>[/OBJECT_ID]

普通角色

在k8s之上,role, rolebinding分别拥有有两个级别

  1. 集群
  2. 名称空间: role, rolebinding主要是在名称空间级别范围内的许可权限

集群角色

集群级别的用户角色绑定

  • clusterrole: 集群角色
  • clusterrolebinding: 集群角色绑定

在这里插入图片描述

rolebinding绑定role: 在名称空间A中 (default) 定义了一个角色 Role-A, 与用户A-user建立绑定关系,从而A-user就拥有了当前 (default) 名称空间的权限, 而不是集群上的名称空间权限

clusterrolebinding绑定clusterrole: 在集群级别定义一个clusterRole, 该用户就能获取所有名称空间的权限

rolebinding绑定ClusterRole: 意味着 这个用户能获取所属名称空间的所有权限, 使用范围:假设如果该节点有N个名称空间, 那么就需要定义N个role然后进行绑定, 此时定义clusterRole那么只需要绑定一个cluserRole就能获取所有名称空间权限了

​ - 说明: 就好比 role是单个名称空间的权限, 而clusterrole却可以定义多个或全部名称空间的权限

RBAC-示例

查看api资源详细信息: kubectl api-resources
在这里插入图片描述

一、rolebinding绑定role

  1. 创建role
 ]# kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run -o yaml   # 创建,不加 --dry-run -o yaml执行
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pod-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
  1. 查看role

    ]# kubectl describe role pod-reader 
    Name:         pod-reader
    Labels:       <none>
    Annotations:  PolicyRule:
    Resources   Non-Resource URLs  Resource Names  Verbs
    ---------   -----------------  --------------  -----
    pods        []                 []              [get list watch]
    
    参数 说明
    Resources 资源类别, 一整类下的所有资源 object
    Non-Resource URLs 非资源URL,某种特殊操作
    Resource Names 资源名称,针对这个资源类别的某个特定资源进行操作
    Verbs 允许操作的方式,[get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection]
  2. 创建rolebinding

    角色(权限), 用户 --> rolebinging
    ]# kubectl create rolebinding xiong-role --role=pod-reader --user=xiong-k8s --dry-run=client -o yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      creationTimestamp: null
      name: xiong-role
    roleRef:                 # 引用 role
      apiGroup: rbac.authorization.k8s.io
      kind: Role		     # role 资源类型 
      name: pod-reader       # role资源名称
    subjects:   # 执行主题 绑定哪个用户
    - apiGroup: rbac.authorization.k8s.io
      kind: User   # User资源类别是不存在的
      name: xiong
    
  3. 查看绑定关系

]# kubectl get rolebindings
NAME         ROLE              AGE     
xiong-role   Role/pod-reader   8s

]# kubectl describe rolebindings xiong-role
Name:         xiong-role
Labels:       <none>
Annotations:  Role:
  Kind:       Role
  Name:       pod-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  xiong  
  1. 切换用户
# 创建一个私钥
]# openssl genrsa -out lzx.key 4096

# 为证书生成一个证书签署请求,并且使用kubernetes的CA来签署, CN代表用户名, 0组织表示组
]# openssl req -new -key lzx.key -out lzx.csr -subj "/CN=xiong/O=kubernetes"

]# openssl x509 -req -in lzx.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key  -CAcreateserial -out lzx.crt -days 3650

]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt  --client-key=/etc/kubernetes/lzx/lzx.key  --embed-certs=true

]# kubectl config set-context xiong-k8s --cluster=kubernetes --user=xiong

]# kubectl config use-context xiong-k8s

]# kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
t3-xiong    1/1     Running             1          6d2h

# 查看svc就没有权限了,只能查看 default名称空间
]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "xiong" cannot list resource "services" in API group "" in the namespace "default"

二、集群角色绑定

        创建一个ClusterRole允许访问集群级别的资源,集群级别权限就是最大的,不局限于namespace,也就是说权限再不受namespace的控制,比如授予了一个list权限,那就可以查看整个集群所有的namespace,不局限于namespace,它和Role的区别也仅仅是namespace

  1. 创建 clusterrole
]# 创建之前先切换回有权限用户 kubectl config use-config kubernetes-admin@kubernetes

]# kubectl create clusterrole cluster-pod-read --verb=get,list,patch --resource=pods --dry-run=client -o yaml > cluster-pod-read.yaml

]# cat cluster-pod-read.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-read
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - patch

]# kubectl apply -f cluster-pod-read.yaml
  1. 查看资源
]# kubectl get clusterrole cluster-pod-read 
NAME               CREATED AT
cluster-pod-read   2020-05-13T09:10:42Z

]# kubectl describe clusterrole cluster-pod-read 
Name:         cluster-pod-read
Labels:       <none>
Annotations:  PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  pods        []                 []              [get list patch]
  1. clusterbinding创建
]# kubectl create clusterrolebinding clusterbind-pod-all --clusterrole=cluster-pod-read --user=xiong --dry-run=client -o yaml > clusterbind-pod-all.yaml

]# cat clusterbind-pod-all.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: clusterbind-pod-all
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-pod-read
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: xiong
 
]# kubectl apply -f clusterbind-pod-all.yaml
  1. 查看绑定关系
]# kubectl get clusterrolebindings clusterbind-pod-all 
NAME                  ROLE                           AGE
clusterbind-pod-all   ClusterRole/cluster-pod-read   40s

]# kubectl describe clusterrolebindings clusterbind-pod-all 
Name:         clusterbind-pod-all
Labels:       <none>
Annotations:  Role:
  Kind:       ClusterRole
  Name:       cluster-pod-read
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  xiong  
  
# 切换用户前先删除原先的 role 然后使用集群角色进行测试
  1. 效果
# 查看pod下所有的名称空间,没问题
~]# kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
myapp-0     0/1     ContainerCreating   0          27h
myapp-1     0/1     Error               0          4d8h
myapp-2     0/1     Error               0          4d8h
myapp-3     0/1     Error               0          4d8h
myapp-4     0/1     Error               0          4d8h
pod-sa      1/1     Running             0          27h
s1-secret   1/1     Running             1          6d2h
t3-xiong    1/1     Running             1          6d3h

~]# kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-67754f4878-fr8cz   1/1     Running   1          2d2h

 ~]# kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-7ff77c879f-4pbhq         1/1     Running   1          6d5h

# 在verbs中没有定义delete就不能进行操作啦
 ~]# kubectl delete pod myapp-1
Error from server (Forbidden): pods "myapp-1" is forbidden: User "xiong" cannot delete resource "pods" in API group "" in the namespace "default"

三、rolebinding绑定ClusterRole

# 删除上面绑定的clusterrolebind

# 将rolebinding绑定至clusterrole
]# kubectl create rolebinding rolebind-clusterrole-pod-read --clusterrole=cluster-pod-read --user=xiong --dry-run=client -o yaml > rolebind-clusterrole-pod-read.yaml

]# kubectl apply -f rolebind-clusterrole-pod-read.yaml 
rolebinding.rbac.authorization.k8s.io/rolebind-clusterrole-pod-read created

]# kubectl get rolebindings rolebind-clusterrole-pod-read 
NAME                            ROLE                           AGE
rolebind-clusterrole-pod-read   ClusterRole/cluster-pod-read   26s

]# kubectl describe rolebindings rolebind-clusterrole-pod-read 
Name:         rolebind-clusterrole-pod-read
Labels:       <none>
Annotations:  Role:
  Kind:       ClusterRole
  Name:       cluster-pod-read
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  xiong  
  
]# kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
t3-xiong    1/1     Terminating         1          6d21h

# 将 普通角色绑定到集群角色,其实是一个降级降维的结果, 访问的最终还是该节点的默认名称空间
]# kubectl get pods -n ingress-nginx
Error from server (Forbidden): pods is forbidden: User "xiong" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"

Kubernetes内建Cluster

通过: kubectl get clusterRole可以查看所有的集群角色

  1. cluster-admin:超级管理员权限,拥有整个集群的所有权限;
  2. admin:假如需要授权一个用户对某个名称空间具有管理员权限,那么就可以使用rolebinding绑定到这个admin的集群角色,自动成为该名称空间的管理员;
  3. edit:假如需要授权一个用户对某个名称空间具有修改权限,那么就可以使用rolebinding绑定到这个edit的集群角色,然后就可以修改该名称空间的资源了;
  4. view:假如需要授权一个用户对某个名称空间具有查看你权限,那么就可以使用rolebinding绑定到这个view的集群角色,然后就可以查看该名称空间的资源了;

总结

        通过 clusterrole get绑定clusterrolebind拥有集群中整个名称空间pod资源的查看权限,rolebind绑定clusterrole则是一个降维的过程,跟role绑定rolebind是一样的权限, 通过cluster-admin绑定clusterrolebind则是超级管理员权限, 权限操作过程,需要先定义用户[注意证书],然后 配置角色(role|clusterrole), 最后在通过 rolebind或clusterrolebind绑定 role|clusterrole跟用户,最后在切换用户,在普通客户机上定义用户时需要指定service的路径

dashboard

        Dashboard 是基于网页的 Kubernetes 用户界面。您可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。您可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如 Deployment,Job,DaemonSet 等等)。例如,您可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。
        kubeadm安装和部署的集群默认是强制启动的rbac, 而dashboard接口是管理所有集群的接口,登陆dashboard只是一个认证代表,所有的帐号应该是k8s的帐号以及授权

部署 Dashboard UI

默认情况下不会部署 Dashboard。可以通过以下命令部署:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml

查看

]# kubectl get svc -n kubernetes-dashboard 
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
dashboard-metrics-scraper   ClusterIP   10.105.31.103   <none>        8000/TCP   48s
kubernetes-dashboard        ClusterIP   10.108.182.92   <none>        443/TCP    50s

]# kubectl get pods -n kubernetes-dashboard 
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-6b4884c9d5-4z4h9   1/1     Running   0          75s
kubernetes-dashboard-7b544877d5-4tmnc        1/1     Running   0          76s

访问Dashboard

集群外连接

  1. 定义一个Nodeport

    ]# cat k8s-dashboard.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: k8s-dashboard
      namespace: kubernetes-dashboard
      labels:  # 需要先查看 deployment对应的dashboard的label
        k8s-app: kubernetes-dashboard
    spec:
      selector:
         k8s-app: kubernetes-dashboard
      type: NodePort
      clusterIP: ""
      ports:
      - name: k8s-dashboard-http
        port: 8443
        nodePort: 30443
    
  2. 直接修改

    ]# kubectl get svc -n kubernetes-dashboard 
    NAME                   TYPE    CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    kubernetes-dashboard  ClusterIP   10.108.182.92   <none>     443/TCP   114m
    
    ]# kubectl patch svc -p '{"spec":{"type":"NodePort"}}' -n kubernetes-dashboard kubernetes-dashboard 
    
    # 通过 这个随机端口也能直接访问
    kubernetes-dashboard        NodePort    10.108.182.92   <none>        443:30993/TCP    117m
    

在这里插入图片描述

通过Token访问

admin权限

需要使用: ServerAccount而不是直接写义某个系统用户
创建一个管理员权限的帐号: service-accout绑定在cluster-admin角色上 

# 创建一个sa
]# kubectl create sa k8s-dashboard-sa -n kube-system

# 绑定一个admin的集群admin权限sa
]# kubectl create clusterrolebinding k8s-cls-dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:k8s-dashboard-sa 
# serviceaccount=左名称空间:sa名称

]# kubectl describe clusterrolebindings k8s-cluster-dashboard 
Name:         k8s-cluster-dashboard
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind            Name              Namespace
  ----            ----              ---------
  ServiceAccount  k8s-dashboard-sa  kube-system
  
# 查看sa的token
]#  kubectl describe secrets k8s-dashboard-sa-token-nqz74 
Name:         k8s-dashboard-sa-token-kxmks
Namespace:    kube-system

Type:  kubernetes.io/service-account-token

Data
====
namespace:  7 bytes
token:     # 这段token用来登陆
ca.crt:     1025 bytes

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fzrcYfCc-1593652468945)(C:\Users\xiong\AppData\Roaming\Typora\typora-user-images\image-20200514160245370.png)]
在这里插入图片描述

普通名称空间权限

# 1、创建一个sa
]# kubectl create sa def-dashboard-sa

2、创建一个普通角色 权限绑定集群角色
]# kubectl create rolebinding def-dashboard-sa --clusterrole=admin --serviceaccount=default:def-dashboard-sa

3、查看token
]# kubectl describe secrets def-dashboard-sa-token-2lcmp 
Name:         def-dashboard-sa-token-2lcmp
Namespace:    default
Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      这里是token

此时就只剩下一个名称空间的内容了
在这里插入图片描述

通过.conf访问

  1. 创建ServiceAccount, 根据其管理目标, 使用rolebinding或clusterrolebinding绑定至合理role或clusterrole

    ]# kubectl create sa dash-cf-sa
    ]# kubectl create rolebinding dash-cf-sa --clusterrole=admin --serviceaccount=defalut:dash-cf-sa
    
  2. 获取as的token

    # 将base64加密的token解密,用于kubeconfig文件使用
    KUBE_DASH_SA=$(kubectl get secrets dash-cf-sa-token-4nln4 -o jsonpath=
    {
           
           ".data.token"} | base64 -d)
    
  3. 生成kubeconfig文件

    kubectl config set-cluster
    kubectl config set-credentisales NAME --token=
    kubectl config set-context
    kubectl config use-context
    
    # 设定连接地址
    ]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.2.220:6443 --kubeconfig=/root/k8s-dash-user.conf
    
    # 指定token
    ]# kubectl config set-credentials dashboard --token=$KUBE_DASH_SA --kubeconfig=/root/k8s-dash-user.conf
    
    # 将连接地址与token进行绑定,定义一个上下文
    ]# kubectl config set-context [email protected] --cluster=kubernetes --user=dashboard --kubeconfig=/root/k8s-dash-user.conf 
    
    # 切换使用这个上下文
    ]# kubectl config use-context --kubeconfig=/root/k8s-dash-user.conf [email protected] 
    
    ]# cat /root/k8s-dash-user.conf 
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority: /etc/kubernetes/pki/ca.crt
        server: https://192.168.2.220:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: dashboard
      name: [email protected]
    current-context: [email protected]
    kind: Config
    preferences: {
          
          }
    users:
    - name: dashboard
      user:
        token: 这个是token内容
    
  4. 验证,下载这个conf文件, 然后登陆
    在这里插入图片描述

k8s集群的管理方式:

  1. 命令式: create , run , expose, delete, edit
  2. 命令式配置文件: create -f /PATH/TO/resource_container_file, delete -f, replace -f
  3. 声明式配置文件: apply -f, patch 推荐使用这种

猜你喜欢

转载自blog.csdn.net/u010304195/article/details/107077083