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;在k8s1.8之后的版本强制使用RBAC用户授权,任何人的操作必须在RBAC中有明确定义,无定义无权限,匿名用户默认无权限,包括刚认证的用户也只有极少数权限,使用rbac.authorization.k8s.io API驱动授权决策,并支持动态配置,RBAC的出现是因为SA只认证不授权,也就是默认权限全开; 查看默认授权插件可通过kubadm部署的集群中查看: /etc/kubernetes/manifests/kube-apiserver.yaml
为了实现RBAC,我们需要定义如下消息
用户,我们称之为Subjects主语,而这个用户账号有两种,这就是我们RBAC可以拿来当主语的东西; 第一种: UserAccount;第二种: ServiceAccount; 资源,我们称之为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;所有的授权都是指派在角色之上,让用户添加角色即可获取相对应的权限。
对象引用的URL格式: 名称空间级别: /apis/<GROUP>/<VERSION>/namespace/<NAMESPACE_NAME>/<KIND>[/OBJECT_ID]
在k8s之上,role, rolebinding分别拥有有两个级别
集群名称空间: 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却可以定义多个或全部名称空间的权限
查看api资源详细信息: kubectl api-resources
查看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资源类别, 一整类下的所有资源 objectNon-Resource URLs非资源URL,某种特殊操作Resource Names资源名称,针对这个资源类别的某个特定资源进行操作Verbs允许操作的方式,[get、list、create、update、patch、watch、proxy、redirect、delete以及deletecollection]创建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查看绑定关系
]# 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 切换用户 # 创建一个私钥 ]# 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
创建 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 查看资源 ]# 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] 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 查看绑定关系 ]# 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 然后使用集群角色进行测试 效果 # 查看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"通过: kubectl get clusterRole可以查看所有的集群角色
cluster-admin:超级管理员权限,拥有整个集群的所有权限;admin:假如需要授权一个用户对某个名称空间具有管理员权限,那么就可以使用rolebinding绑定到这个admin的集群角色,自动成为该名称空间的管理员;edit:假如需要授权一个用户对某个名称空间具有修改权限,那么就可以使用rolebinding绑定到这个edit的集群角色,然后就可以修改该名称空间的资源了;view:假如需要授权一个用户对某个名称空间具有查看你权限,那么就可以使用rolebinding绑定到这个view的集群角色,然后就可以查看该名称空间的资源了;通过 clusterrole get绑定clusterrolebind拥有集群中整个名称空间pod资源的查看权限,rolebind绑定clusterrole则是一个降维的过程,跟role绑定rolebind是一样的权限, 通过cluster-admin绑定clusterrolebind则是超级管理员权限, 权限操作过程,需要先定义用户[注意证书],然后 配置角色(role|clusterrole), 最后在通过 rolebind或clusterrolebind绑定 role|clusterrole跟用户,最后在切换用户,在普通客户机上定义用户时需要指定service的路径
Dashboard 是基于网页的 Kubernetes 用户界面。您可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。您可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如 Deployment,Job,DaemonSet 等等)。例如,您可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。 kubeadm安装和部署的集群默认是强制启动的rbac, 而dashboard接口是管理所有集群的接口,登陆dashboard只是一个认证代表,所有的帐号应该是k8s的帐号以及授权
默认情况下不会部署 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定义一个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直接修改
]# 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[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fzrcYfCc-1593652468945)(C:\Users\xiong\AppData\Roaming\Typora\typora-user-images\image-20200514160245370.png)]
此时就只剩下一个名称空间的内容了
创建ServiceAccount, 根据其管理目标, 使用rolebinding或clusterrolebinding绑定至合理role或clusterrole
]# kubectl create sa dash-cf-sa ]# kubectl create rolebinding dash-cf-sa --clusterrole=admin --serviceaccount=defalut:dash-cf-sa获取as的token
# 将base64加密的token解密,用于kubeconfig文件使用 KUBE_DASH_SA=$(kubectl get secrets dash-cf-sa-token-4nln4 -o jsonpath= {".data.token"} | base64 -d)生成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 dashboard@kubernetes.admin --cluster=kubernetes --user=dashboard --kubeconfig=/root/k8s-dash-user.conf # 切换使用这个上下文 ]# kubectl config use-context --kubeconfig=/root/k8s-dash-user.conf dashboard@kubernetes.admin ]# 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: dashboard@kubernetes.admin current-context: dashboard@kubernetes.admin kind: Config preferences: {} users: - name: dashboard user: token: 这个是token内容验证,下载这个conf文件, 然后登陆
k8s集群的管理方式:
命令式: create , run , expose, delete, edit命令式配置文件: create -f /PATH/TO/resource_container_file, delete -f, replace -f声明式配置文件: apply -f, patch 推荐使用这种